[tryton-commits] changeset in trytond:default Add validate option to trytond-admin
changeset d27b905106dd in trytond:default details: https://hg.tryton.org/trytond?cmd=changeset;node=d27b905106dd description: Add validate option to trytond-admin It validates a percentage of the listed models or all and report the errors. issue9782 review312751002 diffstat: CHANGELOG | 1 + trytond/admin.py | 39 +++ trytond/commandline.py | 5 + 3 files changed, 45 insertions(+), 0 deletions(-) diffs (76 lines): diff -r 32cd371b3e9c -r d27b905106dd CHANGELOG --- a/CHANGELOG Wed Jan 20 00:52:07 2021 +0100 +++ b/CHANGELOG Mon Jan 25 22:56:02 2021 +0100 @@ -1,3 +1,4 @@ +* Add validate option to trytond-admin * Refresh pool of other processes * Add clear_all method to Cache * Support Genshi element directives in HTML editor diff -r 32cd371b3e9c -r d27b905106dd trytond/admin.py --- a/trytond/admin.py Wed Jan 20 00:52:07 2021 +0100 +++ b/trytond/admin.py Mon Jan 25 22:56:02 2021 +0100 @@ -3,6 +3,7 @@ import sys import os import logging +import random from getpass import getpass from sql import Table, Literal @@ -119,3 +120,41 @@ if options.hostname is not None: configuration.hostname = options.hostname or None configuration.save() +with Transaction().start(db_name, 0, readonly=True): +if options.validate is not None: +validate(options.validate, options.validate_percentage) + + +def validate(models, percentage=100): +from trytond.model import ModelStorage, ModelSingleton +from trytond.model.exceptions import ValidationError +logger = logging.getLogger('validate') +pool = Pool() +if not models: +models = sorted([n for n, _ in pool.iterobject()]) +ratio = min(100, percentage) / 100 +in_max = Transaction().database.IN_MAX +for name in models: +logger.info("validate: %s", name) +Model = pool.get(name) +if not issubclass(Model, ModelStorage): +continue +offset = 0 +limit = in_max +while True: +records = Model.search( +[], order=[('id', 'ASC')], offset=offset, limit=limit) +if not records: +break +records = Model.browse( +random.sample(records, int(len(records) * ratio))) +for record in records: +try: +Model._validate([record]) +except ValidationError as exception: +logger.error("%s: KO '%s'", record, exception) +else: +logger.info("%s: OK", record) +if issubclass(Model, ModelSingleton): +break +offset += limit diff -r 32cd371b3e9c -r d27b905106dd trytond/commandline.py --- a/trytond/commandline.pyWed Jan 20 00:52:07 2021 +0100 +++ b/trytond/commandline.pyMon Jan 25 22:56:02 2021 +0100 @@ -90,6 +90,11 @@ default=[], metavar='CODE', help="Load language translations") parser.add_argument("--hostname", dest="hostname", default=None, help="Limit database listing to the hostname") +parser.add_argument("--validate", dest="validate", nargs='*', +metavar='MODEL', help="validate records of models") +parser.add_argument("--validate-percentage", dest="validate_percentage", +type=float, default=100, metavar="PERCENTAGE", +help="percentage of records to validate (default: 100)") parser.epilog = ('The first time a database is initialized ' 'or when the password is set, the admin password is read '
[tryton-commits] changeset in tryton:default Execute report asynchronously
changeset 8e13d64f983f in tryton:default details: https://hg.tryton.org/tryton?cmd=changeset;node=8e13d64f983f description: Execute report asynchronously Some reports may be long to generate so it is better to display the watch cursor. issue8845 review349111003 diffstat: CHANGELOG | 1 + tryton/action/main.py | 36 ++-- 2 files changed, 19 insertions(+), 18 deletions(-) diffs (62 lines): diff -r 42d0c1e001a1 -r 8e13d64f983f CHANGELOG --- a/CHANGELOG Sun Jan 24 20:59:46 2021 +0100 +++ b/CHANGELOG Mon Jan 25 22:13:11 2021 +0100 @@ -1,3 +1,4 @@ +* Execute report asynchronously * Add support for Python 3.9 * Support empty value for timedelta converter * Add interactive search on tree view diff -r 42d0c1e001a1 -r 8e13d64f983f tryton/action/main.py --- a/tryton/action/main.py Sun Jan 24 20:59:46 2021 +0100 +++ b/tryton/action/main.py Mon Jan 25 22:13:11 2021 +0100 @@ -4,7 +4,7 @@ import webbrowser import tryton.rpc as rpc -from tryton.common import RPCProgress, RPCExecute, RPCException +from tryton.common import RPCExecute, RPCException from tryton.common import message, selection, file_write, file_open from tryton.config import CONFIG from tryton.pyson import PYSONDecoder @@ -18,24 +18,24 @@ def exec_report(name, data, direct_print=False, context=None): if context is None: context = {} -data = data.copy() -ctx = rpc.CONTEXT.copy() -ctx.update(context) -ctx['direct_print'] = direct_print -args = ('report', name, 'execute', data.get('ids', []), data, ctx) -try: -res = RPCProgress('execute', args).run() -except RPCException: -return False -if not res: -return False -(type, data, print_p, name) = res -if not print_p and direct_print: -print_p = True +else: +context = context.copy() +context['direct_print'] = direct_print +ids = data.get('ids', []) -fp_name = file_write((name, type), data) -file_open(fp_name, type, print_p=print_p) -return True +def callback(result): +try: +result = result() +except RPCException: +return +type, data, print_p, name = result +if not print_p and direct_print: +print_p = True +fp_name = file_write((name, type), data) +file_open(fp_name, type, print_p=print_p) +RPCExecute( +'report', name, 'execute', ids, data, context=context, +callback=callback) @staticmethod def execute(action, data, context=None, keyword=False):
[tryton-commits] changeset in modules/sale_payment:default Avoid duplicate record...
changeset fe5699894b9f in modules/sale_payment:default details: https://hg.tryton.org/modules/sale_payment?cmd=changeset;node=fe5699894b9f description: Avoid duplicate records when confirming sale payments issue9969 review322971002 diffstat: account.py | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diffs (14 lines): diff -r 009610ee7f1c -r fe5699894b9f account.py --- a/account.pyFri Jan 22 01:16:37 2021 +0100 +++ b/account.pyMon Jan 25 16:36:22 2021 +0100 @@ -18,8 +18,8 @@ result = func(cls, payments, *args, **kwargs) -sales = [p.origin for p in payments -if isinstance(p.origin, Sale)] +sales = {p.origin for p in payments +if isinstance(p.origin, Sale)} sales = Sale.browse(sales) # optimize cache Sale.payment_confirm(sales)
[tryton-commits] changeset in sao:default Keep empty string attribute of label no...
changeset 668481952aca in sao:default details: https://hg.tryton.org/sao?cmd=changeset;node=668481952aca description: Keep empty string attribute of label node when necessary issue10022 review339691009 diffstat: src/view.js | 3 ++- 1 files changed, 2 insertions(+), 1 deletions(-) diffs (13 lines): diff -r 7c5827774384 -r 668481952aca src/view.js --- a/src/view.js Fri Jan 22 01:15:24 2021 +0100 +++ b/src/view.js Mon Jan 25 15:32:57 2021 +0100 @@ -132,7 +132,8 @@ if (!node_attrs.widget) { node_attrs.widget = field.type; } -if ((node.tagName == 'label') && (!node_attrs.string)) { +if ((node.tagName == 'label') && +(node_attrs.string === undefined)) { node_attrs.string = field.string + Sao.i18n.gettext(':'); } if ((node.tagName == 'field') && (!node_attrs.help)) {