diff --git a/babi_multiprocess.diff b/babi_multiprocess.diff new file mode 100644 index 0000000..30bc38c --- /dev/null +++ b/babi_multiprocess.diff @@ -0,0 +1,25 @@ + diff -r cc988ec8da34 trytond/trytond/protocols/dispatcher.py + --- a/trytond/trytond/protocols/dispatcher.py Mon Apr 23 17:12:37 2018 +0200 + +++ b/trytond/trytond/protocols/dispatcher.py Fri May 11 12:53:17 2018 +0200 + @@ -122,8 +122,19 @@ + type, _ = method.split('.', 1) + name = '.'.join(method.split('.')[1:-1]) + method = method.split('.')[-1] + - return pool.get(name, type=type), method + - + + try: + + obj = pool.get(name, type=type) + + except KeyError: + + if name[:15] == 'babi_execution_': + + with Transaction().start(pool.database_name, request.user_id, + + readonly=False): + + Execution = pool.get('babi.report.execution') + + execution = Execution(int(name[15:])) + + execution.validate_model() + + obj = pool.get(name, type=type) + + else: + + raise + + return obj, method + + @app.auth_required + @with_pool diff --git a/domain_validation_warning.diff b/domain_validation_warning.diff new file mode 100644 index 0000000..0166fd9 --- /dev/null +++ b/domain_validation_warning.diff @@ -0,0 +1,414 @@ +Index: b/trytond/trytond/model/modelstorage.py +=================================================================== +--- a/trytond/trytond/model/modelstorage.py ++++ b/trytond/trytond/model/modelstorage.py +@@ -5,6 +5,7 @@ import datetime + import time + import csv + import warnings ++import logging + + from decimal import Decimal + from itertools import islice, ifilter, chain, izip +@@ -27,6 +28,7 @@ from .modelview import ModelView + from .descriptors import dualmethod + + __all__ = ['ModelStorage', 'EvalEnvironment'] ++logger = logging.getLogger(__name__) + + + def without_check_access(func): +@@ -1009,8 +1011,27 @@ class ModelStorage(Model): + domain, + ]) + if sub_relations != set(finds): ++ fail_field_value = sub_relations.difference( ++ set(finds)).pop() ++ error_args = cls._get_error_args(field.name) ++ error_args.update({ ++ 'value': fail_field_value.rec_name if ++ isinstance(fail_field_value, Model) ++ else fail_field_value, ++ 'domain': getattr(cls, field_name).domain ++ }) ++ msg = cls.raise_user_error('domain_validation_record', ++ error_args=error_args, raise_exception=False) ++ msg += ' Records: ' + ', '.join( ++ [str(r.id) for r in records]) ++ msg += ' Domain: %s' % (domain,) ++ msg += ' Relations: ' + ', '.join( ++ [str(r.id) for r in list(sub_relations)]) ++ msg += ' Finds: ' + ', '.join( ++ [str(r.id) for r in finds]) ++ logger.warn(msg) + cls.raise_user_error('domain_validation_record', +- error_args=cls._get_error_args(field.name)) ++ error_args=error_args) + + field_names = set(field_names or []) + function_fields = {name for name, field in cls._fields.iteritems() +Index: b/trytond/trytond/ir/translation.xml +=================================================================== +--- a/trytond/trytond/ir/translation.xml ++++ b/trytond/trytond/ir/translation.xml +@@ -129,8 +129,8 @@ this repository contains the full copyri + domain_validation_record + en + error +- The value of the field "%(field)s" on "%(model)s" is not valid according to its domain. +- The value of the field "%(field)s" on "%(model)s" is not valid according to its domain. ++ The value "%(value)s" of the field "%(field)s" on "%(model)s" is not valid according to its domain "%(domain)s". ++ The value "%(value)s" of the field "%(field)s" on "%(model)s" is not valid according to its domain "%(domain)s". + ir + + +Index: b/trytond/trytond/ir/locale/bg.po +=================================================================== +--- a/trytond/trytond/ir/locale/bg.po ++++ b/trytond/trytond/ir/locale/bg.po +@@ -26,11 +26,11 @@ msgstr "" + + msgctxt "error:domain_validation_record:" + msgid "" +-"The value of the field \"%(field)s\" on \"%(model)s\" is not valid according" +-" to its domain." ++"The value \"%(value)s\" of the field \"%(field)s\" on \"%(model)s\" is not " ++"valid according to its domain \"%(domain)s\"." + msgstr "" +-"The value of the field \"%(field)s\" on \"%(model)s\" is not valid according" +-" to its domain." ++"The value \"%(value)s\" of the field \"%(field)s\" on \"%(model)s\" is not " ++"valid according to its domain \"%(domain)s\"." + + msgctxt "error:foreign_model_exist:" + msgid "" +Index: b/trytond/trytond/ir/locale/ca.po +=================================================================== +--- a/trytond/trytond/ir/locale/ca.po ++++ b/trytond/trytond/ir/locale/ca.po +@@ -24,11 +24,11 @@ msgstr "" + + msgctxt "error:domain_validation_record:" + msgid "" +-"The value of the field \"%(field)s\" on \"%(model)s\" is not valid according" +-" to its domain." ++"The value \"%(value)s\" of the field \"%(field)s\" on \"%(model)s\" is not " ++"valid according to its domain \"%(domain)s\"." + msgstr "" +-"El valor del camp \"%(field)s\" de \"%(model)s\" no és correcte segons " +-"aquest domini." ++"El valor \"%(field)s\" del camp \"%(field)s\" de \"%(model)s\" no és correcte segons " ++"aquest domini \"%(domain)s\"." + + msgctxt "error:foreign_model_exist:" + msgid "" +Index: b/trytond/trytond/ir/locale/cs.po +=================================================================== +--- a/trytond/trytond/ir/locale/cs.po ++++ b/trytond/trytond/ir/locale/cs.po +@@ -24,11 +24,11 @@ msgstr "" + + msgctxt "error:domain_validation_record:" + msgid "" +-"The value of the field \"%(field)s\" on \"%(model)s\" is not valid according" +-" to its domain." ++"The value \"%(value)s\" of the field \"%(field)s\" on \"%(model)s\" is not " ++"valid according to its domain \"%(domain)s\"." + msgstr "" +-"The value of the field \"%(field)s\" on \"%(model)s\" is not valid according" +-" to its domain." ++"The value \"%(value)s\" of the field \"%(field)s\" on \"%(model)s\" is not " ++"valid according to its domain \"%(domain)s\"." + + msgctxt "error:foreign_model_exist:" + msgid "" +Index: b/trytond/trytond/ir/locale/de.po +=================================================================== +--- a/trytond/trytond/ir/locale/de.po ++++ b/trytond/trytond/ir/locale/de.po +@@ -23,11 +23,11 @@ msgstr "" + + msgctxt "error:domain_validation_record:" + msgid "" +-"The value of the field \"%(field)s\" on \"%(model)s\" is not valid according" +-" to its domain." ++"The value \"%(value)s\" of the field \"%(field)s\" on \"%(model)s\" is not " ++"valid according to its domain \"%(domain)s\"." + msgstr "" +-"Der Wert des Feldes \"%(field)s\" in \"%(model)s\" liegt nicht im gültigen " +-"Wertebereich (Domain)." ++"Der Wert \"%(value)s\" des Feldes \"%(field)s\" in \"%(model)s\" liegt nicht im gültigen " ++"Wertebereich (Domain) \"%(domain)s\"." + + msgctxt "error:foreign_model_exist:" + msgid "" +Index: b/trytond/trytond/ir/locale/es.po +=================================================================== +--- a/trytond/trytond/ir/locale/es.po ++++ b/trytond/trytond/ir/locale/es.po +@@ -22,11 +22,11 @@ msgstr "" + + msgctxt "error:domain_validation_record:" + msgid "" +-"The value of the field \"%(field)s\" on \"%(model)s\" is not valid according" +-" to its domain." ++"The value \"%(value)s\" of the field \"%(field)s\" on \"%(model)s\" is not " ++"valid according to its domain \"%(domain)s\"." + msgstr "" +-"El valor del campo \"%(field)s\" de \"%(model)s\" no es correcto según su " +-"dominio." ++"El valor \"%(value)s\" del campo \"%(field)s\" de \"%(model)s\" no es correcto según su " ++"dominio \"%(domain)s\"." + + msgctxt "error:foreign_model_exist:" + msgid "" +Index: b/trytond/trytond/ir/locale/es_419.po +=================================================================== +--- a/trytond/trytond/ir/locale/es_419.po ++++ b/trytond/trytond/ir/locale/es_419.po +@@ -20,8 +20,8 @@ msgstr "" + + msgctxt "error:domain_validation_record:" + msgid "" +-"The value of the field \"%(field)s\" on \"%(model)s\" is not valid according" +-" to its domain." ++"The value \"%(value)s\" of the field \"%(field)s\" on \"%(model)s\" is not " ++"valid according to its domain \"%(domain)s\"." + msgstr "" + + msgctxt "error:foreign_model_exist:" +Index: b/trytond/trytond/ir/locale/fa.po +=================================================================== +--- a/trytond/trytond/ir/locale/fa.po ++++ b/trytond/trytond/ir/locale/fa.po +@@ -24,8 +24,8 @@ msgstr "" + + msgctxt "error:domain_validation_record:" + msgid "" +-"The value of the field \"%(field)s\" on \"%(model)s\" is not valid according" +-" to its domain." ++"The value \"%(value)s\" of the field \"%(field)s\" on \"%(model)s\" is not " ++"valid according to its domain \"%(domain)s\"." + msgstr "مقدار فیلد: \"%s\" در مدل: \"%s\" باتوجه به دامنه آن معتبر نیست." + + msgctxt "error:foreign_model_exist:" +Index: b/trytond/trytond/ir/locale/fr.po +=================================================================== +--- a/trytond/trytond/ir/locale/fr.po ++++ b/trytond/trytond/ir/locale/fr.po +@@ -24,11 +24,11 @@ msgstr "" + + msgctxt "error:domain_validation_record:" + msgid "" +-"The value of the field \"%(field)s\" on \"%(model)s\" is not valid according" +-" to its domain." ++"The value \"%(value)s\" of the field \"%(field)s\" on \"%(model)s\" is not " ++"valid according to its domain \"%(domain)s\"." + msgstr "" +-"La valeur du champ « %(field)s » sur « %(model)s » n'est pas valide selon " +-"son domaine." ++"La valeur \"%(value)s\" du champ « %(field)s » sur « %(model)s » n'est pas valide selon " ++"son domaine \"%(domain)s\"." + + msgctxt "error:foreign_model_exist:" + msgid "" +Index: b/trytond/trytond/ir/locale/hu_HU.po +=================================================================== +--- a/trytond/trytond/ir/locale/hu_HU.po ++++ b/trytond/trytond/ir/locale/hu_HU.po +@@ -27,11 +27,11 @@ msgstr "" + #, fuzzy + msgctxt "error:domain_validation_record:" + msgid "" +-"The value of the field \"%(field)s\" on \"%(model)s\" is not valid according" +-" to its domain." ++"The value \"%(value)s\" of the field \"%(field)s\" on \"%(model)s\" is not " ++"valid according to its domain \"%(domain)s\"." + msgstr "" +-"The value of the field \"%(field)s\" on \"%(model)s\" is not valid according" +-" to its domain." ++"The value \"%(value)s\" of the field \"%(field)s\" on \"%(model)s\" is not " ++"valid according to its domain \"%(domain)s\"." + + #, fuzzy + msgctxt "error:foreign_model_exist:" +Index: b/trytond/trytond/ir/locale/it_IT.po +=================================================================== +--- a/trytond/trytond/ir/locale/it_IT.po ++++ b/trytond/trytond/ir/locale/it_IT.po +@@ -27,11 +27,11 @@ msgstr "" + #, fuzzy + msgctxt "error:domain_validation_record:" + msgid "" +-"The value of the field \"%(field)s\" on \"%(model)s\" is not valid according" +-" to its domain." ++"The value \"%(value)s\" of the field \"%(field)s\" on \"%(model)s\" is not " ++"valid according to its domain \"%(domain)s\"." + msgstr "" +-"The value of the field \"%(field)s\" on \"%(model)s\" is not valid according" +-" to its domain." ++"The value \"%(value)s\" of the field \"%(field)s\" on \"%(model)s\" is not " ++"valid according to its domain \"%(domain)s\"." + + #, fuzzy + msgctxt "error:foreign_model_exist:" +Index: b/trytond/trytond/ir/locale/ja_JP.po +=================================================================== +--- a/trytond/trytond/ir/locale/ja_JP.po ++++ b/trytond/trytond/ir/locale/ja_JP.po +@@ -24,11 +24,11 @@ msgstr "" + + msgctxt "error:domain_validation_record:" + msgid "" +-"The value of the field \"%(field)s\" on \"%(model)s\" is not valid according" +-" to its domain." ++"The value \"%(value)s\" of the field \"%(field)s\" on \"%(model)s\" is not " ++"valid according to its domain \"%(domain)s\"." + msgstr "" +-"The value of the field \"%(field)s\" on \"%(model)s\" is not valid according" +-" to its domain." ++"The value \"%(value)s\" of the field \"%(field)s\" on \"%(model)s\" is not " ++"valid according to its domain \"%(domain)s\"." + + msgctxt "error:foreign_model_exist:" + msgid "" +Index: b/trytond/trytond/ir/locale/lo.po +=================================================================== +--- a/trytond/trytond/ir/locale/lo.po ++++ b/trytond/trytond/ir/locale/lo.po +@@ -24,11 +24,11 @@ msgstr "" + + msgctxt "error:domain_validation_record:" + msgid "" +-"The value of the field \"%(field)s\" on \"%(model)s\" is not valid according" +-" to its domain." ++"The value \"%(value)s\" of the field \"%(field)s\" on \"%(model)s\" is not " ++"valid according to its domain \"%(domain)s\"." + msgstr "" +-"The value of the field \"%(field)s\" on \"%(model)s\" is not valid according" +-" to its domain." ++"The value \"%(value)s\" of the field \"%(field)s\" on \"%(model)s\" is not " ++"valid according to its domain \"%(domain)s\"." + + msgctxt "error:foreign_model_exist:" + msgid "" +Index: b/trytond/trytond/ir/locale/nl.po +=================================================================== +--- a/trytond/trytond/ir/locale/nl.po ++++ b/trytond/trytond/ir/locale/nl.po +@@ -26,11 +26,11 @@ msgstr "" + + msgctxt "error:domain_validation_record:" + msgid "" +-"The value of the field \"%(field)s\" on \"%(model)s\" is not valid according" +-" to its domain." ++"The value \"%(value)s\" of the field \"%(field)s\" on \"%(model)s\" is not " ++"valid according to its domain \"%(domain)s\"." + msgstr "" +-"The value of the field \"%(field)s\" on \"%(model)s\" is not valid according" +-" to its domain." ++"The value \"%(value)s\" of the field \"%(field)s\" on \"%(model)s\" is not " ++"valid according to its domain \"%(domain)s\"." + + msgctxt "error:foreign_model_exist:" + msgid "" +Index: b/trytond/trytond/ir/locale/pl.po +=================================================================== +--- a/trytond/trytond/ir/locale/pl.po ++++ b/trytond/trytond/ir/locale/pl.po +@@ -24,11 +24,11 @@ msgstr "" + + msgctxt "error:domain_validation_record:" + msgid "" +-"The value of the field \"%(field)s\" on \"%(model)s\" is not valid according" +-" to its domain." ++"The value \"%(value)s\" of the field \"%(field)s\" on \"%(model)s\" is not " ++"valid according to its domain \"%(domain)s\"." + msgstr "" +-"Wartość w polu \"%(field)s\" dla \"%(model)s\" jest nieprawidłowa względem " +-"swojej domeny." ++"Wartość \"%(value)s\" w polu \"%(field)s\" dla \"%(model)s\" jest " ++"nieprawidłowa względem swojej domeny\"%(domain)s\"." + + msgctxt "error:foreign_model_exist:" + msgid "" +Index: b/trytond/trytond/ir/locale/pt_BR.po +=================================================================== +--- a/trytond/trytond/ir/locale/pt_BR.po ++++ b/trytond/trytond/ir/locale/pt_BR.po +@@ -27,11 +27,11 @@ msgstr "" + #, fuzzy + msgctxt "error:domain_validation_record:" + msgid "" +-"The value of the field \"%(field)s\" on \"%(model)s\" is not valid according" +-" to its domain." ++"The value \"%(value)s\" of the field \"%(field)s\" on \"%(model)s\" is not " ++"valid according to its domain \"%(domain)s\"." + msgstr "" +-"The value of the field \"%(field)s\" on \"%(model)s\" is not valid according" +-" to its domain." ++"The value \"%(value)s\" of the field \"%(field)s\" on \"%(model)s\" is not " ++"valid according to its domain \"%(domain)s\"." + + #, fuzzy + msgctxt "error:foreign_model_exist:" +Index: b/trytond/trytond/ir/locale/ru.po +=================================================================== +--- a/trytond/trytond/ir/locale/ru.po ++++ b/trytond/trytond/ir/locale/ru.po +@@ -26,11 +26,11 @@ msgstr "" + + msgctxt "error:domain_validation_record:" + msgid "" +-"The value of the field \"%(field)s\" on \"%(model)s\" is not valid according" +-" to its domain." ++"The value \"%(value)s\" of the field \"%(field)s\" on \"%(model)s\" is not " ++"valid according to its domain \"%(domain)s\"." + msgstr "" +-"The value of the field \"%(field)s\" on \"%(model)s\" is not valid according" +-" to its domain." ++"The value \"%(value)s\" of the field \"%(field)s\" on \"%(model)s\" is not " ++"valid according to its domain \"%(domain)s\"."" + + msgctxt "error:foreign_model_exist:" + msgid "" +Index: b/trytond/trytond/ir/locale/sl.po +=================================================================== +--- a/trytond/trytond/ir/locale/sl.po ++++ b/trytond/trytond/ir/locale/sl.po +@@ -27,11 +27,11 @@ msgstr "" + #, fuzzy + msgctxt "error:domain_validation_record:" + msgid "" +-"The value of the field \"%(field)s\" on \"%(model)s\" is not valid according" +-" to its domain." ++"The value \"%(value)s\" of the field \"%(field)s\" on \"%(model)s\" is not " ++"valid according to its domain \"%(domain)s\"." + msgstr "" +-"The value of the field \"%(field)s\" on \"%(model)s\" is not valid according" +-" to its domain." ++"The value \"%(value)s\" of the field \"%(field)s\" on \"%(model)s\" is not " ++"valid according to its domain \"%(domain)s\"." + + #, fuzzy + msgctxt "error:foreign_model_exist:" +Index: b/trytond/trytond/ir/locale/zh_CN.po +=================================================================== +--- a/trytond/trytond/ir/locale/zh_CN.po ++++ b/trytond/trytond/ir/locale/zh_CN.po +@@ -27,11 +27,11 @@ msgstr "" + #, fuzzy + msgctxt "error:domain_validation_record:" + msgid "" +-"The value of the field \"%(field)s\" on \"%(model)s\" is not valid according" +-" to its domain." ++"The value \"%(value)s\" of the field \"%(field)s\" on \"%(model)s\" is not " ++"valid according to its domain \"%(domain)s\"." + msgstr "" +-"The value of the field \"%(field)s\" on \"%(model)s\" is not valid according" +-" to its domain." ++"The value \"%(value)s\" of the field \"%(field)s\" on \"%(model)s\" is not " ++"valid according to its domain \"%(domain)s\"." + + #, fuzzy + msgctxt "error:foreign_model_exist:" diff --git a/improve_performance_on_try_assign.diff b/improve_performance_on_try_assign.diff new file mode 100644 index 0000000..d2245fe --- /dev/null +++ b/improve_performance_on_try_assign.diff @@ -0,0 +1,43 @@ +diff -r 3239605d105d move.py +--- a/trytond/trytond/modules/stock/move.py Mon May 21 20:17:34 2018 +0200 ++++ b/trytond/trytond/modules/stock/move.py Fri Jul 20 12:16:25 2018 +0200 +@@ -850,6 +850,7 @@ + ]) + else: + locations = list(set((m.from_location for m in moves))) ++ + location_ids = [l.id for l in locations] + product_ids = list(set((m.product.id for m in moves))) + stock_date_end = Date.today() +@@ -1446,12 +1447,27 @@ + if location not in location_ids: + del quantities[key] + +- # Round quantities +- default_uom = dict((p.id, p.default_uom) for p in +- Model.browse(list(ids))) ++ Uom = Pool().get('product.uom') ++ ttemplate = Template.__table__() ++ table = Model.__table__() ++ cursor = Transaction().connection.cursor() ++ ++ if Model == Template: ++ cursor.execute(*ttemplate.select(ttemplate.id, ++ ttemplate.default_uom, ++ where=reduce_ids(ttemplate.id, ids))) ++ else: ++ cursor.execute(*ttemplate.join(table, ++ condition=table.template == ttemplate.id).select( ++ table.id, ttemplate.default_uom, ++ where=reduce_ids(table.id, ids))) ++ ++ default_uom = dict((x[0], x[1]) for x in ++ cursor.fetchall()) ++ + for key, quantity in quantities.iteritems(): + location = key[0] +- uom = default_uom[id_getter(key)] ++ uom = Uom(default_uom[id_getter(key)]) + quantities[key] = uom.round(quantity) + + return quantities diff --git a/issue10467.diff b/issue10467.diff new file mode 100644 index 0000000..249aa91 --- /dev/null +++ b/issue10467.diff @@ -0,0 +1,24 @@ +diff -r 8a6a82c717d6 stock.py +--- a/trytond/trytond/modules/stock_lot/stock.py Tue Jul 10 12:57:12 2018 +0200 ++++ b/trytond/trytond/modules/stock_lot/stock.py Tue Jul 10 12:58:45 2018 +0200 +@@ -159,6 +159,20 @@ + 'lot_required': 'Lot is required for move of product "%s".', + }) + ++ @classmethod ++ def assign_try(cls, moves, with_childs=True, grouping=('product',)): ++ lot_moves = [] ++ product_moves = [] ++ for move in moves: ++ if move.lot: ++ lot_moves.append(move) ++ else: ++ product_moves.append(move) ++ return (super(Move, cls).assign_try(lot_moves, ++ with_childs=with_childs, grouping=('product', 'lot')) ++ & super(Move, cls).assign_try(product_moves, ++ with_childs=with_childs, grouping=grouping)) ++ + def check_lot(self): + "Check if lot is required" + if (self.state == 'done' diff --git a/issue240_631.diff b/issue240_631.diff new file mode 100644 index 0000000..f14a5b0 --- /dev/null +++ b/issue240_631.diff @@ -0,0 +1,323 @@ +diff -r d1102046dce6 __init__.py +--- a/trytond/trytond/modules/stock_lot/__init__.py Mon Apr 23 17:32:23 2018 +0200 ++++ b/trytond/trytond/modules/stock_lot/__init__.py Thu Jun 14 14:59:26 2018 +0200 +@@ -2,24 +2,29 @@ + # this repository contains the full copyright notices and license terms. + + from trytond.pool import Pool +-from .stock import * +-from .product import * ++from . import stock ++from . import product + + + def register(): + Pool.register( +- Lot, +- LotByLocationContext, +- LotType, +- Move, +- ShipmentIn, +- ShipmentOut, +- ShipmentOutReturn, +- Period, +- PeriodCacheLot, +- Inventory, +- InventoryLine, +- Template, +- Product, +- TemplateLotType, ++ stock.Lot, ++ stock.LotByLocationContext, ++ stock.LotType, ++ stock.Move, ++ stock.ShipmentIn, ++ stock.ShipmentOut, ++ stock.ShipmentOutReturn, ++ stock.Period, ++ stock.PeriodCacheLot, ++ stock.Inventory, ++ stock.InventoryLine, ++ product.Template, ++ product.Product, ++ product.TemplateLotType, ++ stock.Location, ++ stock.LotByLocationStart, + module='stock_lot', type_='model') ++ Pool.register( ++ stock.LotByLocation, ++ module='stock_lot', type_='wizard') +diff -r d1102046dce6 stock.py +--- a/trytond/trytond/modules/stock_lot/stock.py Mon Apr 23 17:32:23 2018 +0200 ++++ b/trytond/trytond/modules/stock_lot/stock.py Thu Jun 14 14:59:26 2018 +0200 +@@ -4,16 +4,86 @@ + from collections import defaultdict + + from trytond.model import ModelView, ModelSQL, fields +-from trytond.pyson import Eval ++from trytond.pyson import PYSONEncoder, Eval + from trytond.pool import Pool, PoolMeta + from trytond.transaction import Transaction + from trytond.modules.stock import StockMixin ++from trytond.wizard import Wizard, StateView, StateAction, Button + +-__all__ = ['Lot', 'LotType', 'Move', 'ShipmentIn', 'ShipmentOut', ++_all__ = ['Lot', 'LotType', 'Move', 'ShipmentIn', 'ShipmentOut', + 'LotByLocationContext', 'ShipmentOutReturn', + 'Period', 'PeriodCacheLot', +- 'Inventory', 'InventoryLine', 'LotByLocationContext'] ++ 'Inventory', 'InventoryLine', 'LotByLocationContext', ++ 'Location', 'LotByLocation', 'LotByLocationStart'] ++ ++ ++class Location: ++ __name__ = 'stock.location' ++ __metaclass__ = PoolMeta ++ ++ @classmethod ++ def _quantity_grouping_and_key(cls): ++ if Transaction().context.get('lot'): ++ lot_id = Transaction().context['lot'] ++ product_id = Transaction().context['product'] ++ return ('product', 'lot'), (product_id, lot_id) ++ return super(Location, cls)._quantity_grouping_and_key() ++ ++ ++class LotByLocationStart(ModelView): ++ 'Lot by Location' ++ __name__ = 'stock.lot.by_location.start' ++ forecast_date = fields.Date( ++ 'At Date', help=('Allow to compute expected ' ++ 'stock quantities for this date.\n' ++ '* An empty value is an infinite date in the future.\n' ++ '* A date in the past will provide historical values.')) ++ ++ @staticmethod ++ def default_forecast_date(): ++ Date = Pool().get('ir.date') ++ return Date.today() ++ + ++class LotByLocation(Wizard): ++ 'Lot by Location' ++ __name__ = 'stock.lot.by_location' ++ start = StateView('stock.lot.by_location.start', ++ 'stock_lot.lot_by_location_start_view_form', [ ++ Button('Cancel', 'end', 'tryton-cancel'), ++ Button('Open', 'open', 'tryton-ok', default=True), ++ ]) ++ open = StateAction('stock.act_location_quantity_tree') ++ ++ def do_open(self, action): ++ pool = Pool() ++ Lot = pool.get('stock.lot') ++ Lang = pool.get('ir.lang') ++ ++ context = {} ++ lot_id = Transaction().context['active_id'] ++ context['lot'] = lot_id ++ ++ lot = Lot(lot_id) ++ context['product'] = lot.product.id ++ ++ if self.start.forecast_date: ++ context['stock_date_end'] = self.start.forecast_date ++ else: ++ context['stock_date_end'] = datetime.date.max ++ action['pyson_context'] = PYSONEncoder().encode(context) ++ ++ for code in [Transaction().language, 'en_US']: ++ langs = Lang.search([ ++ ('code', '=', code), ++ ]) ++ if langs: ++ break ++ lang, = langs ++ date = lang.strftime(context['stock_date_end']) ++ action['name'] += ' - %s (%s) @ %s' % (lot.rec_name, ++ lot.product.default_uom.rec_name, date) ++ return action, {} + + class Lot(ModelSQL, ModelView, StockMixin): + "Stock Lot" +diff -r d1102046dce6 stock.xml +--- a/trytond/trytond/modules/stock_lot/stock.xml Mon Apr 23 17:32:23 2018 +0200 ++++ b/trytond/trytond/modules/stock_lot/stock.xml Thu Jun 14 14:59:26 2018 +0200 +@@ -112,6 +112,28 @@ + + + ++ ++ ++ Lot by Locations ++ stock.lot.by_location ++ stock.lot ++ ++ ++ form_relate ++ stock.lot,-1 ++ ++ ++ ++ ++ ++ ++ ++ stock.lot.by_location.start ++ form ++ lot_by_location_start_form ++ ++ + + supplier + Supplier +diff -r d1102046dce6 view/lot_by_location_start_form.xml +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/trytond/trytond/modules/stock_lot/view/lot_by_location_start_form.xml Thu Jun 14 14:59:26 2018 +0200 +@@ -0,0 +1,7 @@ ++ ++ ++
++
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/issue4030.diff b/issue4030.diff new file mode 100644 index 0000000..d752df5 --- /dev/null +++ b/issue4030.diff @@ -0,0 +1,12 @@ +diff -r 1329bfa523a8 trytond/trytond/modules/analytic_account/line.py +--- a/trytond/trytond/modules/analytic_account/line.py Mon Apr 23 17:28:19 2018 +0200 ++++ b/trytond/trytond/modules/analytic_account/line.py Fri May 11 13:16:07 2018 +0200 +@@ -28,7 +28,7 @@ + 'on_change_with_company', searcher='search_company') + account = fields.Many2One('analytic_account.account', 'Account', + required=True, select=True, domain=[ +- ('type', 'not in', ['view', 'distribution']), ++ ('type', 'not in', ['view', 'distribution', 'root']), + ['OR', + ('company', '=', None), + ('company', '=', Eval('company', -1)), diff --git a/issue4341.diff b/issue4341.diff new file mode 100644 index 0000000..a1e7df0 --- /dev/null +++ b/issue4341.diff @@ -0,0 +1,72 @@ +diff -r e978ecc8f044 trytond/trytond/modules/account/view/account_list.xml +--- a/trytond/trytond/modules/account/view/account_list.xml Mon Apr 23 17:24:11 2018 +0200 ++++ b/trytond/trytond/modules/account/view/account_list.xml Fri May 11 14:15:10 2018 +0200 +@@ -5,4 +5,5 @@ + + + ++ + +diff -r e978ecc8f044 trytond/trytond/modules/account/view/account_tree.xml +--- a/trytond/trytond/modules/account/view/account_tree.xml Mon Apr 23 17:24:11 2018 +0200 ++++ b/trytond/trytond/modules/account/view/account_tree.xml Fri May 11 14:15:10 2018 +0200 +@@ -7,4 +7,5 @@ + + + ++ + +diff -r e978ecc8f044 trytond/trytond/modules/account/view/journal_period_tree.xml +--- a/trytond/trytond/modules/account/view/journal_period_tree.xml Mon Apr 23 17:24:11 2018 +0200 ++++ b/trytond/trytond/modules/account/view/journal_period_tree.xml Fri May 11 14:15:10 2018 +0200 +@@ -5,4 +5,5 @@ + + + ++ + +diff -r e978ecc8f044 trytond/trytond/modules/account/view/journal_tree.xml +--- a/trytond/trytond/modules/account/view/journal_tree.xml Mon Apr 23 17:24:11 2018 +0200 ++++ b/trytond/trytond/modules/account/view/journal_tree.xml Fri May 11 14:15:10 2018 +0200 +@@ -5,4 +5,5 @@ + + + ++ + +diff -r e978ecc8f044 trytond/trytond/modules/account/view/move_template_list.xml +--- a/trytond/trytond/modules/account/view/move_template_list.xml Mon Apr 23 17:24:11 2018 +0200 ++++ b/trytond/trytond/modules/account/view/move_template_list.xml Fri May 11 14:15:10 2018 +0200 +@@ -3,4 +3,5 @@ + this repository contains the full copyright notices and license terms. --> + + ++ + +diff -r e978ecc8f044 trytond/trytond/modules/account/view/tax_code_list.xml +--- a/trytond/trytond/modules/account/view/tax_code_list.xml Mon Apr 23 17:24:11 2018 +0200 ++++ b/trytond/trytond/modules/account/view/tax_code_list.xml Fri May 11 14:15:10 2018 +0200 +@@ -5,4 +5,5 @@ + + + ++ + +diff -r e978ecc8f044 trytond/trytond/modules/account/view/tax_code_tree.xml +--- a/trytond/trytond/modules/account/view/tax_code_tree.xml Mon Apr 23 17:24:11 2018 +0200 ++++ b/trytond/trytond/modules/account/view/tax_code_tree.xml Fri May 11 14:15:10 2018 +0200 +@@ -7,4 +7,5 @@ + + + ++ + +diff -r e978ecc8f044 trytond/trytond/modules/account/view/tax_list.xml +--- a/trytond/trytond/modules/account/view/tax_list.xml Mon Apr 23 17:24:11 2018 +0200 ++++ b/trytond/trytond/modules/account/view/tax_list.xml Fri May 11 14:15:10 2018 +0200 +@@ -5,4 +5,5 @@ + + + ++ + diff --git a/issue4482.diff b/issue4482.diff new file mode 100644 index 0000000..b071370 --- /dev/null +++ b/issue4482.diff @@ -0,0 +1,19 @@ +diff -r 98c229b8cb4a trytond/trytond/modules/stock/inventory.xml +--- a/trytond/trytond/modules/stock/inventory.xml Mon Apr 23 17:29:56 2018 +0200 ++++ b/trytond/trytond/modules/stock/inventory.xml Fri May 11 13:46:51 2018 +0200 +@@ -60,6 +60,15 @@ + inventory_line_tree + + ++ ++ ++ ++ ++ ++ ++ ++ ++ + + + diff --git a/issue4506.diff b/issue4506.diff new file mode 100644 index 0000000..37e2d6a --- /dev/null +++ b/issue4506.diff @@ -0,0 +1,49 @@ +diff -r 9cd9f1c27fdd trytond/trytond/modules/account_invoice/invoice.xml +--- a/trytond/trytond/modules/account_invoice/invoice.xml Mon Apr 23 17:32:58 2018 +0200 ++++ b/trytond/trytond/modules/account_invoice/invoice.xml Fri May 11 13:11:48 2018 +0200 +@@ -132,6 +132,17 @@ + + ++ ++ Credit Notes ++ account.invoice ++ ++ ++ ++ form_relate ++ account.invoice,-1 ++ ++ ++ + + + +diff -r 9cd9f1c27fdd trytond/trytond/modules/account_invoice/locale/ca.po +--- a/trytond/trytond/modules/account_invoice/locale/ca.po Mon Apr 23 17:32:58 2018 +0200 ++++ b/trytond/trytond/modules/account_invoice/locale/ca.po Fri May 11 13:11:48 2018 +0200 +@@ -1127,6 +1127,10 @@ + msgid "Invoice Tax" + msgstr "Impost de factura" + ++msgctxt "model:ir.action,name:act_credit_notes_form" ++msgid "Credit Notes" ++msgstr "Abonaments" ++ + msgctxt "model:ir.action,name:act_invoice_form" + msgid "Invoices" + msgstr "Factures" +diff -r 9cd9f1c27fdd trytond/trytond/modules/account_invoice/locale/es.po +--- a/trytond/trytond/modules/account_invoice/locale/es.po Mon Apr 23 17:32:58 2018 +0200 ++++ b/trytond/trytond/modules/account_invoice/locale/es.po Fri May 11 13:11:48 2018 +0200 +@@ -1123,6 +1123,10 @@ + msgid "Invoice Tax" + msgstr "Impuesto de factura" + ++msgctxt "model:ir.action,name:act_credit_notes_form" ++msgid "Credit Notes" ++msgstr "Abonos" ++ + msgctxt "model:ir.action,name:act_invoice_form" + msgid "Invoices" + msgstr "Facturas" diff --git a/issue53451002_1_10001.diff b/issue53451002_1_10001.diff new file mode 100644 index 0000000..9bcfec6 --- /dev/null +++ b/issue53451002_1_10001.diff @@ -0,0 +1,93 @@ +diff -r 29eb0f164bcb move.py +--- a/trytond/trytond/modules/stock/move.py Tue Oct 30 12:37:21 2018 +0100 ++++ b/trytond/trytond/modules/stock/move.py Tue Oct 30 12:41:42 2018 +0100 +@@ -850,7 +850,6 @@ + ]) + else: + locations = list(set((m.from_location for m in moves))) +- + location_ids = [l.id for l in locations] + product_ids = list(set((m.product.id for m in moves))) + stock_date_end = Date.today() +@@ -967,7 +966,8 @@ + + @classmethod + def compute_quantities_query(cls, location_ids, with_childs=False, +- grouping=('product',), grouping_filter=None): ++ grouping=('product',), grouping_filter=None, ++ quantity_field='internal_quantity'): + """ + Prepare a query object to compute for each location and product the + stock quantity in the default uom of the product. +@@ -985,6 +985,8 @@ + stock_skip_warehouse: if set, quantities on a warehouse are no more + quantities of all child locations but quantities of the storage + zone. ++ quantity_field is the name of the field containing the quantity to be ++ aggregated + If with_childs, it computes also for child locations. + grouping is a tuple of Move (or Product if prefixed by 'product.') + field names and defines how stock moves are grouped. +@@ -1037,7 +1039,7 @@ + if use_product: + product = Product.__table__() + columns = ['id', 'state', 'effective_date', 'planned_date', +- 'internal_quantity', 'from_location', 'to_location'] ++ quantity_field, 'from_location', 'to_location'] + columns += list(grouping) + columns = [get_column(c, move, product) for c in columns] + move = (move +@@ -1050,7 +1052,7 @@ + period_cache = PeriodCache.__table__() + if use_product: + product_cache = Product.__table__() +- columns = ['internal_quantity', 'period', 'location'] ++ columns = [quantity_field, 'period', 'location'] + columns += list(grouping) + columns = [get_column(c, period_cache, product_cache) + for c in columns] +@@ -1067,7 +1069,7 @@ + to_location = Location.__table__() + to_parent_location = Location.__table__() + columns = ['id', 'state', 'effective_date', 'planned_date', +- 'internal_quantity'] + list(grouping) ++ quantity_field] + list(grouping) + columns = [Column(move, c).as_(c) for c in columns] + + move_with_parent = (move +@@ -1121,7 +1123,7 @@ + if PeriodCache: + location = Location.__table__() + parent_location = Location.__table__() +- columns = ['internal_quantity', 'period'] + list(grouping) ++ columns = [quantity_field, 'period'] + list(grouping) + columns = [Column(period_cache, c).as_(c) for c in columns] + period_cache = Union( + period_cache.select( +@@ -1319,7 +1321,7 @@ + move_keys_alias = [Column(move, key).as_(key) for key in grouping] + move_keys = [Column(move, key) for key in grouping] + query = move.select(move.to_location.as_('location'), +- Sum(move.internal_quantity).as_('quantity'), ++ Sum(getattr(move, quantity_field)).as_('quantity'), + *move_keys_alias, + where=state_date_clause_in + & where +@@ -1329,7 +1331,7 @@ + & dest_clause_from, + group_by=[move.to_location] + move_keys) + query = Union(query, move.select(move.from_location.as_('location'), +- (-Sum(move.internal_quantity)).as_('quantity'), ++ (-Sum(getattr(move, quantity_field))).as_('quantity'), + *move_keys_alias, + where=state_date_clause_out + & where +@@ -1344,7 +1346,7 @@ + for key in grouping] + query = Union(query, from_period.select( + period_cache.location.as_('location'), +- period_cache.internal_quantity.as_('quantity'), ++ getattr(period_cache, quantity_field).as_('quantity'), + *period_keys, + where=(period_cache.period + == (period.id if period else None)) diff --git a/issue7276.diff b/issue7276.diff new file mode 100644 index 0000000..7e365cf --- /dev/null +++ b/issue7276.diff @@ -0,0 +1,21 @@ +diff -r 0447f28ab266 trytond/trytond/modules/account/move.py +--- a/trytond/trytond/modules/account/move.py Wed Sep 12 15:56:58 2018 +0200 ++++ b/trytond/trytond/modules/account/move.py Wed Sep 12 16:09:55 2018 +0200 +@@ -635,7 +635,6 @@ + party_required = fields.Function(fields.Boolean('Party Required'), + 'on_change_with_party_required') + maturity_date = fields.Date('Maturity Date', +- states=_states, depends=_depends, + help='This field is used for payable and receivable lines. \n' + 'You can put the limit date for the payment.') + state = fields.Selection([ +@@ -668,7 +667,8 @@ + @classmethod + def __setup__(cls): + super(Line, cls).__setup__() +- cls._check_modify_exclude = {'reconciliation'} ++ cls._check_modify_exclude = { ++ 'maturity_date', 'reconciliation', 'tax_lines'} + cls._reconciliation_modify_disallow = { + 'account', 'debit', 'credit', 'party', + } diff --git a/issue7826.diff b/issue7826.diff new file mode 100644 index 0000000..0775218 --- /dev/null +++ b/issue7826.diff @@ -0,0 +1,13 @@ +diff -r 4c5abccfccf2 trytond/trytond/modules/stock_package/stock.py +--- a/trytond/trytond/modules/stock_package/stock.py Mon Apr 23 17:36:31 2018 +0200 ++++ b/trytond/trytond/modules/stock_package/stock.py Tue Oct 30 12:45:02 2018 +0100 +@@ -212,7 +212,8 @@ + + @property + def packages_moves(self): +- return (m for m in self.outgoing_moves if m.state != 'cancel') ++ return (m for m in self.outgoing_moves ++ if m.state != 'cancel' and m.quantity != 0.0) + + + class ShipmentInReturn(PackageMixin, object): diff --git a/issue7856.diff b/issue7856.diff new file mode 100644 index 0000000..2a10b63 --- /dev/null +++ b/issue7856.diff @@ -0,0 +1,20 @@ +diff -r 10d517bd46f1 trytond/trytond/modules/stock/move.py +--- a/trytond/trytond/modules/stock/move.py Wed Nov 14 09:54:25 2018 +0100 ++++ b/trytond/trytond/modules/stock/move.py Wed Nov 14 09:55:39 2018 +0100 +@@ -907,6 +907,7 @@ + if move.state == 'staging': + success = False + continue ++ to_location = move.to_location + # Keep location order for pick_product + location_qties = OrderedDict() + if with_childs: +@@ -919,6 +920,8 @@ + else: + childs = [move.from_location] + for location in childs: ++ if location.id == to_location.id: ++ continue + key = get_key(move, location) + if key in pbl: + location_qties[location] = Uom.compute_qty( diff --git a/logging_jsonrpc_exeption.diff b/logging_jsonrpc_exeption.diff new file mode 100644 index 0000000..d3f9e31 --- /dev/null +++ b/logging_jsonrpc_exeption.diff @@ -0,0 +1,31 @@ +diff -r 7ed03689fe01 trytond/trytond/protocols/dispatcher.py +--- a/trytond/trytond/protocols/dispatcher.py Fri May 11 13:52:50 2018 +0200 ++++ b/trytond/trytond/protocols/dispatcher.py Fri May 11 13:56:27 2018 +0200 +@@ -192,7 +192,7 @@ + raise + except (ConcurrencyException, UserError, UserWarning, + LoginException): +- logger.debug(log_message, *log_args, exc_info=True) ++ logger.warning(log_message, *log_args, exc_info=True) + raise + except Exception: + logger.error(log_message, *log_args, exc_info=True) +diff -r 7ed03689fe01 trytond/trytond/protocols/jsonrpc.py +--- a/trytond/trytond/protocols/jsonrpc.py Fri May 11 13:52:50 2018 +0200 ++++ b/trytond/trytond/protocols/jsonrpc.py Fri May 11 13:56:27 2018 +0200 +@@ -4,6 +4,7 @@ + from decimal import Decimal + import json + import base64 ++import logging + + from werkzeug.wrappers import Response + from werkzeug.utils import cached_property +@@ -12,6 +13,8 @@ + from trytond.protocols.wrappers import Request + from trytond.exceptions import TrytonException + ++logger = logging.getLogger(__name__) ++ + + class JSONDecoder(object): diff --git a/match.diff b/match.diff new file mode 100644 index 0000000..7663ad5 --- /dev/null +++ b/match.diff @@ -0,0 +1,12 @@ +diff -r 5b4101d67bb7 trytond/model/match.py +--- a/trytond/trytond/model/match.py Mon Oct 15 22:49:51 2018 +0200 ++++ b/trytond/trytond/model/match.py Sat Nov 03 18:21:44 2018 +0100 +@@ -10,6 +10,8 @@ + and matching value as value''' + for field, pattern_value in pattern.iteritems(): + value = getattr(self, field) ++ if self._fields[field]._type in ('char', 'text') and value == "": ++ value = None + if not match_none and value is None: + continue + if self._fields[field]._type == 'many2one': diff --git a/purchase_request.diff b/purchase_request.diff new file mode 100644 index 0000000..47e6309 --- /dev/null +++ b/purchase_request.diff @@ -0,0 +1,12 @@ +diff -r a4d9a0d5ca24 purchase_request.py +--- a/trytond/trytond/modules/purchase_request/purchase_request.py Mon May 21 20:13:25 2018 +0200 ++++ b/trytond/trytond/modules/purchase_request/purchase_request.py Tue Jul 24 15:56:01 2018 +0200 +@@ -276,6 +276,8 @@ + + supplier = None + today = Date.today() ++ if not date: ++ date = today + for product_supplier in product.product_suppliers: + supply_date = product_supplier.compute_supply_date(date=today) + timedelta = date - supply_date diff --git a/sale_number_of_packages.diff b/sale_number_of_packages.diff new file mode 100644 index 0000000..c04ebd4 --- /dev/null +++ b/sale_number_of_packages.diff @@ -0,0 +1,32 @@ +diff -r 8eadb6e76468 trytond/trytond/modules/sale_number_of_packages/stock.py +--- a/trytond/trytond/modules/sale_number_of_packages/stock.py Mon Dec 03 16:38:23 2018 +0100 ++++ b/trytond/trytond/modules/sale_number_of_packages/stock.py Wed Dec 12 14:45:49 2018 +0100 +@@ -179,7 +179,8 @@ + + @classmethod + def compute_quantities_query(cls, location_ids, with_childs=False, +- grouping=('product',), grouping_filter=None): ++ grouping=('product',), grouping_filter=None, ++ quantity_field='internal_quantity'): + pool = Pool() + Lot = pool.get('stock.lot') + lot = Lot.__table__() +@@ -187,7 +188,8 @@ + if not Transaction().context.get('normalized_number_of_packages'): + return super(Move, cls).compute_quantities_query( + location_ids, with_childs=with_childs, grouping=grouping, +- grouping_filter=grouping_filter) ++ grouping_filter=grouping_filter, ++ quantity_field=quantity_field) + + new_grouping = grouping[:] + new_grouping_filter = (grouping_filter[:] if grouping_filter != None +@@ -199,7 +201,8 @@ + + query = super(Move, cls).compute_quantities_query( + location_ids, with_childs=with_childs, grouping=new_grouping, +- grouping_filter=new_grouping_filter) ++ grouping_filter=new_grouping_filter, ++ quantity_field=quantity_field) + if not query: + return query diff --git a/search_warehouse.diff b/search_warehouse.diff new file mode 100644 index 0000000..9765a54 --- /dev/null +++ b/search_warehouse.diff @@ -0,0 +1,40 @@ +diff -r 78ac887c5b7f location.py +--- a/trytond/trytond/modules/stock/location.py Tue Jun 12 16:16:43 2018 +0200 ++++ b/trytond/trytond/modules/stock/location.py Tue Jun 12 16:19:53 2018 +0200 +@@ -59,7 +59,7 @@ + "Flat Children", + help="Check to restrict to one level of children.") + warehouse = fields.Function(fields.Many2One('stock.location', 'Warehouse'), +- 'get_warehouse') ++ 'get_warehouse', searcher='search_warehouse') + input_location = fields.Many2One( + "stock.location", "Input", states={ + 'invisible': Eval('type') != 'warehouse', +@@ -195,6 +195,27 @@ + inactives.append(location) + cls.check_inactive(inactives) + ++ @classmethod ++ def search_warehouse(cls, name, clause): ++ warehouse_child_locations = cls.search([ ++ ('parent.type', '=', 'warehouse'), ++ ('type', '=', 'storage'), ++ ('parent', clause[1], clause[2]), ++ ]) ++ found_warehouse_ids = [] ++ storage_location_ids = [] ++ for location in warehouse_child_locations: ++ storage_location_ids.append(location.id) ++ found_warehouse_ids.append(location.parent.id) ++ warehouse_location_ids = [] ++ for location in cls.search([ ++ ('parent', 'child_of', storage_location_ids), ++ ]): ++ if (location.warehouse and location.warehouse.id in ++ found_warehouse_ids): ++ warehouse_location_ids.append(location.id) ++ return [('id', 'in', warehouse_location_ids)] ++ + def check_type_for_moves(self): + """ Check locations with moves have types compatible with moves. """ + invalid_move_types = ['warehouse', 'view'] diff --git a/series b/series index 6863b34..8cf2e55 100644 --- a/series +++ b/series @@ -1,2 +1,26 @@ -issue6253.diff # add invoice type criteria -lock_stock_move.diff # stock +babi_multiprocess.diff # [trytond] babi multiprocess +logging_jsonrpc_exeption.diff # [trytond] logging JSONRPC Exception +match.diff # [trytond] Control when tje filed is a Char o Text and the value is not none but it's an empty string +issue3932.diff # [account] rule account move and account move line by company +issue6253.diff # [account_invoice] add invoice type criteria +issue4506.diff # [account_invoice] Add credit invoices keyword from account.invoice +issue4030.diff # [analytic_account] Not selected root accounts in analytic account lines +purchase_request.diff # [purchase_request] as shippment_date it's not required we need to ensure operation could be done + +issue4482.diff # [stock] stock inventory misses company access rule +search_warehouse.diff #[stock] search function for warehouse. + +# TODO: improve_performance_on_try_assign.diff # [stock] change browse of product to get default_uom to pysql + +issue240_631.diff # [stock_lot] stock_by_locations get all locations with that lot. +issue10467.diff # stock_lot: add lot to grouping if lot it's required on product + +issue53451002_1_10001.diff # [stock] Allow configuring which quantity is grouped in compute_quantities_query() needed by stock_number_of_packages +sale_number_of_packages.diff # [sale_number_of_packages] Allow configuring which quantity is grouped in compute_quantities_query() needed by stock_number_of_packages +stock_external_party.diff # [stock_external_party] Allow configuring which quantity is grouped in compute_quantities_query() needed by stock_number_of_packages +stock_lot_deactivatable.diff # [stock_lot_deactivatable] Allow configuring which quantity is grouped in compute_quantities_query() needed by stock_number_of_packages +stock_lot_sled.diff # [stock_lot_sled] Allow configuring which quantity is grouped in compute_quantities_query() needed by stock_number_of_packages + +issue7826.diff # [stock_package] Total packages moves are all +lock_stock_move.diff # [stock] Function to overwrite if lock table or not +issue7856.diff # [stock] Can't move qty from a parent location to child location diff --git a/stock_external_party.diff b/stock_external_party.diff new file mode 100644 index 0000000..27bdc8f --- /dev/null +++ b/stock_external_party.diff @@ -0,0 +1,22 @@ +diff -r f7f8e7da9dd8 trytond/trytond/modules/stock_external_party/stock.py +--- a/trytond/trytond/modules/stock_external_party/stock.py Tue Dec 04 13:36:33 2018 +0100 ++++ b/trytond/trytond/modules/stock_external_party/stock.py Wed Dec 05 16:24:09 2018 +0100 +@@ -155,7 +155,8 @@ + + @classmethod + def compute_quantities_query(cls, location_ids, with_childs=False, +- grouping=('product',), grouping_filter=None): ++ grouping=('product',), grouping_filter=None, ++ quantity_field='internal_quantity'): + context = Transaction().context + + new_grouping = grouping[:] +@@ -168,7 +169,7 @@ + + query = super(Move, cls).compute_quantities_query( + location_ids, with_childs=with_childs, grouping=new_grouping, +- grouping_filter=new_grouping_filter) ++ grouping_filter=new_grouping_filter, quantity_field=quantity_field) + return query + + @classmethod diff --git a/stock_lot_deactivatable.diff b/stock_lot_deactivatable.diff new file mode 100644 index 0000000..d66ed34 --- /dev/null +++ b/stock_lot_deactivatable.diff @@ -0,0 +1,20 @@ +diff -r c8f4cfc59666 trytond/trytond/modules/stock_lot_deactivatable/stock.py +--- a/trytond/trytond/modules/stock_lot_deactivatable/stock.py Wed Dec 12 15:46:19 2018 +0100 ++++ b/trytond/trytond/modules/stock_lot_deactivatable/stock.py Wed Dec 12 15:50:28 2018 +0100 +@@ -82,13 +82,14 @@ + + @classmethod + def compute_quantities_query(cls, location_ids, with_childs=False, +- grouping=('product',), grouping_filter=None): ++ grouping=('product',), grouping_filter=None, ++ quantity_field='internal_quantity'): + pool = Pool() + Lot = pool.get('stock.lot') + Period = pool.get('stock.period') + query = super(Move, cls).compute_quantities_query( + location_ids, with_childs=with_childs, grouping=grouping, +- grouping_filter=grouping_filter) ++ grouping_filter=grouping_filter, quantity_field=quantity_field) + + if not query or 'lot' not in grouping: + return query diff --git a/stock_lot_sled.diff b/stock_lot_sled.diff new file mode 100644 index 0000000..cc9ff0e --- /dev/null +++ b/stock_lot_sled.diff @@ -0,0 +1,39 @@ +diff -r fb7f3b05e343 stock.py +--- a/trytond/trytond/modules/stock_lot_sled/stock.py Mon Apr 23 17:44:40 2018 +0200 ++++ b/trytond/trytond/modules/stock_lot_sled/stock.py Tue Nov 27 11:21:59 2018 +0100 +@@ -229,7 +229,8 @@ + + @classmethod + def compute_quantities_query(cls, location_ids, with_childs=False, +- grouping=('product',), grouping_filter=None): ++ grouping=('product',), grouping_filter=None, ++ quantity_field='internal_quantity'): + pool = Pool() + Date = pool.get('ir.date') + Lot = pool.get('stock.lot') +@@ -237,7 +238,24 @@ + + query = super(Move, cls).compute_quantities_query( + location_ids, with_childs=with_childs, grouping=grouping, +- grouping_filter=grouping_filter) ++ grouping_filter=grouping_filter, quantity_field=quantity_field) ++ ++ ++ return query ++ ++ # We avoid this part of code, and pass responsability to user to ++ # remove expired products from stock locations. ++ # This code had several problems and add inconsitence what you get ++ # in client and what you get in code ++ # In client you get all stock ++ # In code you get all stock without quanities expired ++ # Code tries to remove all quantities from expired products but ++ # introduces some issues on stock_supply procedure. ++ # - he substract all quantities from beginning to start_day, ++ # every day of planning ++ # - Even If you do not configure expired quantity, has anormal ++ # results in stock. ++ + + context = Transaction().context + today = Date.today()