From 6e286c100f6fa3b3c44659bfa7b94a377aa51515 Mon Sep 17 00:00:00 2001 From: Raimon Esteve Date: Mon, 30 May 2016 17:10:04 +0200 Subject: [PATCH] Remove patches from default branch Force to change branch before to apply patches --- 024726_account_bank_remove_company.diff | 11 - ...6_account_payment_type_remove_company.diff | 121 -- ..._5155_5456_optimize_move_write_assign.diff | 115 -- README | 8 + account_chart_speedup.diff | 1150 ----------------- account_move_line_rule.diff | 19 - analytic_account.diff | 240 ---- analytic_invoice.diff | 48 - analytic_purchase.diff | 37 - analytic_sale.diff | 45 - babi_multiprocess.diff | 24 - do_not_lock_on_assign_try.diff | 12 - domain_field.diff | 65 - ...unding_in_sync_inventory_to_outgoing.patch | 49 - fix_wizard_copy.diff | 21 - incremental_wait_in_retries.diff | 15 - invoice_speedup.diff | 500 ------- issue10091002_1.diff | 66 - issue10391004_1.diff | 14 - issue10467.diff | 23 - issue130_392_10919.diff | 34 - issue13181002_1.diff | 70 - issue13891002_20001.diff | 29 - issue15211002-sale-confirmed-to-done.diff | 12 - issue154_316.diff | 37 - issue16661002_1.diff | 38 - issue17881002_1.diff | 71 - issue18481003_1.diff | 29 - issue18801002_1.diff | 38 - issue23901002_1.diff | 75 -- issue239_630.diff | 31 - issue240_631.diff | 304 ----- issue4950_sale.diff | 115 -- issue4950_stock.diff | 81 -- issue4986.diff | 19 - issue5118.diff | 27 - issue6021003_1.diff | 148 --- issue6341003_1.diff | 22 - issue9231002_20001.diff | 29 - ...voices_in_creit_note_action_by_domain.diff | 22 - multicompany_cron.diff | 13 - purchase_fix_get_move_done_rounding.diff | 12 - sao_nantic_theme.diff | 147 --- series | 45 - ...x_pick_product_without_outgoing_moves.diff | 12 - ...ot_improve_sync_inventory_to_outgoing.diff | 28 - ...ly_production-performance-improvement.diff | 31 - tax_active_invisible.diff | 20 - top.diff | 132 -- 49 files changed, 8 insertions(+), 4246 deletions(-) delete mode 100644 024726_account_bank_remove_company.diff delete mode 100644 024726_account_payment_type_remove_company.diff delete mode 100644 025476_5154_5155_5456_optimize_move_write_assign.diff create mode 100644 README delete mode 100644 account_chart_speedup.diff delete mode 100644 account_move_line_rule.diff delete mode 100644 analytic_account.diff delete mode 100644 analytic_invoice.diff delete mode 100644 analytic_purchase.diff delete mode 100644 analytic_sale.diff delete mode 100644 babi_multiprocess.diff delete mode 100644 do_not_lock_on_assign_try.diff delete mode 100644 domain_field.diff delete mode 100644 fix_rounding_in_sync_inventory_to_outgoing.patch delete mode 100644 fix_wizard_copy.diff delete mode 100644 incremental_wait_in_retries.diff delete mode 100644 invoice_speedup.diff delete mode 100644 issue10091002_1.diff delete mode 100644 issue10391004_1.diff delete mode 100644 issue10467.diff delete mode 100644 issue130_392_10919.diff delete mode 100644 issue13181002_1.diff delete mode 100644 issue13891002_20001.diff delete mode 100644 issue15211002-sale-confirmed-to-done.diff delete mode 100644 issue154_316.diff delete mode 100644 issue16661002_1.diff delete mode 100644 issue17881002_1.diff delete mode 100644 issue18481003_1.diff delete mode 100644 issue18801002_1.diff delete mode 100644 issue23901002_1.diff delete mode 100644 issue239_630.diff delete mode 100644 issue240_631.diff delete mode 100644 issue4950_sale.diff delete mode 100644 issue4950_stock.diff delete mode 100644 issue4986.diff delete mode 100644 issue5118.diff delete mode 100644 issue6021003_1.diff delete mode 100644 issue6341003_1.diff delete mode 100644 issue9231002_20001.diff delete mode 100644 limit_invoices_in_creit_note_action_by_domain.diff delete mode 100644 multicompany_cron.diff delete mode 100644 purchase_fix_get_move_done_rounding.diff delete mode 100644 sao_nantic_theme.diff delete mode 100644 series delete mode 100644 stock_lot_fix_pick_product_without_outgoing_moves.diff delete mode 100644 stock_lot_improve_sync_inventory_to_outgoing.diff delete mode 100644 stock_supply_production-performance-improvement.diff delete mode 100644 tax_active_invisible.diff delete mode 100644 top.diff diff --git a/024726_account_bank_remove_company.diff b/024726_account_bank_remove_company.diff deleted file mode 100644 index 6717d73..0000000 --- a/024726_account_bank_remove_company.diff +++ /dev/null @@ -1,11 +0,0 @@ -diff --git a/view/account_payment_type_form_view.xml b/view/account_payment_type_form_view.xml ---- a/trytond/trytond/modules/account_bank/view/account_payment_type_form_view.xml -+++ b/trytond/trytond/modules/account_bank/view/account_payment_type_form_view.xml -@@ -1,6 +1,6 @@ - - -- -+ - - -diff --git a/payment_type.py b/payment_type.py ---- a/trytond/trytond/modules/account_payment_type/payment_type.py -+++ b/trytond/trytond/modules/account_payment_type/payment_type.py -@@ -1,11 +1,10 @@ - # This file is part of account_payment_type module for Tryton. - # The COPYRIGHT file at the top level of this repository contains - # the full copyright notices and license terms. -- - from trytond.model import ModelView, ModelSQL, fields --from trytond.pyson import Eval, If - from trytond.pool import Pool - from trytond.transaction import Transaction -+from trytond import backend - - __all__ = ['PaymentType'] - -@@ -17,11 +16,6 @@ - name = fields.Char('Name', required=True, translate=True) - code = fields.Char('Code') - active = fields.Boolean('Active') -- company = fields.Many2One('company.company', 'Company', required=True, -- select=True, readonly=True, domain=[ -- ('id', If(Eval('context', {}).contains('company'), '=', '!='), -- Eval('context', {}).get('company', 0)), -- ]) - note = fields.Text('Description', translate=True, - help=('Description of the payment type that will be shown in ' - 'descriptions')) -@@ -32,6 +26,17 @@ - help='The kind of payment type.') - - @classmethod -+ def __register__(cls, module_name): -+ TableHandler = backend.get('TableHandler') -+ cursor = Transaction().cursor -+ table = TableHandler(cursor, cls, module_name) -+ -+ super(PaymentType, cls).__register__(module_name) -+ -+ # Migration from 3.4: drop required on company -+ table.not_null_action('company', action='remove') -+ -+ @classmethod - def __setup__(cls): - super(PaymentType, cls).__setup__() - cls._check_modify_fields = set(['kind']) -@@ -49,10 +54,6 @@ - def default_active(): - return True - -- @staticmethod -- def default_company(): -- return Transaction().context.get('company') -- - def get_rec_name(self, name): - if self.code: - return '[' + self.code + '] ' + self.name diff --git a/025476_5154_5155_5456_optimize_move_write_assign.diff b/025476_5154_5155_5456_optimize_move_write_assign.diff deleted file mode 100644 index f337999..0000000 --- a/025476_5154_5155_5456_optimize_move_write_assign.diff +++ /dev/null @@ -1,115 +0,0 @@ -diff -r 5d7c2958b920 move.py ---- a/trytond/trytond/modules/stock/move.py Mon Nov 23 17:59:15 2015 +0100 -+++ b/trytond/trytond/modules/stock/move.py Mon Nov 23 18:09:01 2015 +0100 -@@ -607,9 +607,15 @@ - @Workflow.transition('assigned') - def assign(cls, moves): - cls.check_origin(moves) -+ -+ to_write = [] - for move in moves: - move.set_effective_date() -- move.save() -+ to_write.extend(([move], { -+ 'effective_date': move.effective_date, -+ 'state': 'assigned' -+ })) -+ cls.write(*to_write) - - @classmethod - @ModelView.button -@@ -661,7 +667,12 @@ - - @classmethod - def write(cls, *args): -+ pool = Pool() -+ Product = pool.get('product.product') -+ Uom = pool.get('product.uom') -+ - actions = iter(args) -+ args = [] - for moves, values in zip(actions, actions): - vals_set = set(values) - if cls._deny_modify_assigned & vals_set: -@@ -673,6 +684,27 @@ - if move.state in ('done', 'cancel'): - cls.raise_user_error('modify_done_cancel', - (move.rec_name,)) -+ if set(['quantity', 'uom', 'product']) & vals_set: -+ int_qty2moves = {} -+ for move in moves: -+ uom = values.get('uom', move.uom) -+ if not isinstance(uom, Uom): -+ uom = Uom(uom) -+ product = values.get('product', move.product) -+ if not isinstance(product, Uom): -+ product = Product(product) -+ internal_quantity = cls._get_internal_quantity( -+ values.get('quantity', move.quantity), -+ uom, -+ product) -+ int_qty2moves.setdefault( -+ internal_quantity, []).append(move) -+ for int_qty, int_qty_moves in int_qty2moves.iteritems(): -+ new_values = values.copy() -+ new_values['internal_quantity'] = int_qty -+ args.extend((int_qty_moves, new_values)) -+ else: -+ args.extend((moves, values)) - - super(Move, cls).write(*args) - -@@ -680,15 +712,6 @@ - for moves, values in zip(actions, actions): - if any(f not in cls._allow_modify_closed_period for f in values): - cls.check_period_closed(moves) -- for move in moves: -- internal_quantity = cls._get_internal_quantity(move.quantity, -- move.uom, move.product) -- if (internal_quantity != move.internal_quantity -- and internal_quantity -- != values.get('internal_quantity')): -- cls.write([move], { -- 'internal_quantity': internal_quantity, -- }) - - @classmethod - def delete(cls, moves): -diff -r 5d7c2958b920 shipment.py ---- a/trytond/trytond/modules/stock/shipment.py Mon Nov 23 17:59:15 2015 +0100 -+++ b/trytond/trytond/modules/stock/shipment.py Mon Nov 23 18:09:01 2015 +0100 -@@ -1225,18 +1225,26 @@ - Set planned date of moves for the shipments - ''' - Move = Pool().get('stock.move') -+ to_write = [] - for shipment in shipments: - outgoing_date, inventory_date = shipment._move_planned_date -- Move.write([x for x in shipment.outgoing_moves -+ out_moves_to_write = [x for x in shipment.outgoing_moves - if (x.state not in ('assigned', 'done', 'cancel') -- and x.planned_date != outgoing_date)], { -- 'planned_date': outgoing_date, -- }) -- Move.write([x for x in shipment.inventory_moves -+ and x.planned_date != outgoing_date)] -+ if out_moves_to_write: -+ to_write.extend((out_moves_to_write, { -+ 'planned_date': outgoing_date, -+ })) -+ -+ inv_moves_to_write = [x for x in shipment.inventory_moves - if (x.state not in ('assigned', 'done', 'cancel') -- and x.planned_date != inventory_date)], { -- 'planned_date': inventory_date, -- }) -+ and x.planned_date != inventory_date)] -+ if inv_moves_to_write: -+ to_write.extend((inv_moves_to_write, { -+ 'planned_date': inventory_date, -+ })) -+ if to_write: -+ Move.write(*to_write) - - @classmethod - def create(cls, vlist): diff --git a/README b/README new file mode 100644 index 0000000..76a1199 --- /dev/null +++ b/README @@ -0,0 +1,8 @@ +NaN-TIC patches +=============== + +Change to branch patches before to apply patch: + +* v4.0 +* v3.8 +* ... diff --git a/account_chart_speedup.diff b/account_chart_speedup.diff deleted file mode 100644 index 24eb8e1..0000000 --- a/account_chart_speedup.diff +++ /dev/null @@ -1,1150 +0,0 @@ - -# HG changeset patch -# User Cédric Krier -# Date 1458600296 -3600 -# Node ID 532fd5a46527a0c2f5b96f062b34f5bda18e88b5 -# Parent 6d37f343013df686a8875aaa7b234ddedcdf05ff -Improve create/update chart of accounts - -We create in one call all the records of the same tree level and we update all -the record in one call. -Side effect, as there is no more recursion, the depth of the chart can be -higher than the maximum depth of the Python interpreter stack. - -issue5400 -review23991002 - -diff -r 6d37f343013d -r 532fd5a46527 trytond/trytond/modules/account/account.py ---- a/trytond/trytond/modules/account/account.py Sun Mar 20 22:58:02 2016 +0100 -+++ b/trytond/trytond/modules/account/account.py Mon Mar 21 23:44:56 2016 +0100 -@@ -115,35 +115,42 @@ - res['template'] = self.id - return res - -- def create_type(self, company_id, template2type=None, parent_id=None): -+ def create_type(self, company_id, template2type=None): - ''' - Create recursively types based on template. - template2type is a dictionary with template id as key and type id as - value, used to convert template id into type. The dictionary is filled - with new types. -- Return the id of the type created - ''' - pool = Pool() - Type = pool.get('account.account.type') -+ assert self.parent is None - - if template2type is None: - template2type = {} - -- if self.id not in template2type: -- vals = self._get_type_value() -- vals['company'] = company_id -- vals['parent'] = parent_id -+ def create(templates): -+ values = [] -+ created = [] -+ for template in templates: -+ if template.id not in template2type: -+ vals = template._get_type_value() -+ vals['company'] = company_id -+ if template.parent: -+ vals['parent'] = template2type[template.parent.id] -+ else: -+ vals['parent'] = None -+ values.append(vals) -+ created.append(template) - -- new_type, = Type.create([vals]) -+ types = Type.create(values) -+ for template, type_ in zip(created, types): -+ template2type[template.id] = type_.id - -- template2type[self.id] = new_type.id -- new_id = template2type[self.id] -- -- new_childs = [] -- for child in self.childs: -- new_childs.append(child.create_type(company_id, -- template2type=template2type, parent_id=new_id)) -- return new_id -+ childs = [self] -+ while childs: -+ create(childs) -+ childs = sum((c.childs for c in childs), ()) - - - class Type(ModelSQL, ModelView): -@@ -269,19 +276,22 @@ - value, used to convert template id into type. The dictionary is filled - with new types - ''' -- - if template2type is None: - template2type = {} - -- if self.template: -- vals = self.template._get_type_value(type=self) -- if vals: -- self.write([self], vals) -- -- template2type[self.template.id] = self.id -- -- for child in self.childs: -- child.update_type(template2type=template2type) -+ values = [] -+ childs = [self] -+ while childs: -+ for child in childs: -+ if child.template: -+ vals = child.template._get_type_value(type=child) -+ if vals: -+ values.append([child]) -+ values.append(vals) -+ template2type[child.template.id] = child.id -+ childs = sum((c.childs for c in childs), ()) -+ if values: -+ self.write(*values) - - - class OpenType(Wizard): -@@ -419,7 +429,7 @@ - return res - - def create_account(self, company_id, template2account=None, -- template2type=None, parent_id=None): -+ template2type=None): - ''' - Create recursively accounts based on template. - template2account is a dictionary with template id as key and account id -@@ -427,10 +437,10 @@ - filled with new accounts - template2type is a dictionary with type template id as key and type id - as value, used to convert type template id into type. -- Return the id of the account created - ''' - pool = Pool() - Account = pool.get('account.account') -+ assert self.parent is None - - if template2account is None: - template2account = {} -@@ -438,24 +448,32 @@ - if template2type is None: - template2type = {} - -- if self.id not in template2account: -- vals = self._get_account_value() -- vals['company'] = company_id -- vals['parent'] = parent_id -- vals['type'] = (template2type.get(self.type.id) if self.type -- else None) -+ def create(templates): -+ values = [] -+ created = [] -+ for template in templates: -+ if template.id not in template2account: -+ vals = template._get_account_value() -+ vals['company'] = company_id -+ if template.parent: -+ vals['parent'] = template2account[template.parent.id] -+ else: -+ vals['parent'] = None -+ if template.type: -+ vals['type'] = template2type.get(template.type.id) -+ else: -+ vals['type'] = None -+ values.append(vals) -+ created.append(template) - -- new_account, = Account.create([vals]) -+ accounts = Account.create(values) -+ for template, account in zip(created, accounts): -+ template2account[template.id] = account.id - -- template2account[self.id] = new_account.id -- new_id = template2account[self.id] -- -- new_childs = [] -- for child in self.childs: -- new_childs.append(child.create_account(company_id, -- template2account=template2account, template2type=template2type, -- parent_id=new_id)) -- return new_id -+ childs = [self] -+ while childs: -+ create(childs) -+ childs = sum((c.childs for c in childs), ()) - - def update_account_taxes(self, template2account, template2tax, - template_done=None): -@@ -477,17 +495,25 @@ - if template_done is None: - template_done = [] - -- if self.id not in template_done: -- if self.taxes: -- Account.write([Account(template2account[self.id])], { -- 'taxes': [ -- ('add', [template2tax[x.id] for x in self.taxes])], -- }) -- template_done.append(self.id) -+ def update(templates): -+ to_write = [] -+ for template in templates: -+ if template.id not in template_done: -+ if template.taxes: -+ tax_ids = [template2tax[x.id] for x in template.taxes] -+ to_write.append([Account(template2account[template.id])]) -+ to_write.append({ -+ 'taxes': [ -+ ('add', tax_ids)], -+ }) -+ template_done.append(template.id) -+ if to_write: -+ Account.write(to_write) - -- for child in self.childs: -- child.update_account_taxes(template2account, template2tax, -- template_done=template_done) -+ childs = [self] -+ while childs: -+ update(childs) -+ childs = sum((c.childs for c in childs), ()) - - - class Account(ModelSQL, ModelView): -@@ -846,28 +872,33 @@ - template2type is a dictionary with type template id as key and type id - as value, used to convert type template id into type. - ''' -- - if template2account is None: - template2account = {} - - if template2type is None: - template2type = {} - -- if self.template: -- vals = self.template._get_account_value(account=self) -- current_type = self.type.id if self.type else None -- template_type = (template2type.get(self.template.type.id) -- if self.template.type else None) -- if current_type != template_type: -- vals['type'] = template_type -- if vals: -- self.write([self], vals) -- -- template2account[self.template.id] = self.id -- -- for child in self.childs: -- child.update_account(template2account=template2account, -- template2type=template2type) -+ values = [] -+ childs = [self] -+ while childs: -+ for child in childs: -+ if child.template: -+ vals = child.template._get_account_value(account=child) -+ current_type = child.type.id if child.type else None -+ if child.template.type: -+ template_type = template2type.get( -+ child.template.type.id) -+ else: -+ template_type = None -+ if current_type != template_type: -+ vals['type'] = template_type -+ if vals: -+ values.append([child]) -+ values.append(vals) -+ template2account[child.template.id] = child.id -+ childs = sum((c.childs for c in childs), ()) -+ if values: -+ self.write(*values) - - def update_account_taxes(self, template2account, template2tax): - ''' -@@ -883,23 +914,30 @@ - if template2tax is None: - template2tax = {} - -- if self.template: -- if self.template.taxes: -- tax_ids = [template2tax[x.id] for x in self.template.taxes -- if x.id in template2tax] -- old_tax_ids = [x.id for x in self.taxes] -+ values = [] -+ childs = [self] -+ while childs: -+ for child in childs: -+ if not child.template: -+ continue -+ if not child.template.taxes: -+ continue -+ tax_ids = [template2tax[x.id] for x in child.template.taxes -+ if x.id in template2tax] -+ old_tax_ids = [x.id for x in child.taxes] - for tax_id in tax_ids: - if tax_id not in old_tax_ids: -- self.write([self], { -- 'taxes': [ -+ values.append([child]) -+ values.append({ -+ 'taxes': [ - ('add', template2tax[x.id]) - for x in self.template.taxes - if x.id in template2tax], - }) - break -- -- for child in self.childs: -- child.update_account_taxes(template2account, template2tax) -+ childs = sum((c.childs for c in childs), ()) -+ if values: -+ self.write(*values) - - - class AccountDeferral(ModelSQL, ModelView): -@@ -1685,38 +1723,34 @@ - with Transaction().set_context(language=Config.get_language(), - company=self.account.company.id): - account_template = self.account.account_template -+ company = self.account.company - - # Create account types - template2type = {} -- account_template.type.create_type(self.account.company.id, -+ account_template.type.create_type( -+ company.id, - template2type=template2type) - - # Create accounts - template2account = {} -- account_template.create_account(self.account.company.id, -- template2account=template2account, template2type=template2type) -+ account_template.create_account( -+ company.id, -+ template2account=template2account, -+ template2type=template2type) - - # Create tax codes - template2tax_code = {} -- tax_code_templates = TaxCodeTemplate.search([ -- ('account', '=', account_template.id), -- ('parent', '=', None), -- ]) -- for tax_code_template in tax_code_templates: -- tax_code_template.create_tax_code(self.account.company.id, -- template2tax_code=template2tax_code) -+ TaxCodeTemplate.create_tax_code( -+ account_template.id, company.id, -+ template2tax_code=template2tax_code) - - # Create taxes - template2tax = {} -- tax_templates = TaxTemplate.search([ -- ('account', '=', account_template.id), -- ('parent', '=', None), -- ]) -- for tax_template in tax_templates: -- tax_template.create_tax(self.account.company.id, -- template2tax_code=template2tax_code, -- template2account=template2account, -- template2tax=template2tax) -+ TaxTemplate.create_tax( -+ account_template.id, company.id, -+ template2tax_code=template2tax_code, -+ template2account=template2account, -+ template2tax=template2tax) - - # Update taxes on accounts - account_template.update_account_taxes(template2account, -@@ -1724,21 +1758,15 @@ - - # Create tax rules - template2rule = {} -- tax_rule_templates = TaxRuleTemplate.search([ -- ('account', '=', account_template.id), -- ]) -- for tax_rule_template in tax_rule_templates: -- tax_rule_template.create_rule(self.account.company.id, -- template2rule=template2rule) -+ TaxRuleTemplate.create_rule( -+ account_template.id, company.id, -+ template2rule=template2rule) - - # Create tax rule lines - template2rule_line = {} -- tax_rule_line_templates = TaxRuleLineTemplate.search([ -- ('rule.account', '=', account_template.id), -- ]) -- for tax_rule_line_template in tax_rule_line_templates: -- tax_rule_line_template.create_rule_line(template2tax, -- template2rule, template2rule_line=template2rule_line) -+ TaxRuleLineTemplate.create_rule_line( -+ account_template.id, template2tax, template2rule, -+ template2rule_line=template2rule_line) - return 'properties' - - def default_properties(self, fields): -@@ -1829,13 +1857,15 @@ - pool.get('account.tax.rule.line.template') - - account = self.start.account -+ company = account.company - - # Update account types - template2type = {} - account.type.update_type(template2type=template2type) - # Create missing account types - if account.type.template: -- account.type.template.create_type(account.company.id, -+ account.type.template.create_type( -+ company.id, - template2type=template2type) - - # Update accounts -@@ -1844,82 +1874,57 @@ - template2type=template2type) - # Create missing accounts - if account.template: -- account.template.create_account(account.company.id, -- template2account=template2account, template2type=template2type) -+ account.template.create_account( -+ company.id, -+ template2account=template2account, -+ template2type=template2type) - - # Update tax codes - template2tax_code = {} -- tax_codes = TaxCode.search([ -- ('company', '=', account.company.id), -- ('parent', '=', None), -- ]) -- for tax_code in tax_codes: -- tax_code.update_tax_code(template2tax_code=template2tax_code) -+ TaxCode.update_tax_code( -+ company.id, -+ template2tax_code=template2tax_code) - # Create missing tax codes - if account.template: -- tax_code_templates = TaxCodeTemplate.search([ -- ('account', '=', account.template.id), -- ('parent', '=', None), -- ]) -- for tax_code_template in tax_code_templates: -- tax_code_template.create_tax_code(account.company.id, -- template2tax_code=template2tax_code) -+ TaxCodeTemplate.create_tax_code( -+ account.template.id, company.id, -+ template2tax_code=template2tax_code) - - # Update taxes - template2tax = {} -- taxes = Tax.search([ -- ('company', '=', account.company.id), -- ('parent', '=', None), -- ]) -- for tax in taxes: -- tax.update_tax(template2tax_code=template2tax_code, -- template2account=template2account, -- template2tax=template2tax) -+ Tax.update_tax( -+ company.id, -+ template2tax_code=template2tax_code, -+ template2account=template2account, -+ template2tax=template2tax) - # Create missing taxes - if account.template: -- tax_templates = TaxTemplate.search([ -- ('account', '=', account.template.id), -- ('parent', '=', None), -- ]) -- for tax_template in tax_templates: -- tax_template.create_tax(account.company.id, -- template2tax_code=template2tax_code, -- template2account=template2account, -- template2tax=template2tax) -+ TaxTemplate.create_tax( -+ account.template.id, account.company.id, -+ template2tax_code=template2tax_code, -+ template2account=template2account, -+ template2tax=template2tax) - - # Update taxes on accounts - account.update_account_taxes(template2account, template2tax) - - # Update tax rules - template2rule = {} -- tax_rules = TaxRule.search([ -- ('company', '=', account.company.id), -- ]) -- for tax_rule in tax_rules: -- tax_rule.update_rule(template2rule=template2rule) -+ TaxRule.update_rule(company.id, template2rule=template2rule) - # Create missing tax rules - if account.template: -- tax_rule_templates = TaxRuleTemplate.search([ -- ('account', '=', account.template.id), -- ]) -- for tax_rule_template in tax_rule_templates: -- tax_rule_template.create_rule(account.company.id, -- template2rule=template2rule) -+ TaxRuleTemplate.create_rule( -+ account.template.id, account.company.id, -+ template2rule=template2rule) - - # Update tax rule lines - template2rule_line = {} -- tax_rule_lines = TaxRuleLine.search([ -- ('rule.company', '=', account.company.id), -- ]) -- for tax_rule_line in tax_rule_lines: -- tax_rule_line.update_rule_line(template2tax, template2rule, -- template2rule_line=template2rule_line) -+ TaxRuleLine.update_rule_line( -+ company.id, template2tax, template2rule, -+ template2rule_line=template2rule_line) - # Create missing tax rule lines - if account.template: -- tax_rule_line_templates = TaxRuleLineTemplate.search([ -- ('rule.account', '=', account.template.id), -- ]) -- for tax_rule_line_template in tax_rule_line_templates: -- tax_rule_line_template.create_rule_line(template2tax, -- template2rule, template2rule_line=template2rule_line) -+ TaxRuleLineTemplate.create_rule_line( -+ account.template.id, template2tax, template2rule, -+ template2rule_line=template2rule_line) - return 'succeed' -diff -r 6d37f343013d -r 532fd5a46527 trytond/trytond/modules/account/tax.py ---- a/trytond/trytond/modules/account/tax.py Sun Mar 20 22:58:02 2016 +0100 -+++ b/trytond/trytond/modules/account/tax.py Mon Mar 21 23:44:56 2016 +0100 -@@ -88,14 +88,13 @@ - res['template'] = self.id - return res - -- def create_tax_code(self, company_id, template2tax_code=None, -- parent_id=None): -+ @classmethod -+ def create_tax_code(cls, account_id, company_id, template2tax_code=None): - ''' - Create recursively tax codes based on template. - template2tax_code is a dictionary with tax code template id as key and - tax code id as value, used to convert template id into tax code. The - dictionary is filled with new tax codes. -- Return the id of the tax code created - ''' - pool = Pool() - TaxCode = pool.get('account.tax.code') -@@ -103,24 +102,31 @@ - if template2tax_code is None: - template2tax_code = {} - -- if self.id not in template2tax_code: -- vals = self._get_tax_code_value() -- vals['company'] = company_id -- vals['parent'] = parent_id -+ def create(templates): -+ values = [] -+ created = [] -+ for template in templates: -+ if template.id not in template2tax_code: -+ vals = template._get_tax_code_value() -+ vals['company'] = company_id -+ if template.parent: -+ vals['parent'] = template2tax_code[template.parent.id] -+ else: -+ vals['parent'] = None -+ values.append(vals) -+ created.append(template) - -- new_tax_code, = TaxCode.create([vals]) -+ tax_codes = TaxCode.create(values) -+ for template, tax_code in zip(created, tax_codes): -+ template2tax_code[template.id] = tax_code.id - -- prev_data = {} -- for field_name, field in self._fields.iteritems(): -- prev_data[field_name] = getattr(self, field_name) -- template2tax_code[self.id] = new_tax_code.id -- new_id = template2tax_code[self.id] -- -- new_childs = [] -- for child in self.childs: -- new_childs.append(child.create_tax_code(company_id, -- template2tax_code=template2tax_code, parent_id=new_id)) -- return new_id -+ childs = cls.search([ -+ ('account', '=', account_id), -+ ('parent', '=', None), -+ ]) -+ while childs: -+ create(childs) -+ childs = sum((c.childs for c in childs), ()) - - - class TaxCode(ModelSQL, ModelView): -@@ -232,25 +238,33 @@ - ]) - super(TaxCode, cls).delete(codes) - -- def update_tax_code(self, template2tax_code=None): -+ @classmethod -+ def update_tax_code(cls, company_id, template2tax_code=None): - ''' - Update recursively tax code based on template. - template2tax_code is a dictionary with tax code template id as key and - tax code id as value, used to convert template id into tax code. The - dictionary is filled with new tax codes - ''' -- - if template2tax_code is None: - template2tax_code = {} - -- if self.template: -- vals = self.template._get_tax_code_value(code=self) -- if vals: -- self.write([self], vals) -- template2tax_code[self.template.id] = self.id -- -- for child in self.childs: -- child.update_tax_code(template2tax_code=template2tax_code) -+ values = [] -+ childs = cls.search([ -+ ('company', '=', company_id), -+ ('parent', '=', None), -+ ]) -+ while childs: -+ for child in childs: -+ if child.template: -+ vals = child.template._get_tax_code_value(code=child) -+ if vals: -+ values.append([child]) -+ values.append(vals) -+ template2tax_code[child.template.id] = child.id -+ childs = sum((c.childs for c in childs), ()) -+ if values: -+ cls.write(*values) - - - class OpenChartTaxCodeStart(ModelView): -@@ -454,8 +468,9 @@ - res['template'] = self.id - return res - -- def create_tax(self, company_id, template2tax_code, template2account, -- template2tax=None, parent_id=None): -+ @classmethod -+ def create_tax(cls, account_id, company_id, template2tax_code, -+ template2account, template2tax=None): - ''' - Create recursively taxes based on template. - -@@ -467,7 +482,6 @@ - template2tax is a dictionary with tax template id as key and tax id as - value, used to convert template id into tax. The dictionary is filled - with new taxes. -- Return id of the tax created - ''' - pool = Pool() - Tax = pool.get('account.tax') -@@ -475,52 +489,63 @@ - if template2tax is None: - template2tax = {} - -- if self.id not in template2tax: -- vals = self._get_tax_value() -- vals['company'] = company_id -- vals['parent'] = parent_id -- if self.invoice_account: -- vals['invoice_account'] = \ -- template2account[self.invoice_account.id] -- else: -- vals['invoice_account'] = None -- if self.credit_note_account: -- vals['credit_note_account'] = \ -- template2account[self.credit_note_account.id] -- else: -- vals['credit_note_account'] = None -- if self.invoice_base_code: -- vals['invoice_base_code'] = \ -- template2tax_code[self.invoice_base_code.id] -- else: -- vals['invoice_base_code'] = None -- if self.invoice_tax_code: -- vals['invoice_tax_code'] = \ -- template2tax_code[self.invoice_tax_code.id] -- else: -- vals['invoice_tax_code'] = None -- if self.credit_note_base_code: -- vals['credit_note_base_code'] = \ -- template2tax_code[self.credit_note_base_code.id] -- else: -- vals['credit_note_base_code'] = None -- if self.credit_note_tax_code: -- vals['credit_note_tax_code'] = \ -- template2tax_code[self.credit_note_tax_code.id] -- else: -- vals['credit_note_tax_code'] = None -+ def create(templates): -+ values = [] -+ created = [] -+ for template in templates: -+ if template.id not in template2tax: -+ vals = template._get_tax_value() -+ vals['company'] = company_id -+ if template.parent: -+ vals['parent'] = template2tax[template.parent.id] -+ else: -+ vals['parent'] = None -+ if template.invoice_account: -+ vals['invoice_account'] = \ -+ template2account[template.invoice_account.id] -+ else: -+ vals['invoice_account'] = None -+ if template.credit_note_account: -+ vals['credit_note_account'] = \ -+ template2account[template.credit_note_account.id] -+ else: -+ vals['credit_note_account'] = None -+ if template.invoice_base_code: -+ vals['invoice_base_code'] = \ -+ template2tax_code[template.invoice_base_code.id] -+ else: -+ vals['invoice_base_code'] = None -+ if template.invoice_tax_code: -+ vals['invoice_tax_code'] = \ -+ template2tax_code[template.invoice_tax_code.id] -+ else: -+ vals['invoice_tax_code'] = None -+ if template.credit_note_base_code: -+ vals['credit_note_base_code'] = \ -+ template2tax_code[ -+ template.credit_note_base_code.id] -+ else: -+ vals['credit_note_base_code'] = None -+ if template.credit_note_tax_code: -+ vals['credit_note_tax_code'] = \ -+ template2tax_code[template.credit_note_tax_code.id] -+ else: -+ vals['credit_note_tax_code'] = None - -- new_tax, = Tax.create([vals]) -+ values.append(vals) -+ created.append(template) - -- template2tax[self.id] = new_tax.id -- new_id = template2tax[self.id] -+ taxes = Tax.create(values) -+ for template, tax in zip(created, taxes): -+ template2tax[template.id] = tax.id - -- new_childs = [] -- for child in self.childs: -- new_childs.append(child.create_tax(company_id, template2tax_code, -- template2account, template2tax=template2tax, -- parent_id=new_id)) -- return new_id -+ childs = cls.search([ -+ ('account', '=', account_id), -+ ('parent', '=', None), -+ ]) -+ while childs: -+ create(childs) -+ childs = sum((c.childs for c in childs), ()) - - - class Tax(ModelSQL, ModelView): -@@ -869,7 +894,8 @@ - taxes = cls.sort_taxes(taxes) - return cls._reverse_unit_compute(price_unit, taxes, date) - -- def update_tax(self, template2tax_code, template2account, -+ @classmethod -+ def update_tax(cls, company_id, template2tax_code, template2account, - template2tax=None): - ''' - Update recursively taxes based on template. -@@ -882,81 +908,88 @@ - value, used to convert template id into tax. The dictionary is filled - with new taxes. - ''' -- - if template2tax is None: - template2tax = {} - -- if self.template: -- vals = self.template._get_tax_value(tax=self) -- invoice_account_id = (self.invoice_account.id -- if self.invoice_account else None) -- if (self.template.invoice_account and -- invoice_account_id != template2account.get( -- self.template.invoice_account.id)): -- vals['invoice_account'] = template2account.get( -- self.template.invoice_account.id) -- elif (not self.template.invoice_account -- and self.invoice_account): -- vals['invoice_account'] = None -- credit_note_account_id = (self.credit_note_account.id -- if self.credit_note_account else None) -- if (self.template.credit_note_account and -- credit_note_account_id != template2account.get( -- self.template.credit_note_account.id)): -- vals['credit_note_account'] = template2account.get( -- self.template.credit_note_account.id) -- elif (not self.template.credit_note_account -- and self.credit_note_account): -- vals['credit_note_account'] = None -- invoice_base_code_id = (self.invoice_base_code.id -- if self.invoice_base_code else None) -- if (self.template.invoice_base_code and -- invoice_base_code_id != template2tax_code.get( -- self.template.invoice_base_code.id)): -- vals['invoice_base_code'] = template2tax_code.get( -- self.template.invoice_base_code.id) -- elif (not self.template.invoice_base_code -- and self.invoice_base_code): -- vals['invoice_base_code'] = None -- invoice_tax_code_id = (self.invoice_tax_code.id -- if self.invoice_tax_code else None) -- if (self.template.invoice_tax_code -- and invoice_tax_code_id != template2tax_code.get( -- self.template.invoice_tax_code.id)): -- vals['invoice_tax_code'] = template2tax_code.get( -- self.template.invoice_tax_code.id) -- elif (not self.template.invoice_tax_code -- and self.invoice_tax_code): -- vals['invoice_tax_code'] = None -- credit_note_base_code_id = (self.credit_note_base_code.id -- if self.credit_note_base_code else None) -- if (self.template.credit_note_base_code -- and credit_note_base_code_id != template2tax_code.get( -- self.template.credit_note_base_code.id)): -- vals['credit_note_base_code'] = template2tax_code.get( -- self.template.credit_note_base_code.id) -- elif (not self.template.credit_note_base_code -- and self.credit_note_base_code): -- vals['credit_note_base_code'] = None -- credit_note_tax_code_id = (self.credit_note_tax_code.id -- if self.credit_note_tax_code else None) -- if (self.template.credit_note_tax_code -- and credit_note_tax_code_id != template2tax_code.get( -- self.template.credit_note_tax_code.id)): -- vals['credit_note_tax_code'] = template2tax_code.get( -- self.template.credit_note_tax_code.id) -- elif (not self.template.credit_note_tax_code -- and self.credit_note_tax_code): -- vals['credit_note_tax_code'] = None -+ values = [] -+ childs = cls.search([ -+ ('company', '=', company_id), -+ ('parent', '=', None), -+ ]) -+ while childs: -+ for child in childs: -+ if child.template: -+ vals = child.template._get_tax_value(tax=child) -+ invoice_account_id = (child.invoice_account.id -+ if child.invoice_account else None) -+ if (child.template.invoice_account and -+ invoice_account_id != template2account.get( -+ child.template.invoice_account.id)): -+ vals['invoice_account'] = template2account.get( -+ child.template.invoice_account.id) -+ elif (not child.template.invoice_account -+ and child.invoice_account): -+ vals['invoice_account'] = None -+ credit_note_account_id = (child.credit_note_account.id -+ if child.credit_note_account else None) -+ if (child.template.credit_note_account and -+ credit_note_account_id != template2account.get( -+ child.template.credit_note_account.id)): -+ vals['credit_note_account'] = template2account.get( -+ child.template.credit_note_account.id) -+ elif (not child.template.credit_note_account -+ and child.credit_note_account): -+ vals['credit_note_account'] = None -+ invoice_base_code_id = (child.invoice_base_code.id -+ if child.invoice_base_code else None) -+ if (child.template.invoice_base_code and -+ invoice_base_code_id != template2tax_code.get( -+ child.template.invoice_base_code.id)): -+ vals['invoice_base_code'] = template2tax_code.get( -+ child.template.invoice_base_code.id) -+ elif (not child.template.invoice_base_code -+ and child.invoice_base_code): -+ vals['invoice_base_code'] = None -+ invoice_tax_code_id = (child.invoice_tax_code.id -+ if child.invoice_tax_code else None) -+ if (child.template.invoice_tax_code -+ and invoice_tax_code_id != template2tax_code.get( -+ child.template.invoice_tax_code.id)): -+ vals['invoice_tax_code'] = template2tax_code.get( -+ child.template.invoice_tax_code.id) -+ elif (not child.template.invoice_tax_code -+ and child.invoice_tax_code): -+ vals['invoice_tax_code'] = None -+ credit_note_base_code_id = (child.credit_note_base_code.id -+ if child.credit_note_base_code else None) -+ if (child.template.credit_note_base_code -+ and (credit_note_base_code_id -+ != template2tax_code.get( -+ child.template.credit_note_base_code.id))): -+ vals['credit_note_base_code'] = template2tax_code.get( -+ child.template.credit_note_base_code.id) -+ elif (not child.template.credit_note_base_code -+ and child.credit_note_base_code): -+ vals['credit_note_base_code'] = None -+ credit_note_tax_code_id = (child.credit_note_tax_code.id -+ if child.credit_note_tax_code else None) -+ if (child.template.credit_note_tax_code -+ and (credit_note_tax_code_id -+ != template2tax_code.get( -+ child.template.credit_note_tax_code.id))): -+ vals['credit_note_tax_code'] = template2tax_code.get( -+ child.template.credit_note_tax_code.id) -+ elif (not child.template.credit_note_tax_code -+ and child.credit_note_tax_code): -+ vals['credit_note_tax_code'] = None - -- if vals: -- self.write([self], vals) -- -- template2tax[self.template.id] = self.id -- -- for child in self.childs: -- child.update_tax(template2tax_code, template2account, -- template2tax=template2tax) -+ if vals: -+ values.append([child]) -+ values.append(vals) -+ template2tax[child.template.id] = child.id -+ childs = sum((c.childs for c in childs), ()) -+ if values: -+ cls.write(*values) - - - class _TaxKey(dict): -@@ -1132,13 +1165,13 @@ - res['template'] = self.id - return res - -- def create_rule(self, company_id, template2rule=None): -+ @classmethod -+ def create_rule(cls, account_id, company_id, template2rule=None): - ''' - Create tax rule based on template. - template2rule is a dictionary with tax rule template id as key and tax - rule id as value, used to convert template id into tax rule. The - dictionary is filled with new tax rules. -- Return id of the tax rule created - ''' - pool = Pool() - Rule = pool.get('account.tax.rule') -@@ -1146,13 +1179,22 @@ - if template2rule is None: - template2rule = {} - -- if self.id not in template2rule: -- vals = self._get_tax_rule_value() -- vals['company'] = company_id -- new_rule, = Rule.create([vals]) -+ templates = cls.search([ -+ ('account', '=', account_id), -+ ]) - -- template2rule[self.id] = new_rule.id -- return template2rule[self.id] -+ values = [] -+ created = [] -+ for template in templates: -+ if template.id not in template2rule: -+ vals = template._get_tax_rule_value() -+ vals['company'] = company_id -+ values.append(vals) -+ created.append(template) -+ -+ rules = Rule.create(values) -+ for template, rule in zip(created, rules): -+ template2rule[template.id] = rule.id - - - class TaxRule(ModelSQL, ModelView): -@@ -1192,23 +1234,30 @@ - return line.get_taxes() - return tax and [tax.id] or None - -- def update_rule(self, template2rule=None): -+ @classmethod -+ def update_rule(cls, company_id, template2rule=None): - ''' - Update tax rule based on template. - template2rule is a dictionary with tax rule template id as key and tax - rule id as value, used to convert template id into tax rule. The - dictionary is filled with new tax rules. - ''' -- - if template2rule is None: - template2rule = {} - -- if self.template: -- vals = self.template._get_tax_rule_value(rule=self) -- if vals: -- self.write([self], vals) -- -- template2rule[self.template.id] = self.id -+ values = [] -+ rules = cls.search([ -+ ('company', '=', company_id), -+ ]) -+ for rule in rules: -+ if rule.template: -+ vals = rule.template._get_tax_rule_value(rule=rule) -+ if vals: -+ values.append([rule]) -+ values.append(vals) -+ template2rule[rule.template.id] = rule.id -+ if values: -+ cls.write(*values) - - - class TaxRuleLineTemplate(ModelSQL, ModelView): -@@ -1288,7 +1337,8 @@ - res['template'] = self.id - return res - -- def create_rule_line(self, template2tax, template2rule, -+ @classmethod -+ def create_rule_line(cls, account_id, template2tax, template2rule, - template2rule_line=None): - ''' - Create tax rule line based on template. -@@ -1299,27 +1349,36 @@ - template2rule_line is a dictionary with tax rule line template id as - key and tax rule line id as value, used to convert template id into tax - rule line. The dictionary is filled with new tax rule lines. -- Return id of the tax rule line created - ''' - RuleLine = Pool().get('account.tax.rule.line') - - if template2rule_line is None: - template2rule_line = {} - -- if self.id not in template2rule_line: -- vals = self._get_tax_rule_line_value() -- vals['rule'] = template2rule[self.rule.id] -- if self.origin_tax: -- vals['origin_tax'] = template2tax[self.origin_tax.id] -- else: -- vals['origin_tax'] = None -- if self.tax: -- vals['tax'] = template2tax[self.tax.id] -- else: -- vals['tax'] = None -- new_rule_line, = RuleLine.create([vals]) -- template2rule_line[self.id] = new_rule_line.id -- return template2rule_line[self.id] -+ templates = cls.search([ -+ ('rule.account', '=', account_id), -+ ]) -+ -+ values = [] -+ created = [] -+ for template in templates: -+ if template.id not in template2rule_line: -+ vals = template._get_tax_rule_line_value() -+ vals['rule'] = template2rule[template.rule.id] -+ if template.origin_tax: -+ vals['origin_tax'] = template2tax[template.origin_tax.id] -+ else: -+ vals['origin_tax'] = None -+ if template.tax: -+ vals['tax'] = template2tax[template.tax.id] -+ else: -+ vals['tax'] = None -+ values.append(vals) -+ created.append(template) -+ -+ rule_lines = RuleLine.create(values) -+ for template, rule_line in zip(created, rule_lines): -+ template2rule_line[template.id] = rule_line.id - - - class TaxRuleLine(ModelSQL, ModelView, MatchMixin): -@@ -1402,7 +1461,8 @@ - return [self.tax.id] - return None - -- def update_rule_line(self, template2tax, template2rule, -+ @classmethod -+ def update_rule_line(cls, company_id, template2tax, template2rule, - template2rule_line=None): - ''' - Update tax rule line based on template. -@@ -1417,31 +1477,40 @@ - if template2rule_line is None: - template2rule_line = {} - -- if self.template: -- vals = self.template._get_tax_rule_line_value(rule_line=self) -- if self.rule.id != template2rule[self.template.rule.id]: -- vals['rule'] = template2rule[self.template.rule.id] -- if self.origin_tax: -- if self.template.origin_tax: -- if (self.origin_tax.id != -- template2tax[self.template.origin_tax.id]): -- vals['origin_tax'] = template2tax[ -- self.template.origin_tax.id] -- else: -- vals['origin_tax'] = None -- elif self.template.origin_tax: -- vals['origin_tax'] = template2tax[self.template.origin_tax.id] -- if self.tax: -- if self.template.tax: -- if self.tax.id != template2tax[self.template.tax.id]: -- vals['tax'] = template2tax[self.template.tax.id] -- else: -- vals['tax'] = None -- elif self.template.tax: -- vals['tax'] = template2tax[self.template.tax.id] -- if vals: -- self.write([self], vals) -- template2rule_line[self.template.id] = self.id -+ values = [] -+ lines = cls.search([ -+ ('rule.company', '=', company_id), -+ ]) -+ for line in lines: -+ if line.template: -+ vals = line.template._get_tax_rule_line_value(rule_line=line) -+ if line.rule.id != template2rule[line.template.rule.id]: -+ vals['rule'] = template2rule[line.template.rule.id] -+ if line.origin_tax: -+ if line.template.origin_tax: -+ if (line.origin_tax.id != -+ template2tax[line.template.origin_tax.id]): -+ vals['origin_tax'] = template2tax[ -+ line.template.origin_tax.id] -+ else: -+ vals['origin_tax'] = None -+ elif line.template.origin_tax: -+ vals['origin_tax'] = template2tax[ -+ line.template.origin_tax.id] -+ if line.tax: -+ if line.template.tax: -+ if line.tax.id != template2tax[line.template.tax.id]: -+ vals['tax'] = template2tax[line.template.tax.id] -+ else: -+ vals['tax'] = None -+ elif line.template.tax: -+ vals['tax'] = template2tax[line.template.tax.id] -+ if vals: -+ values.append([line]) -+ values.append(vals) -+ template2rule_line[line.template.id] = line.id -+ if values: -+ cls.write(*values) - - - class OpenTaxCode(Wizard): diff --git a/account_move_line_rule.diff b/account_move_line_rule.diff deleted file mode 100644 index 7f29cad..0000000 --- a/account_move_line_rule.diff +++ /dev/null @@ -1,19 +0,0 @@ -diff -r 32ceadcd01cd move.xml ---- a/trytond/trytond/modules/account/move.xml Mon Feb 02 18:44:16 2015 +0100 -+++ b/trytond/trytond/modules/account/move.xml Thu Apr 02 10:58:14 2015 +0200 -@@ -259,6 +259,15 @@ - - - -+ -+ -+ -+ -+ -+ -+ -+ -+ - - account.move.reconcile_lines.writeoff - form diff --git a/analytic_account.diff b/analytic_account.diff deleted file mode 100644 index 1a7dd0b..0000000 --- a/analytic_account.diff +++ /dev/null @@ -1,240 +0,0 @@ -# HG changeset patch -# User Sergi Almacellas Abellana -Add company domain - - -issue5104 - -review19141003 - -Index: trytond/trytond/modules/analytic_account/account.py -=================================================================== - -diff -r 0cd556f1c82c account.py ---- a/trytond/trytond/modules/analytic_account/account.py Sun Mar 13 16:19:22 2016 +0100 -+++ b/trytond/trytond/modules/analytic_account/account.py Tue Apr 26 18:24:04 2016 +0200 -@@ -8,7 +8,7 @@ - from trytond import backend - from trytond.model import ModelView, ModelSQL, fields, Unique - from trytond.wizard import Wizard, StateView, StateAction, Button --from trytond.pyson import Eval, PYSONEncoder -+from trytond.pyson import Eval, If, PYSONEncoder, PYSONDecoder - from trytond.transaction import Transaction - from trytond.pool import Pool - -@@ -22,7 +22,7 @@ - name = fields.Char('Name', required=True, translate=True, select=True) - code = fields.Char('Code', select=True) - active = fields.Boolean('Active', select=True) -- company = fields.Many2One('company.company', 'Company') -+ company = fields.Many2One('company.company', 'Company', required=True) - currency = fields.Many2One('currency.currency', 'Currency', required=True) - currency_digits = fields.Function(fields.Integer('Currency Digits'), - 'on_change_with_currency_digits') -@@ -33,6 +33,7 @@ - ], 'Type', required=True) - root = fields.Many2One('analytic_account.account', 'Root', select=True, - domain=[ -+ ('company', '=', Eval('company')), - ('parent', '=', None), - ('type', '=', 'root'), - ], -@@ -40,7 +41,7 @@ - 'invisible': Eval('type') == 'root', - 'required': Eval('type') != 'root', - }, -- depends=['type']) -+ depends=['company', 'type']) - parent = fields.Many2One('analytic_account.account', 'Parent', select=True, - domain=[('parent', 'child_of', Eval('root'))], - states={ -@@ -311,19 +312,26 @@ - __name__ = 'analytic.account.entry' - origin = fields.Reference('Origin', selection='get_origin', select=True) - root = fields.Many2One('analytic_account.account', 'Root Analytic', -- domain=[('type', '=', 'root')]) -+ domain=[ -+ ('company', '=', Eval('company')), -+ ('type', '=', 'root'), -+ ], -+ depends=['company']) - account = fields.Many2One('analytic_account.account', 'Account', - ondelete='RESTRICT', - states={ - 'required': Eval('required', False), - }, - domain=[ -+ ('company', '=', Eval('company')), - ('root', '=', Eval('root')), - ('type', '=', 'normal'), - ], -- depends=['root', 'required']) -+ depends=['root', 'required', 'company']) - required = fields.Function(fields.Boolean('Required'), - 'on_change_with_required') -+ company = fields.Function(fields.Many2One('company.company', 'Company'), -+ 'on_change_with_company', searcher='search_company') - - @classmethod - def __register__(cls, module_name): -@@ -386,12 +394,27 @@ - return self.root.mandatory - return False - -+ @classmethod -+ def default_company(cls): -+ return Transaction().context.get('company') -+ -+ def on_change_with_company(self, name=None): -+ return Transaction().context.get('company') -+ -+ @classmethod -+ def search_company(cls, name, clause): -+ raise NotImplementedError() -+ - - class AnalyticMixin(ModelSQL): - - analytic_accounts = fields.One2Many('analytic.account.entry', 'origin', - 'Analytic Accounts', - size=Eval('analytic_accounts_size', 0), -+ domain=[ -+ ('company', If(Eval('context', {}).contains('company'), '=', '!='), -+ Eval('context', {}).get('company', -1)), -+ ], - depends=['analytic_accounts_size']) - analytic_accounts_size = fields.Function(fields.Integer( - 'Analytic Accounts Size'), 'get_analytic_accounts_size') -@@ -427,13 +450,19 @@ - where=entry.selection == selection_id)) - handler.drop_column('analytic_accounts') - -- @staticmethod -- def default_analytic_accounts(): -+ @classmethod -+ def analytic_accounts_domain(cls): -+ return PYSONDecoder(Transaction().context).decode( -+ PYSONEncoder().encode(cls.analytic_accounts.domain)) -+ -+ @classmethod -+ def default_analytic_accounts(cls): - pool = Pool() - AnalyticAccount = pool.get('analytic_account.account') - - accounts = [] -- root_accounts = AnalyticAccount.search([ -+ root_accounts = AnalyticAccount.search( -+ cls.analytic_accounts_domain() + [ - ('parent', '=', None), - ]) - for account in root_accounts: -@@ -443,11 +472,14 @@ - }) - return accounts - -- @staticmethod -- def default_analytic_accounts_size(): -+ @classmethod -+ def default_analytic_accounts_size(cls): - pool = Pool() - AnalyticAccount = pool.get('analytic_account.account') -- return len(AnalyticAccount.search([('type', '=', 'root')])) -+ return len(AnalyticAccount.search( -+ cls.analytic_accounts_domain() + [ -+ ('type', '=', 'root'), -+ ])) - - @classmethod - def get_analytic_accounts_size(cls, records, name): -@@ -464,12 +496,17 @@ - "Check that all mandatory root entries are defined in entries" - pool = Pool() - Account = pool.get('analytic_account.account') -- mandatory_roots = {a for a in Account.search([ -+ all_mandatory_roots = {a for a in Account.search([ - ('type', '=', 'root'), - ('mandatory', '=', True), - ])} - for analytic in analytics: - analytic_roots = {e.root for e in analytic.analytic_accounts} -+ companies = {e.company for e in analytic.analytic_accounts} -+ mandatory_roots = set() -+ for mandatory in all_mandatory_roots: -+ if mandatory.company in companies: -+ mandatory_roots.add(mandatory) - if not mandatory_roots <= analytic_roots: - cls.raise_user_error('root_account', { - 'name': analytic.rec_name, -diff -r 0cd556f1c82c account.xml ---- a/trytond/trytond/modules/analytic_account/account.xml Sun Mar 13 16:19:22 2016 +0100 -+++ b/trytond/trytond/modules/analytic_account/account.xml Tue Apr 26 18:24:04 2016 +0200 -@@ -124,5 +124,27 @@ - tree - analytic_account_entry_tree - -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ - - -diff -r 0cd556f1c82c line.py ---- a/trytond/trytond/modules/analytic_account/line.py Sun Mar 13 16:19:22 2016 +0100 -+++ b/trytond/trytond/modules/analytic_account/line.py Tue Apr 26 18:24:04 2016 +0200 -@@ -24,7 +24,7 @@ - currency_digits = fields.Function(fields.Integer('Currency Digits'), - 'on_change_with_currency_digits') - company = fields.Function(fields.Many2One('company.company', 'Company'), -- 'on_change_with_company') -+ 'on_change_with_company', searcher='search_company') - account = fields.Many2One('analytic_account.account', 'Account', - required=True, select=True, domain=[ - ('type', '!=', 'view'), -@@ -104,6 +104,10 @@ - if self.move_line: - return self.move_line.account.company.id - -+ @classmethod -+ def search_company(cls, name, clause): -+ return [('move_line.account.company',) + tuple(clause[1:])] -+ - @staticmethod - def query_get(table): - ''' -diff -r 0cd556f1c82c line.xml ---- a/trytond/trytond/modules/analytic_account/line.xml Sun Mar 13 16:19:22 2016 +0100 -+++ b/trytond/trytond/modules/analytic_account/line.xml Tue Apr 26 18:24:04 2016 +0200 -@@ -67,5 +67,15 @@ - move_line_form - - -+ -+ -+ -+ -+ -+ -+ -+ - - diff --git a/analytic_invoice.diff b/analytic_invoice.diff deleted file mode 100644 index 61b04af..0000000 --- a/analytic_invoice.diff +++ /dev/null @@ -1,48 +0,0 @@ -# HG changeset patch -# User Sergi Almacellas Abellana -Add company domain on analytic entries - - -issue5104 - - -review24081002 - -Index: trytond/trytond/modules/analytic_invoice/invoice.py -=================================================================== - ---- a/trytond/trytond/modules/analytic_invoice/invoice.py -+++ b/trytond/trytond/modules/analytic_invoice/invoice.py -@@ -1,5 +1,6 @@ - # This file is part of Tryton. The COPYRIGHT file at the top level of - # this repository contains the full copyright notices and license terms. -+from trytond.model import fields - from trytond.pool import PoolMeta, Pool - - from trytond.modules.analytic_account import AnalyticMixin -@@ -61,3 +62,24 @@ - def _get_origin(cls): - origins = super(AnalyticAccountEntry, cls)._get_origin() - return origins + ['account.invoice.line'] -+ -+ @fields.depends('origin') -+ def on_change_with_company(self, name=None): -+ pool = Pool() -+ InvoiceLine = pool.get('account.invoice.line') -+ company = super(AnalyticAccountEntry, self).on_change_with_company( -+ name) -+ if isinstance(self.origin, InvoiceLine): -+ if self.origin.invoice: -+ return self.origin.invoice.company.id -+ elif self.origin.company: -+ return self.origin.company.id -+ return company -+ -+ @classmethod -+ def search_company(cls, name, clause): -+ return ['OR', -+ [('origin.company',) + tuple(clause[1:]) + -+ tuple(('account.invoice.line',))], -+ [('origin.invoice.company',) + tuple(clause[1:]) + -+ tuple(('account.invoice.line',))]] - diff --git a/analytic_purchase.diff b/analytic_purchase.diff deleted file mode 100644 index ec55380..0000000 --- a/analytic_purchase.diff +++ /dev/null @@ -1,37 +0,0 @@ -# HG changeset patch -# User Sergi Almacellas Abellana -Add company domain on analytic entries - -issue5104 - -review17201002 - -Index: trytond/trytond/modules/analytic_purchase/purchase.py -=================================================================== - ---- a/trytond/trytond/modules/analytic_purchase/purchase.py -+++ b/trytond/trytond/modules/analytic_purchase/purchase.py -@@ -79,3 +79,22 @@ - and self.origin.purchase.state in ['cancel', 'draft']): - return False - return required -+ -+ @fields.depends('origin') -+ def on_change_with_company(self, name=None): -+ pool = Pool() -+ PurchaseLine = pool.get('purchase.line') -+ company = super(AnalyticAccountEntry, self).on_change_with_company( -+ name) -+ if isinstance(self.origin, PurchaseLine): -+ if self.origin.purchase: -+ return self.origin.purchase.company.id -+ return company -+ -+ @classmethod -+ def search_company(cls, name, clause): -+ domain = super(AnalyticAccountEntry, cls).search_company(name, clause) -+ return ['OR', -+ domain, -+ [('origin.purchase.company',) + tuple(clause[1:]) + -+ tuple(('purchase.line',))]] - diff --git a/analytic_sale.diff b/analytic_sale.diff deleted file mode 100644 index 07cbb2d..0000000 --- a/analytic_sale.diff +++ /dev/null @@ -1,45 +0,0 @@ -# HG changeset patch -# User Sergi Almacellas Abellana -Add company domain on analytic entries - - -issue5104 - -review17991002 - -Index: trytond/trytond/modules/analytic_sale/sale.py -=================================================================== - ---- a/trytond/trytond/modules/analytic_sale/sale.py -+++ b/trytond/trytond/modules/analytic_sale/sale.py -@@ -1,5 +1,6 @@ - # This file is part of Tryton. The COPYRIGHT file at the top level of - # this repository contains the full copyright notices and license terms. -+from trytond.model import fields - from trytond.pool import Pool, PoolMeta - - from trytond.modules.analytic_account import AnalyticMixin -@@ -32,3 +33,22 @@ - def _get_origin(cls): - origins = super(AnalyticAccountEntry, cls)._get_origin() - return origins + ['sale.line'] -+ -+ @fields.depends('origin') -+ def on_change_with_company(self, name=None): -+ pool = Pool() -+ SaleLine = pool.get('sale.line') -+ company = super(AnalyticAccountEntry, self).on_change_with_company( -+ name) -+ if isinstance(self.origin, SaleLine): -+ if self.origin.sale: -+ return self.origin.sale.company.id -+ return company -+ -+ @classmethod -+ def search_company(cls, name, clause): -+ domain = super(AnalyticAccountEntry, cls).search_company(name, clause) -+ return ['OR', -+ domain, -+ [('origin.sale.company',) + tuple(clause[1:]) + -+ tuple(('sale.line',))]] - diff --git a/babi_multiprocess.diff b/babi_multiprocess.diff deleted file mode 100644 index d391160..0000000 --- a/babi_multiprocess.diff +++ /dev/null @@ -1,24 +0,0 @@ -diff -r 75c44f5a88e0 trytond/trytond/protocols/dispatcher.py ---- a/trytond/trytond/protocols/dispatcher.py Mon Jul 20 09:50:24 2015 +0200 -+++ b/trytond/trytond/protocols/dispatcher.py Mon Jul 20 10:21:09 2015 +0200 -@@ -157,7 +157,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 diff --git a/do_not_lock_on_assign_try.diff b/do_not_lock_on_assign_try.diff deleted file mode 100644 index 6c3594f..0000000 --- a/do_not_lock_on_assign_try.diff +++ /dev/null @@ -1,12 +0,0 @@ -diff -r a87800ef903a move.py ---- a/trytond/trytond/modules/stock/move.py Fri Nov 27 12:13:17 2015 +0100 -+++ b/trytond/trytond/modules/stock/move.py Fri Nov 27 12:13:55 2015 +0100 -@@ -775,7 +775,7 @@ - Date = pool.get('ir.date') - Location = pool.get('stock.location') - -- Transaction().cursor.lock(cls._table) -+ # Transaction().cursor.lock(cls._table) - - if with_childs: - locations = Location.search([ diff --git a/domain_field.diff b/domain_field.diff deleted file mode 100644 index d822011..0000000 --- a/domain_field.diff +++ /dev/null @@ -1,65 +0,0 @@ -diff -r 1a22411f9264 trytond/trytond/model/fields/many2many.py ---- a/trytond/trytond/model/fields/many2many.py Thu Jul 16 01:13:45 2015 +0200 -+++ b/trytond/trytond/model/fields/many2many.py Mon Jul 20 14:20:18 2015 +0200 -@@ -287,6 +287,9 @@ - table, _ = tables[None] - name, operator, value = domain[:3] - assert operator not in {'where', 'not where'} or '.' not in name -+ method = getattr(Model, 'domain_%s' % name, None) -+ if method: -+ return method(domain, tables) - - if Relation._history and transaction.context.get('_datetime'): - relation = Relation.__table_history__() -diff -r 1a22411f9264 trytond/trytond/model/fields/many2one.py ---- a/trytond/trytond/model/fields/many2one.py Thu Jul 16 01:13:45 2015 +0200 -+++ b/trytond/trytond/model/fields/many2one.py Mon Jul 20 14:20:18 2015 +0200 -@@ -159,6 +159,9 @@ - - table, _ = tables[None] - name, operator, value = domain[:3] -+ method = getattr(Model, 'domain_%s' % name, None) -+ if method: -+ return method(domain, tables) - column = self.sql_column(table) - if '.' not in name: - if operator.endswith('child_of') or operator.endswith('parent_of'): -diff -r 1a22411f9264 trytond/trytond/model/fields/one2many.py ---- a/trytond/trytond/model/fields/one2many.py Thu Jul 16 01:13:45 2015 +0200 -+++ b/trytond/trytond/model/fields/one2many.py Mon Jul 20 14:20:18 2015 +0200 -@@ -232,6 +232,9 @@ - table, _ = tables[None] - name, operator, value = domain[:3] - assert operator not in {'where', 'not where'} or '.' not in name -+ method = getattr(Model, 'domain_%s' % name, None) -+ if method: -+ return method(domain, tables) - - if Target._history and transaction.context.get('_datetime'): - target = Target.__table_history__() -diff -r 1a22411f9264 trytond/trytond/model/fields/property.py ---- a/trytond/trytond/model/fields/property.py Thu Jul 16 01:13:45 2015 +0200 -+++ b/trytond/trytond/model/fields/property.py Mon Jul 20 14:20:18 2015 +0200 -@@ -72,6 +72,9 @@ - cursor = Transaction().connection.cursor() - - name, operator, value = domain -+ method = getattr(Model, 'domain_%s' % name, None) -+ if method: -+ return method(domain, tables) - - sql_type = self._field.sql_type().base - -diff -r 1a22411f9264 trytond/trytond/model/fields/reference.py ---- a/trytond/trytond/model/fields/reference.py Thu Jul 16 01:13:45 2015 +0200 -+++ b/trytond/trytond/model/fields/reference.py Mon Jul 20 14:20:18 2015 +0200 -@@ -124,6 +124,9 @@ - return super(Reference, self).convert_domain(domain, tables, Model) - pool = Pool() - name, operator, value, target = domain[:4] -+ method = getattr(Model, 'domain_%s' % name, None) -+ if method: -+ return method(domain, tables) - Target = pool.get(target) - table, _ = tables[None] - name, target_name = name.split('.', 1) diff --git a/fix_rounding_in_sync_inventory_to_outgoing.patch b/fix_rounding_in_sync_inventory_to_outgoing.patch deleted file mode 100644 index 783d48a..0000000 --- a/fix_rounding_in_sync_inventory_to_outgoing.patch +++ /dev/null @@ -1,49 +0,0 @@ -diff -r fdfe606e6b87 stock.py ---- a/trytond/trytond/modules/stock_lot/stock.py Thu Feb 19 00:04:21 2015 +0100 -+++ b/trytond/trytond/modules/stock_lot/stock.py Mon Oct 05 11:56:24 2015 +0200 -@@ -119,16 +119,19 @@ - round=False) - if quantity < out_quantity: - outgoing_moves.extend(Move.copy([out_move], default={ -- 'quantity': out_quantity - quantity, -+ 'quantity': Uom.round( -+ out_quantity - quantity, -+ out_move.uom.rounding), - })) - Move.write([out_move], { -- 'quantity': quantity, -+ 'quantity': Uom.round( -+ quantity, out_move.uom.rounding), - }) - Move.write([out_move], { - 'lot': move.lot.id, - }) - quantity -= out_quantity -- assert quantity <= 0 -+ assert quantity <= move.product.default_uom.rounding - - - class ShipmentOutReturn: -diff -r 519c1c1a1ca2 shipment.py ---- a/trytond/trytond/modules/stock/shipment.py Mon Oct 05 12:22:18 2015 +0200 -+++ b/trytond/trytond/modules/stock/shipment.py Mon Oct 05 12:23:46 2015 +0200 -@@ -1177,14 +1177,17 @@ - continue - key = cls._sync_inventory_to_outgoing_grouping_key(move, - 'outgoing') -- if outgoing_qty.get(key, 0.0) > 0.0: -+ if (outgoing_qty.get(key, 0.0) -+ > move.product.default_uom.rounding): - exc_qty = Uom.compute_qty(move.product.default_uom, - outgoing_qty[key], move.uom) - removed_qty = Uom.compute_qty(move.uom, - min(exc_qty, move.quantity), move.product.default_uom, - round=False) - Move.write([move], { -- 'quantity': max(0.0, move.quantity - exc_qty), -+ 'quantity': max(0.0, Uom.round( -+ move.quantity - exc_qty, -+ move.uom.rounding)), - }) - outgoing_qty[key] -= removed_qty - diff --git a/fix_wizard_copy.diff b/fix_wizard_copy.diff deleted file mode 100644 index a5dd4ab..0000000 --- a/fix_wizard_copy.diff +++ /dev/null @@ -1,21 +0,0 @@ -diff --git a/trytond/ir/action.py b/trytond/ir/action.py ---- a/trytond/trytond/ir/action.py -+++ b/trytond/trytond/ir/action.py -@@ -149,13 +149,13 @@ - def check_wizard_model(self): - ActionWizard = Pool().get('ir.action.wizard') - if self.action.type == 'ir.action.wizard': -- action_wizard, = ActionWizard.search([ -+ action_wizards = ActionWizard.search([ - ('action', '=', self.action.id), - ], limit=1) -- if action_wizard.model: -- if self.model.__name__ != action_wizard.model: -+ if action_wizards and action_wizards[0].model: -+ if self.model.__name__ != action_wizards[0].model: - self.raise_user_error('wrong_wizard_model', ( -- action_wizard.rec_name,)) -+ action_wizards[0].rec_name,)) - - @staticmethod - def _convert_vals(vals): diff --git a/incremental_wait_in_retries.diff b/incremental_wait_in_retries.diff deleted file mode 100644 index 65deaa3..0000000 --- a/incremental_wait_in_retries.diff +++ /dev/null @@ -1,15 +0,0 @@ -diff -r 1b91a9bc6db1 trytond/protocols/dispatcher.py ---- a/trytond/trytond/protocols/dispatcher.py Mon Nov 09 23:16:42 2015 +0100 -+++ b/trytond/trytond/protocols/dispatcher.py Wed Nov 25 08:55:40 2015 +0100 -@@ -172,6 +172,11 @@ - except DatabaseOperationalError: - transaction.cursor.rollback() - if count and not rpc.readonly: -+ retry = config.getint('database', 'retry') -+ waiting_time = min((retry - count) * (retry - count) * 0.1, -+ 4.0) -+ if waiting_time: -+ time.sleep(waiting_time) - continue - raise - except (NotLogged, ConcurrencyException, UserError, UserWarning): diff --git a/invoice_speedup.diff b/invoice_speedup.diff deleted file mode 100644 index a01c0ec..0000000 --- a/invoice_speedup.diff +++ /dev/null @@ -1,500 +0,0 @@ -diff -r 3681a54fda0a trytond/trytond/modules/account_invoice/invoice.py ---- a/trytond/trytond/modules/account_invoice/invoice.py Tue Jul 07 16:46:50 2015 +0200 -+++ b/trytond/trytond/modules/account_invoice/invoice.py Tue Jul 07 17:12:14 2015 +0200 -@@ -859,34 +859,35 @@ - ''' - Return move line - ''' -- Currency = Pool().get('currency.currency') -- res = {} -+ pool = Pool() -+ Currency = pool.get('currency.currency') -+ MoveLine = pool.get('account.move.line') -+ line = MoveLine() - if self.currency.id != self.company.currency.id: - with Transaction().set_context(date=self.currency_date): -- res['amount_second_currency'] = Currency.compute( -+ line.amount_second_currency = Currency.compute( - self.company.currency, amount, self.currency) -- res['second_currency'] = self.currency.id -+ line.amount_second_currency = -line.amount_second_currency -+ line.second_currency = self.currency.id - else: -- res['amount_second_currency'] = None -- res['second_currency'] = None -- if amount <= 0: -- res['debit'], res['credit'] = -amount, 0 -+ line.amount_second_currency = None -+ line.second_currency = None -+ if amount >= Decimal('0.0'): -+ line.debit = Decimal('0.0') -+ line.credit = amount - else: -- res['debit'], res['credit'] = 0, amount -- if res['amount_second_currency']: -- res['amount_second_currency'] = ( -- res['amount_second_currency'].copy_sign( -- res['debit'] - res['credit'])) -- res['account'] = self.account.id -+ line.debit = - amount -+ line.credit = Decimal('0.0') -+ line.account = self.account.id - if self.account.party_required: -- res['party'] = self.party.id -- res['maturity_date'] = date -- res['description'] = self.description -- return res -+ line.party = self.party.id -+ line.maturity_date = date -+ line.description = self.description -+ return line - -- def create_move(self): -+ def get_move(self): - ''' -- Create account move for the invoice and return the created move -+ Compute account move for the invoice and return the created move - ''' - pool = Pool() - Move = pool.get('account.move') -@@ -902,9 +903,9 @@ - total = Decimal('0.0') - total_currency = Decimal('0.0') - for line in move_lines: -- total += line['debit'] - line['credit'] -- if line['amount_second_currency']: -- total_currency += line['amount_second_currency'] -+ total += line.debit - line.credit -+ if line.amount_second_currency: -+ total_currency += line.amount_second_currency - - term_lines = self.payment_term.compute(total, self.company.currency, - self.invoice_date) -@@ -912,28 +913,23 @@ - if not term_lines: - term_lines = [(Date.today(), total)] - for date, amount in term_lines: -- val = self._get_move_line(date, amount) -- if val['amount_second_currency']: -- remainder_total_currency += val['amount_second_currency'] -- move_lines.append(val) -+ line = self._get_move_line(date, amount) -+ if line.amount_second_currency: -+ remainder_total_currency += line.amount_second_currency -+ move_lines.append(line) - if not self.currency.is_zero(remainder_total_currency): -- move_lines[-1]['amount_second_currency'] -= \ -+ move_lines[-1].amount_second_currency -= \ - remainder_total_currency -- - accounting_date = self.accounting_date or self.invoice_date - period_id = Period.find(self.company.id, date=accounting_date) - -- move, = Move.create([{ -- 'journal': self.journal.id, -- 'period': period_id, -- 'date': accounting_date, -- 'origin': str(self), -- 'company': self.company.id, -- 'lines': [('create', move_lines)], -- }]) -- self.write([self], { -- 'move': move.id, -- }) -+ move = Move() -+ move.journal = self.journal -+ move.period = period_id -+ move.date = accounting_date -+ move.origin = self -+ move.company = self.company -+ move.lines = move_lines - return move - - def set_number(self): -@@ -970,10 +966,9 @@ - with Transaction().set_context( - date=self.invoice_date or Date.today()): - number = Sequence.get_id(sequence.id) -- vals = {'number': number} -+ self.number = number - if not self.invoice_date and self.type == 'out': -- vals['invoice_date'] = Transaction().context['date'] -- self.write([self], vals) -+ self.invoice_date = Transaction().context['date'] - - @classmethod - def check_modify(cls, invoices): -@@ -987,9 +982,12 @@ - cls.raise_user_error('modify_invoice', (invoice.rec_name,)) - - def get_rec_name(self, name): -- return (self.number or unicode(self.id) -- + (self.reference and (' ' + self.reference) or '') -- + ' ' + self.party.rec_name) -+ name = self.number or unicode(self.id) -+ if self.reference: -+ name += ' %s' % self.reference -+ if self.party: -+ name += ' %s' % self.party.rec_name -+ return name - - @classmethod - def search_rec_name(cls, name, clause): -@@ -1033,7 +1031,7 @@ - all_invoices += invoices - update_tax = [i for i in all_invoices if i.state == 'draft'] - super(Invoice, cls).write(*args) -- if update_tax: -+ if update_tax and not Transaction().context.get('skip_update_taxes'): - cls.update_taxes(update_tax) - - @classmethod -@@ -1201,18 +1199,16 @@ - ''' - MoveLine = Pool().get('account.move.line') - -- new_invoices = [] -- for invoice in invoices: -- new_invoice, = cls.create([invoice._credit()]) -- new_invoices.append(new_invoice) -- if refund: -- cls.post([new_invoice]) -+ new_invoices = cls.create([i._credit() for i in invoices]) -+ cls.update_taxes(new_invoices) -+ if refund: -+ cls.post(new_invoices) -+ for invoice, new_invoice in itertools.izip(invoices, new_invoices): - if new_invoice.state == 'posted': - MoveLine.reconcile([l for l in invoice.lines_to_pay - if not l.reconciliation] + - [l for l in new_invoice.lines_to_pay - if not l.reconciliation]) -- cls.update_taxes(new_invoices) - return new_invoices - - @classmethod -@@ -1232,10 +1228,16 @@ - @ModelView.button - @Workflow.transition('validated') - def validate_invoice(cls, invoices): -+ to_write = [] - for invoice in invoices: - if invoice.type == 'in': - invoice.set_number() -- invoice.create_move() -+ move = invoice.get_move() -+ if move != invoice.move: -+ invoice.move = invoice.get_move() -+ to_write.extend(([invoice], invoice._save_values)) -+ if to_write: -+ cls.write(*to_write) - - @classmethod - @ModelView.button -@@ -1243,14 +1245,29 @@ - def post(cls, invoices): - Move = Pool().get('account.move') - -- moves = [] -+ to_create = [] - for invoice in invoices: - invoice.set_number() -- moves.append(invoice.create_move()) -- cls.write([i for i in invoices if i.state != 'posted'], { -- 'state': 'posted', -- }) -- Move.post([m for m in moves if m.state != 'posted']) -+ move = invoice.get_move() -+ if move != invoice.move: -+ to_create.append(move._save_values) -+ invoices2move = {} -+ if to_create: -+ moves = Move.create(to_create) -+ for move in moves: -+ invoices2move[move.origin.id] = move.id -+ to_write = [] -+ for invoice in invoices: -+ values = invoice._save_values -+ if invoice.id in invoices2move: -+ values['move'] = invoices2move[invoice.id] -+ if values: -+ to_write.extend(([invoice], values)) -+ if to_write: -+ with Transaction().set_context(skip_update_taxes=True): -+ cls.write(*to_write) -+ cls.write(invoices, {'state': 'posted'}) -+ Move.post([i.move for i in invoices if i.move.state != 'posted']) - for invoice in invoices: - if invoice.type == 'out': - invoice.print_invoice() -@@ -1289,14 +1306,17 @@ - - cancel_moves = [] - delete_moves = [] -+ to_write = [] - for invoice in invoices: - if invoice.move: - if invoice.move.state == 'draft': - delete_moves.append(invoice.move) - elif not invoice.cancel_move: - invoice.cancel_move = invoice.move.cancel() -- invoice.save() - cancel_moves.append(invoice.cancel_move) -+ to_write.extend(([invoice], invoice._save_values)) -+ if to_write: -+ cls.write(*to_write) - if delete_moves: - Move.delete(delete_moves) - if cancel_moves: -@@ -1852,6 +1872,7 @@ - def _compute_taxes(self): - pool = Pool() - Currency = pool.get('currency.currency') -+ TaxLine = pool.get('account.tax.line') - - res = [] - if self.type != 'line': -@@ -1869,53 +1890,55 @@ - date=self.invoice.currency_date): - amount = Currency.compute(self.invoice.currency, - amount, self.invoice.company.currency) -- res.append({ -- 'code': base_code, -- 'amount': amount, -- 'tax': tax['tax'], -- }) -+ tax_line = TaxLine() -+ tax_line.code = base_code -+ tax_line.amount = amount -+ tax_line.tax = tax['tax'] -+ res.append(tax_line) - return res - - def get_move_line(self): - ''' -- Return a list of move lines values for invoice line -+ Return a list of move lines instances for invoice line - ''' -- Currency = Pool().get('currency.currency') -- res = {} -+ pool = Pool() -+ Currency = pool.get('currency.currency') -+ MoveLine = pool.get('account.move.line') - if self.type != 'line': - return [] -- res['description'] = self.description -+ line = MoveLine() -+ line.description = self.description - if self.invoice.currency != self.invoice.company.currency: - with Transaction().set_context(date=self.invoice.currency_date): - amount = Currency.compute(self.invoice.currency, - self.amount, self.invoice.company.currency) -- res['amount_second_currency'] = self.amount -- res['second_currency'] = self.invoice.currency.id -+ line.amount_second_currency = self.amount -+ line.second_currency = self.invoice.currency.id - else: - amount = self.amount -- res['amount_second_currency'] = None -- res['second_currency'] = None -+ line.amount_second_currency = None -+ line.second_currency = None - if amount >= 0: - if self.invoice.type == 'out': -- res['debit'], res['credit'] = 0, amount -+ line.debit, line.credit = 0, amount - else: -- res['debit'], res['credit'] = amount, 0 -+ line.debit, line.credit = amount, 0 - else: - if self.invoice.type == 'out': -- res['debit'], res['credit'] = -amount, 0 -+ line.debit, line.credit = -amount, 0 - else: -- res['debit'], res['credit'] = 0, -amount -- if res['amount_second_currency']: -- res['amount_second_currency'] = ( -- res['amount_second_currency'].copy_sign( -- res['debit'] - res['credit'])) -- res['account'] = self.account.id -+ line.debit, line.credit = 0, -amount -+ if line.amount_second_currency: -+ line.amount_second_currency = ( -+ line.amount_second_currency.copy_sign( -+ line.debit - line.credit)) -+ line.account = self.account.id - if self.account.party_required: -- res['party'] = self.invoice.party.id -+ line.party = self.invoice.party.id - computed_taxes = self._compute_taxes() - if computed_taxes: -- res['tax_lines'] = [('create', [tax for tax in computed_taxes])] -- return [res] -+ line.tax_lines = computed_taxes -+ return [line] - - def _credit(self): - ''' -@@ -2131,47 +2154,50 @@ - - def get_move_line(self): - ''' -- Return a list of move lines values for invoice tax -+ Return a list of move lines instances for invoice tax - ''' -- Currency = Pool().get('currency.currency') -- res = {} -+ pool = Pool() -+ Currency = pool.get('currency.currency') -+ MoveLine = pool.get('account.move.line') -+ TaxLine = pool.get('account.tax.line') -+ line = MoveLine() - if not self.amount: - return [] -- res['description'] = self.description -+ line.description = self.description - if self.invoice.currency != self.invoice.company.currency: - with Transaction().set_context(date=self.invoice.currency_date): - amount = Currency.compute(self.invoice.currency, self.amount, - self.invoice.company.currency) -- res['amount_second_currency'] = self.amount -- res['second_currency'] = self.invoice.currency.id -+ line.amount_second_currency = self.amount -+ line.second_currency = self.invoice.currency.id - else: - amount = self.amount -- res['amount_second_currency'] = None -- res['second_currency'] = None -+ line.amount_second_currency = None -+ line.second_currency = None - if amount >= 0: - if self.invoice.type == 'out': -- res['debit'], res['credit'] = 0, amount -+ line.debit, line.credit = 0, amount - else: -- res['debit'], res['credit'] = amount, 0 -+ line.debit, line.credit = amount, 0 - else: - if self.invoice.type == 'out': -- res['debit'], res['credit'] = -amount, 0 -+ line.debit, line.credit = -amount, 0 - else: -- res['debit'], res['credit'] = 0, -amount -- if res['amount_second_currency']: -- res['amount_second_currency'] = ( -- res['amount_second_currency'].copy_sign( -- res['debit'] - res['credit'])) -- res['account'] = self.account.id -+ line.debit, line.credit = 0, -amount -+ if line.amount_second_currency: -+ line.amount_second_currency = ( -+ line.amount_second_currency.copy_sign( -+ line.debit - line.credit)) -+ line.account = self.account.id - if self.account.party_required: -- res['party'] = self.invoice.party.id -+ line.party = self.invoice.party.id - if self.tax_code: -- res['tax_lines'] = [('create', [{ -- 'code': self.tax_code.id, -- 'amount': amount * self.tax_sign, -- 'tax': self.tax and self.tax.id or None -- }])] -- return [res] -+ tax_line = TaxLine() -+ tax_line.code = self.tax_code -+ tax_line.amount = amount * self.tax_sign -+ tax_line.tax = self.tax -+ line.tax_lines = [tax_line] -+ return [line] - - def _credit(self): - ''' -diff -r 0e69764f2826 trytond/trytond/modules/account_payment_type/invoice.py ---- a/trytond/trytond/modules/account_payment_type/invoice.py Tue Jul 07 10:10:50 2015 +0200 -+++ b/trytond/trytond/modules/account_payment_type/invoice.py Tue Jul 07 17:06:02 2015 +0200 -@@ -82,7 +82,7 @@ - return self.company.party.customer_payment_type.id - - def _get_move_line(self, date, amount): -- res = super(Invoice, self)._get_move_line(date, amount) -+ line = super(Invoice, self)._get_move_line(date, amount) - if self.payment_type: -- res['payment_type'] = self.payment_type -- return res -+ line.payment_type = self.payment_type -+ return line -diff -r 6429c9c53cb8 trytond/trytond/modules/account_bank/account.py ---- a/trytond/trytond/modules/account_bank/account.py Tue May 05 14:36:02 2015 +0200 -+++ b/trytond/trytond/modules/account_bank/account.py Tue Jul 07 15:36:26 2015 +0200 -@@ -179,10 +179,10 @@ - ''' - Add account bank to move line when post invoice. - ''' -- res = super(Invoice, self)._get_move_line(date, amount) -+ line = super(Invoice, self)._get_move_line(date, amount) - if self.bank_account: -- res['bank_account'] = self.bank_account -- return res -+ line.bank_account = self.bank_account -+ return line - - @classmethod - def create(cls, vlist): -diff -r 95d77335bdd5 trytond/trytond/modules/analytic_invoice/invoice.py ---- a/trytond/trytond/modules/analytic_invoice/invoice.py Sun Mar 01 15:34:41 2015 +0100 -+++ b/trytond/trytond/modules/analytic_invoice/invoice.py Mon Nov 30 14:24:25 2015 +0100 -@@ -25,32 +25,33 @@ - - return result - -- def get_analytic_entry(self, entry, value): -- analytic_entry = {} -- analytic_entry['name'] = self.description -- analytic_entry['debit'] = value['debit'] -- analytic_entry['credit'] = value['credit'] -- analytic_entry['account'] = entry.account.id -- analytic_entry['journal'] = self.invoice.journal.id -- analytic_entry['date'] = (self.invoice.accounting_date or -- self.invoice.invoice_date) -- analytic_entry['reference'] = self.invoice.reference -- analytic_entry['party'] = self.invoice.party.id -- return analytic_entry -+ def get_analytic_entry(self, entry, line): -+ pool = Pool() -+ AnalyticLine = pool.get('analytic_account.line') -+ analytic_line = AnalyticLine() -+ analytic_line.name = self.description -+ analytic_line.debit = line.debit -+ analytic_line.credit = line.credit -+ analytic_line.account = entry.account -+ analytic_line.journal = self.invoice.journal -+ analytic_line.date = (self.invoice.accounting_date -+ or self.invoice.invoice_date) -+ analytic_line.reference = self.invoice.reference -+ analytic_line.party = self.invoice.party -+ return analytic_line - - def get_move_line(self): -- values = super(InvoiceLine, self).get_move_line() -+ lines = super(InvoiceLine, self).get_move_line() - if self.analytic_accounts: -- for value in values: -- value['analytic_lines'] = [] -- to_create = [] -+ for line in lines: -+ analytic_lines = [] - for entry in self.analytic_accounts: - if not entry.account: - continue -- to_create.append(self.get_analytic_entry(entry, value)) -- if to_create: -- value['analytic_lines'] = [('create', to_create)] -- return values -+ analytic_lines.append(self.get_analytic_entry(entry, -+ line)) -+ line.analytic_lines = analytic_lines -+ return lines - - - class AnalyticAccountEntry: diff --git a/issue10091002_1.diff b/issue10091002_1.diff deleted file mode 100644 index a69a770..0000000 --- a/issue10091002_1.diff +++ /dev/null @@ -1,66 +0,0 @@ -# HG changeset patch -# User Guillem Barba -add relate to Credit Notes in Invoices - -issue4506 -review10091002 - -Index: invoice.xml -=================================================================== - ---- .a/trytond/trytond/modules/account_invoice/invoice.xml -+++ .b/trytond/trytond/modules/account_invoice/invoice.xml -@@ -38,6 +38,17 @@ - - - -+ -+ Credit Notes -+ account.invoice -+ -+ -+ -+ form_relate -+ account.invoice,-1 -+ -+ -+ - - Customer Invoices - account.invoice - - -Index: ca_ES.xml -=================================================================== - ---- .a/trytond/trytond/modules/account_invoice/locale/ca_ES.po -+++ .b/trytond/trytond/modules/account_invoice/locale/ca_ES.po -@@ -1053,6 +1053,10 @@ - msgid "Invoices" - msgstr "Factures" - -+msgctxt "model:ir.action,name:act_credit_notes_form" -+msgid "Credit Notes" -+msgstr "Abonaments" -+ - msgctxt "model:ir.action,name:act_invoice_in_credit_note_form" - msgid "Supplier Credit Notes" - msgstr "Abonaments de proveïdor" - - -Index: ca_ES.xml -=================================================================== - ---- .a/trytond/trytond/modules/account_invoice/locale/es_ES.po -+++ .b/trytond/trytond/modules/account_invoice/locale/es_ES.po -@@ -1045,6 +1045,10 @@ - msgid "Invoices" - msgstr "Todas las facturas" - -+msgctxt "model:ir.action,name:act_credit_notes_form" -+msgid "Credit Notes" -+msgstr "Abonos" -+ - msgctxt "model:ir.action,name:act_invoice_form2" - msgid "Invoices" - msgstr "Facturas" diff --git a/issue10391004_1.diff b/issue10391004_1.diff deleted file mode 100644 index ccf0ad1..0000000 --- a/issue10391004_1.diff +++ /dev/null @@ -1,14 +0,0 @@ -Index: line.py -=================================================================== - ---- ./trytond/trytond/modules/analytic_account/line.py -+++ ./trytond/trytond/modules/analytic_account/line.py -@@ -28,7 +28,7 @@ - 'on_change_with_company') - account = fields.Many2One('analytic_account.account', 'Account', - required=True, select=True, domain=[ -- ('type', '!=', 'view'), -+ ('type', 'not in', ['view', 'root']), - ['OR', - ('company', '=', None), - ('company', '=', Eval('company', -1)), diff --git a/issue10467.diff b/issue10467.diff deleted file mode 100644 index 510f249..0000000 --- a/issue10467.diff +++ /dev/null @@ -1,23 +0,0 @@ -Index: stock.py -=================================================================== - ---- .a/trytond/trytond/modules/stock_lot/stock.py -+++ .b/trytond/trytond/modules/stock_lot/stock.py -@@ -80,6 +80,20 @@ - for move in moves: - move.check_lot() - -+ @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)) -+ diff --git a/issue130_392_10919.diff b/issue130_392_10919.diff deleted file mode 100644 index dc86cbe..0000000 --- a/issue130_392_10919.diff +++ /dev/null @@ -1,34 +0,0 @@ -diff -r dfbbed6b42d5 trytond/trytond/protocols/dispatcher.py ---- a/trytond/trytond/protocols/dispatcher.py Thu Apr 07 00:04:01 2016 +0200 -+++ b/trytond/trytond/protocols/dispatcher.py Thu Apr 07 10:50:57 2016 +0200 -@@ -212,7 +212,7 @@ - logger.error(log_message, *log_args, exc_info=True) - raise - except (ConcurrencyException, UserError, UserWarning): -- 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 dfbbed6b42d5 trytond/protocols/jsonrpc.py ---- a/trytond/trytond/protocols/jsonrpc.py Thu Apr 07 00:04:01 2016 +0200 -+++ b/trytond/trytond/protocols/jsonrpc.py Thu Apr 07 10:50:57 2016 +0200 -@@ -9,6 +9,7 @@ - except ImportError: - import json - import base64 -+import logging - - from werkzeug.wrappers import Response - from werkzeug.utils import cached_property -@@ -123,6 +124,10 @@ - try: - return json.loads(self.decoded_data, object_hook=JSONDecoder()) - except Exception: -+ exc_type, exc_value = sys.exc_info()[:2] -+ logger = logging.getLogger(__name__) -+ logger.warning('Exception while parsing json: %s (%s)\n %s' -+ % (exc_value, exc_type, traceback.format_exc())) - raise BadRequest('Unable to read JSON request') - else: - raise BadRequest('Not a JSON request') diff --git a/issue13181002_1.diff b/issue13181002_1.diff deleted file mode 100644 index b8ab99e..0000000 --- a/issue13181002_1.diff +++ /dev/null @@ -1,70 +0,0 @@ -# HG changeset patch -# User Sergi Almacellas Abellana -save tree state when executing actions from list view menu - -issue4771 -review13181002 - -Index: tryton/tryton/common/popup_menu.py -=================================================================== - ---- a/tryton/tryton/common/popup_menu.py -+++ b/tryton/tryton/common/popup_menu.py -@@ -11,7 +11,7 @@ - _ = gettext.gettext - - --def populate(menu, model, record, title='', field=None): -+def populate(menu, model, record, title='', field=None, parent_screen=None): - ''' - Fill menu with the actions of model for the record. - If title is filled, the actions will be put in a submenu. -@@ -37,6 +37,8 @@ - return record - - def activate(menuitem, action, atype): -+ if parent_screen: -+ parent_screen.save_tree_state() - rec = load(record) - action = Action.evaluate(action, atype, rec) - data = { - -Index: tryton/tryton/gui/window/view_form/view/list.py -=================================================================== - ---- a/tryton/tryton/gui/window/view_form/view/list.py -+++ b/tryton/tryton/gui/window/view_form/view/list.py -@@ -901,7 +901,7 @@ - menu = gtk.Menu() - menu.popup(None, None, None, event.button, event.time) - -- def pop(menu, group, record): -+ def pop(menu, group, record, screen): - copy_item = gtk.ImageMenuItem('gtk-copy') - copy_item.connect('activate', lambda x: self.on_copy()) - menu.append(copy_item) -@@ -915,7 +915,8 @@ - break - parent = parent.parent - else: -- populate(menu, group.model_name, record) -+ populate(menu, group.model_name, record, -+ parent_screen=screen) - for col in self.treeview.get_columns(): - if not col.get_visible() or not col.name: - continue -@@ -932,10 +933,11 @@ - if not model: - continue - label = field.attrs['string'] -- populate(menu, model, record_id, title=label, field=field) -+ populate(menu, model, record_id, title=label, field=field, -+ parent_screen=screen) - menu.show_all() - # Delay filling of popup as it can take time -- gobject.idle_add(pop, menu, group, record) -+ gobject.idle_add(pop, menu, group, record, self.screen) - elif event.button == 2: - event.button = 1 - event.state |= gtk.gdk.MOD1_MASK - diff --git a/issue13891002_20001.diff b/issue13891002_20001.diff deleted file mode 100644 index 111e420..0000000 --- a/issue13891002_20001.diff +++ /dev/null @@ -1,29 +0,0 @@ -# HG changeset patch -# User Sergi Almacellas Abellana -Add company access rule for inventories - -issue4482 -review13891002 - -Index: trytond/trytond/modules/stock/inventory.xml -=================================================================== - ---- a/trytond/trytond/modules/stock/inventory.xml -+++ b/trytond/trytond/modules/stock/inventory.xml -@@ -57,6 +57,15 @@ - inventory_line_tree - - -+ -+ -+ -+ -+ -+ -+ -+ -+ - - - - diff --git a/issue15211002-sale-confirmed-to-done.diff b/issue15211002-sale-confirmed-to-done.diff deleted file mode 100644 index a47656d..0000000 --- a/issue15211002-sale-confirmed-to-done.diff +++ /dev/null @@ -1,12 +0,0 @@ -diff -r 8635acede28d sale.py ---- .a/trytond/trytond/modules/sale/sale.py Sat Feb 21 19:06:50 2015 +0100 -+++ .b/trytond/trytond/modules/sale/sale.py Mon Apr 20 09:32:28 2015 +0200 -@@ -951,7 +951,7 @@ - if sale.is_done(): - if sale.state != 'done': - done.append(sale) -- elif sale.state != 'processing': -+ if sale.state != 'processing': - process.append(sale) - if process: - cls.proceed(process) diff --git a/issue154_316.diff b/issue154_316.diff deleted file mode 100644 index f1f73f8..0000000 --- a/issue154_316.diff +++ /dev/null @@ -1,37 +0,0 @@ -diff -r ae376b988766 product.py ---- .a/trytond/trytond/modules/purchase/product.py Mon Oct 20 15:02:51 2014 +0200 -+++ .b/trytond/trytond/modules/purchase/product.py Mon Nov 03 13:24:24 2014 +0100 -@@ -132,11 +132,14 @@ - for product_supplier in product.product_suppliers: - if product_supplier.match(pattern): - pattern = ProductSupplierPrice.get_pattern() -- for price in product_supplier.prices: -- if price.match(quantity, uom, pattern): -- prices[product.id] = price.unit_price -- default_uom = product_supplier.uom -- default_currency = product_supplier.currency -+ price = product.get_supplier_price(product_supplier, -+ quantity, uom, pattern) -+ if price is not None: -+ prices[product.id] = price -+ default_uom = product.purchase_uom -+ default_currency = product_supplier.currency -+ else: -+ price = product.cost_price - break - prices[product.id] = Uom.compute_price( - default_uom, prices[product.id], uom) -@@ -147,6 +150,13 @@ - prices[product.id], currency, round=False) - return prices - -+ def get_supplier_price(self, product_supplier, quantity, uom, pattern): -+ res = None -+ for price in product_supplier.prices: -+ if price.match(quantity, uom, pattern): -+ res = price.unit_price -+ return res -+ - - class ProductSupplier(ModelSQL, ModelView, MatchMixin): - 'Product Supplier' diff --git a/issue16661002_1.diff b/issue16661002_1.diff deleted file mode 100644 index 3b6be90..0000000 --- a/issue16661002_1.diff +++ /dev/null @@ -1,38 +0,0 @@ -diff -r 673658d4acd2 account.py ---- a/trytond/trytond/modules/account_invoice_stock/account.py Tue Sep 22 22:57:05 2015 +0200 -+++ b/trytond/trytond/modules/account_invoice_stock/account.py Mon Oct 19 10:43:41 2015 +0200 -@@ -34,6 +34,15 @@ - self.unit) - return quantity - -+ @property -+ def origin_quantity(self): -+ 'The move quantity computed in origin unit' -+ pool = Pool() -+ Uom = pool.get('product.uom') -+ if not self.origin or not hasattr(self.origin, 'unit'): -+ return self.quantity -+ return Uom.compute_qty(self.unit, self.quantity, self.origin.unit) -+ - @classmethod - def copy(cls, lines, default=None): - if default is None: -diff -r 673658d4acd2 stock.py ---- a/trytond/trytond/modules/account_invoice_stock/stock.py Tue Sep 22 22:57:05 2015 +0200 -+++ b/trytond/trytond/modules/account_invoice_stock/stock.py Mon Oct 19 10:43:41 2015 +0200 -@@ -24,6 +24,15 @@ - invoice_line.quantity, self.uom) - return quantity - -+ @property -+ def origin_quantity(self): -+ 'The move quantity computed in origin unit' -+ pool = Pool() -+ Uom = pool.get('product.uom') -+ if not self.origin or not hasattr(self.origin, 'unit'): -+ return self.quantity -+ return Uom.compute_qty(self.uom, self.quantity, self.origin.unit) -+ - @classmethod - def copy(cls, moves, default=None): - if default is None: diff --git a/issue17881002_1.diff b/issue17881002_1.diff deleted file mode 100644 index 6ed1244..0000000 --- a/issue17881002_1.diff +++ /dev/null @@ -1,71 +0,0 @@ -# HG changeset patch -# User Cédric Krier -Disable button during click processing - - -The click event must be blocked when the screen method is called to limit -double execution. A double execution is still possible if the execution of the -action, which is asynchronous, is not started fast enough. - -issue5362 -review17881002 - -Index: src/view/form.js -=================================================================== - ---- a/public_data/sao/src/view/form.js -+++ b/public_data/sao/src/view/form.js -@@ -361,7 +361,12 @@ - }, - button_clicked: function(event) { - var button = event.data; -- this.screen.button(button.attributes); -+ button.el.prop('disabled', true); -+ try { -+ this.screen.button(button.attributes); -+ } finally { -+ button.el.prop('disabled', false); -+ } - }, - selected_records: function() { - if (this.screen.current_record) { - -Index: src/view/tree.js -=================================================================== - ---- a/public_data/sao/src/view/tree.js -+++ b/public_data/sao/src/view/tree.js -@@ -1509,7 +1509,7 @@ - }, - render: function(record) { - var button = new Sao.common.Button(this.attributes); -- button.el.click(record, this.button_clicked.bind(this)); -+ button.el.click([record, button], this.button_clicked.bind(this)); - var fields = jQuery.map(this.screen.model.fields, - function(field, name) { - if ((field.description.loading || 'eager') == -@@ -1526,7 +1526,8 @@ - return button.el; - }, - button_clicked: function(event) { -- var record = event.data; -+ var record = event.data[0]; -+ var button = event.data[1]; - if (record != this.screen.current_record) { - return; - } -@@ -1534,7 +1535,12 @@ - if (states.invisible || states.readonly) { - return; - } -- this.screen.button(this.attributes); -+ button.el.prop('disabled', true); -+ try { -+ this.screen.button(this.attributes); -+ } finally { -+ button.el.prop('disabled', false); -+ } - } - }); - - diff --git a/issue18481003_1.diff b/issue18481003_1.diff deleted file mode 100644 index 1f68df5..0000000 --- a/issue18481003_1.diff +++ /dev/null @@ -1,29 +0,0 @@ -# HG changeset patch -# User Sergi Almacellas Abellana -Correctly show reference and party on invoice rec_name - -issue4878 -review18481003 - -Index: trytond/trytond/modules/account_invoice/invoice.py -=================================================================== - ---- a/trytond/trytond/modules/account_invoice/invoice.py -+++ b/trytond/trytond/modules/account_invoice/invoice.py -@@ -942,9 +942,12 @@ - cls.raise_user_error('modify_invoice', (invoice.rec_name,)) - - def get_rec_name(self, name): -- return (self.number or unicode(self.id) -- + (self.reference and (' ' + self.reference) or '') -- + ' ' + self.party.rec_name) -+ name = self.number or unicode(self.id) -+ if self.reference: -+ name += ' %s' % self.reference -+ if self.party: -+ name += ' %s' % self.party.rec_name -+ return name - - @classmethod - def search_rec_name(cls, name, clause): - diff --git a/issue18801002_1.diff b/issue18801002_1.diff deleted file mode 100644 index 4f6ac51..0000000 --- a/issue18801002_1.diff +++ /dev/null @@ -1,38 +0,0 @@ -# HG changeset patch -# User Sergi Almacellas Abellana -Allow to customize productions code - -issue5144 -review18801002 - -Index: trytond/trytond/modules/production/production.py -=================================================================== - ---- a/trytond/trytond/modules/production/production.py -+++ b/trytond/trytond/modules/production/production.py -@@ -446,7 +446,8 @@ - vlist = [x.copy() for x in vlist] - config = Config(1) - for values in vlist: -- values['code'] = Sequence.get_id(config.production_sequence.id) -+ if not values.get('code'): -+ values['code'] = Sequence.get_id(config.production_sequence.id) - productions = super(Production, cls).create(vlist) - for production in productions: - production._set_move_planned_date() -@@ -458,6 +459,14 @@ - for production in sum(args[::2], []): - production._set_move_planned_date() - -+ @classmethod -+ def copy(cls, productions, default=None): -+ if default is None: -+ default = {} -+ default = default.copy() -+ default.setdefault('code', None) -+ return super(Production, cls).copy(productions, default=default) -+ - def _get_move_planned_date(self): - "Return the planned dates for input and output moves" - return self.planned_date, self.planned_date - diff --git a/issue23901002_1.diff b/issue23901002_1.diff deleted file mode 100644 index e62367f..0000000 --- a/issue23901002_1.diff +++ /dev/null @@ -1,75 +0,0 @@ -# HG changeset patch -# User Cédric Krier -Execute action synchronously - - -The clicked event must be blocked when the action is started, so the retrieval -of the action definition should be synchronous to be done inside the -try/finally. - -issue5362 -review23901002 - -Index: tryton/action/main.py -=================================================================== - ---- a/tryton/tryton/action/main.py -+++ b/tryton/tryton/action/main.py -@@ -54,31 +54,16 @@ - - @staticmethod - def execute(act_id, data, action_type=None, context=None): -- def get_action_type(actions): -- try: -- action, = actions() -- except RPCException: -- return -+ # Must be executed synchronously to avoid double execution -+ # on double click. -+ if not action_type: -+ action, = RPCExecute('model', 'ir.action', 'read', [act_id], -+ ['type'], context=context) - action_type = action['type'] -- exec_action(action_type) -- -- def exec_action(action_type): -- def callback(actions): -- try: -- action, = actions() -- except RPCException: -- return -- Action._exec_action(action, data, context=context) -- -- RPCExecute('model', action_type, 'search_read', -- [('action', '=', act_id)], 0, 1, None, None, -- context=context, callback=callback) -- -- if not action_type: -- RPCExecute('model', 'ir.action', 'read', [act_id], -- ['type'], context=context, callback=get_action_type) -- else: -- exec_action(action_type) -+ action, = RPCExecute('model', action_type, 'search_read', -+ [('action', '=', act_id)], 0, 1, None, None, -+ context=context) -+ Action._exec_action(action, data, context=context) - - @staticmethod - def _exec_action(action, data=None, context=None): - -Index: tryton/gui/window/view_form/view/list_gtk/widget.py -=================================================================== - ---- a/tryton/tryton/gui/window/view_form/view/list_gtk/widget.py -+++ b/tryton/tryton/gui/window/view_form/view/list_gtk/widget.py -@@ -909,4 +909,8 @@ - if state_changes.get('invisible') \ - or state_changes.get('readonly'): - return True -- self.view.screen.button(self.attrs) -+ widget.handler_block_by_func(self.button_clicked) -+ try: -+ self.view.screen.button(self.attrs) -+ finally: -+ widget.handler_unblock_by_func(self.button_clicked) - diff --git a/issue239_630.diff b/issue239_630.diff deleted file mode 100644 index 9ec96a4..0000000 --- a/issue239_630.diff +++ /dev/null @@ -1,31 +0,0 @@ -diff -r ad935d7f423e trytond/trytond/modules/stock/location.py ---- a/trytond/trytond/modules/stock/location.py Mon Mar 28 10:34:04 2016 +0200 -+++ b/trytond/trytond/modules/stock/location.py Thu Apr 07 11:25:56 2016 +0200 -@@ -224,6 +224,11 @@ - return [(cls._rec_name,) + tuple(clause[1:])] - - @classmethod -+ def _quantity_grouping_and_key(cls): -+ product_id = Transaction().context['product'] -+ return ('product', ), (product_id,) -+ -+ @classmethod - def get_quantity(cls, locations, name): - pool = Pool() - Product = pool.get('product.product') -@@ -255,12 +260,13 @@ - pbl = {} - for sub_locations in grouped_slice(locations): - location_ids = [l.id for l in sub_locations] -+ grouping, key = cls._quantity_grouping_and_key() - with Transaction().set_context(context): - pbl.update(Product.products_by_location( - location_ids=location_ids, product_ids=[product_id], -- with_childs=True)) -+ with_childs=True, grouping=grouping)) - -- return dict((loc.id, pbl.get((loc.id, product_id), 0)) -+ return dict((loc.id, pbl.get((loc.id,) + key, 0)) - for loc in locations) - - @classmethod diff --git a/issue240_631.diff b/issue240_631.diff deleted file mode 100644 index 530dc38..0000000 --- a/issue240_631.diff +++ /dev/null @@ -1,304 +0,0 @@ -diff -r 8513232c6649 trytond/trytond/modules/stock_lot/__init__.py ---- a/trytond/trytond/modules/stock_lot/__init__.py Sat Feb 27 00:34:46 2016 +0100 -+++ b/trytond/trytond/modules/stock_lot/__init__.py Thu Apr 07 11:02:06 2016 +0200 -@@ -21,4 +21,9 @@ - Template, - Product, - TemplateLotType, -+ Location, -+ LotByLocationStart, - module='stock_lot', type_='model') -+ Pool.register( -+ LotByLocation, -+ module='stock_lot', type_='wizard') -diff -r 8513232c6649 locale/ca_ES.po ---- a/trytond/trytond/modules/stock_lot/locale/ca_ES.po Sat Feb 27 00:34:46 2016 +0100 -+++ b/trytond/trytond/modules/stock_lot/locale/ca_ES.po Thu Apr 07 11:02:06 2016 +0200 -@@ -86,6 +86,14 @@ - msgid "Write User" - msgstr "Usuari modificació" - -+msgctxt "field:stock.lot.by_location.start,forecast_date:" -+msgid "At Date" -+msgstr "A data" -+ -+msgctxt "field:stock.lot.by_location.start,id:" -+msgid "ID" -+msgstr "Identificador" -+ - msgctxt "field:stock.lot.type,code:" - msgid "Code" - msgstr "Codi" -@@ -174,6 +182,16 @@ - msgid "The type of location for which lot is required" - msgstr "Tipus d'ubicació per la qual el lot és obligatori." - -+msgctxt "help:stock.lot.by_location.start,forecast_date:" -+msgid "" -+"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." -+msgstr "" -+"Permet calcular les quantitats previstes d'estoc per a aquesta data.\n" -+"* Un valor buit és un data infinita en el futur.\n" -+"* Una data en el passat proporcionarà valors històrics." -+ - msgctxt "model:ir.action,name:act_lot_form" - msgid "Lots" - msgstr "Lots" -@@ -182,6 +200,10 @@ - msgid "Moves" - msgstr "Moviments" - -+msgctxt "model:ir.action,name:wizard_lot_by_location" -+msgid "Lot by Locations" -+msgstr "Lots per ubicació" -+ - msgctxt "model:ir.ui.menu,name:menu_lot_form" - msgid "Lots" - msgstr "Lots" -@@ -194,6 +216,10 @@ - msgid "Stock Lot" - msgstr "Lot" - -+msgctxt "model:stock.lot.by_location.start,name:" -+msgid "Lot by Location" -+msgstr "Lot per ubicació" -+ - msgctxt "model:stock.lot.type,name:" - msgid "Stock Lot Type" - msgstr "Tipus de lot" -@@ -226,6 +252,10 @@ - msgid "Lots" - msgstr "Lots" - -+msgctxt "view:stock.lot.by_location.start:" -+msgid "Lot by Location" -+msgstr "Lot per ubicació" -+ - msgctxt "view:stock.lot:" - msgid "Lot" - msgstr "Lot" -@@ -241,3 +271,11 @@ - msgctxt "view:stock.period.cache.lot:" - msgid "Period Lot Caches" - msgstr "Períodes d'estoc precalculat " -+ -+msgctxt "wizard_button:stock.lot.by_location,start,end:" -+msgid "Cancel" -+msgstr "Cancel·la" -+ -+msgctxt "wizard_button:stock.lot.by_location,start,open:" -+msgid "Open" -+msgstr "Obre" -diff -r 8513232c6649 trytond/trytond/modules/stock_lot/locale/es_ES.po ---- a/trytond/trytond/modules/stock_lot/locale/es_ES.po Sat Feb 27 00:34:46 2016 +0100 -+++ b/trytond/trytond/modules/stock_lot/locale/es_ES.po Thu Apr 07 11:02:06 2016 +0200 -@@ -86,6 +86,14 @@ - msgid "Write User" - msgstr "Usuario modificación" - -+msgctxt "field:stock.lot.by_location.start,forecast_date:" -+msgid "At Date" -+msgstr "A fecha" -+ -+msgctxt "field:stock.lot.by_location.start,id:" -+msgid "ID" -+msgstr "Identificador" -+ - msgctxt "field:stock.lot.type,code:" - msgid "Code" - msgstr "Código" -@@ -174,6 +182,16 @@ - msgid "The type of location for which lot is required" - msgstr "El tipo de ubicación en la que el lote es obligatorio." - -+msgctxt "help:stock.lot.by_location.start,forecast_date:" -+msgid "" -+"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." -+msgstr "" -+"Permite calcular las cantidades previstas de stock para esta fecha.\n" -+"* Un valor vacío es un fecha infinita en el futuro.\n" -+"* Una fecha en el pasado proporcionará valores históricos." -+ - msgctxt "model:ir.action,name:act_lot_form" - msgid "Lots" - msgstr "Lotes" -@@ -182,6 +200,10 @@ - msgid "Moves" - msgstr "Movimientos" - -+msgctxt "model:ir.action,name:wizard_lot_by_location" -+msgid "Lot by Locations" -+msgstr "Lotes por ubicación" -+ - msgctxt "model:ir.ui.menu,name:menu_lot_form" - msgid "Lots" - msgstr "Lotes" -@@ -194,6 +216,10 @@ - msgid "Stock Lot" - msgstr "Lote stock" - -+msgctxt "model:stock.lot.by_location.start,name:" -+msgid "Lot by Location" -+msgstr "Lote por ubicación" -+ - msgctxt "model:stock.lot.type,name:" - msgid "Stock Lot Type" - msgstr "Tipo lote stock" -@@ -226,6 +252,10 @@ - msgid "Lots" - msgstr "Lotes" - -+msgctxt "view:stock.lot.by_location.start:" -+msgid "Lot by Location" -+msgstr "Lote por ubicación" -+ - msgctxt "view:stock.lot:" - msgid "Lot" - msgstr "Lote" -@@ -241,3 +271,11 @@ - msgctxt "view:stock.period.cache.lot:" - msgid "Period Lot Caches" - msgstr "Período lote precalculados" -+ -+msgctxt "wizard_button:stock.lot.by_location,start,end:" -+msgid "Cancel" -+msgstr "Cancel·lar" -+ -+msgctxt "wizard_button:stock.lot.by_location,start,open:" -+msgid "Open" -+msgstr "Abrir" -diff -r 8513232c6649 trytond/trytond/modules/stock_lot/stock.py ---- a/trytond/trytond/modules/stock_lot/stock.py Sat Feb 27 00:34:46 2016 +0100 -+++ b/trytond/trytond/modules/stock_lot/stock.py Thu Apr 07 11:02:06 2016 +0200 -@@ -1,15 +1,18 @@ - # This file is part of Tryton. The COPYRIGHT file at the top level of - # this repository contains the full copyright notices and license terms. -+import datetime - from trytond.model import ModelView, ModelSQL, fields --from trytond.pyson import Eval -+from trytond.pyson import Eval, PYSONEncoder - from trytond.pool import Pool, PoolMeta - from trytond.transaction import Transaction -+from trytond.wizard import Wizard, StateView, StateAction, Button - from trytond.modules.stock import StockMixin - - __all__ = ['Lot', 'LotType', 'Move', 'ShipmentIn', 'ShipmentOut', - 'ShipmentOutReturn', - 'Period', 'PeriodCacheLot', -- 'Inventory', 'InventoryLine'] -+ 'Inventory', 'InventoryLine', 'Location', 'LotByLocationStart', -+ 'LotByLocation'] - - - class Lot(ModelSQL, ModelView, StockMixin): -@@ -216,3 +219,74 @@ - if move: - move.lot = self.lot - return move -+ -+ -+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'], -+ lang.code, lang.date) -+ -+ action['name'] += ' - %s (%s) @ %s' % (lot.rec_name, -+ lot.product.default_uom.rec_name, date) -+ return action, {} -diff -r 8513232c6649 trytond/trytond/modules/stock_lot/stock.xml ---- a/trytond/trytond/modules/stock_lot/stock.xml Sat Feb 27 00:34:46 2016 +0100 -+++ b/trytond/trytond/modules/stock_lot/stock.xml Thu Apr 07 11:02:06 2016 +0200 -@@ -62,6 +62,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 --git a/issue4950_sale.diff b/issue4950_sale.diff deleted file mode 100644 index 669a877..0000000 --- a/issue4950_sale.diff +++ /dev/null @@ -1,115 +0,0 @@ -diff -r f9ff7d1399d1 stock.py ---- a/trytond/trytond/modules/sale/stock.py Fri Sep 04 16:30:54 2015 +0200 -+++ b/trytond/trytond/modules/sale/stock.py Fri Sep 04 16:31:35 2015 +0200 -@@ -1,5 +1,6 @@ - # This file is part of Tryton. The COPYRIGHT file at the top level of - # this repository contains the full copyright notices and license terms. -+from itertools import ifilter - from sql import Null - from sql.operators import Concat - -@@ -61,6 +62,35 @@ - - return super(ShipmentOut, cls).draft(shipments) - -+ def get_origins(self, name): -+ return ', '.join(set(ifilter(None, (m.origin_name -+ for m in self.outgoing_moves)))) -+ -+ @classmethod -+ def _sync_inventory_to_outgoing_grouping_key(cls, move, type): -+ pool = Pool() -+ Move = pool.get('stock.move') -+ key = super(ShipmentOut, -+ cls)._sync_inventory_to_outgoing_grouping_key(move, type) -+ if type == 'outgoing': -+ key = tuple([key, move.origin]) -+ if (type == 'inventory' and move.origin and -+ isinstance(move.origin, Move)): -+ key = tuple([key, move.origin.origin]) -+ return key -+ -+ def _get_outgoing_move(self, move): -+ new_move = super(ShipmentOut, self)._get_outgoing_move(move) -+ if new_move: -+ new_move.origin = move -+ return new_move -+ -+ def _get_inventory_move(self, move): -+ new_move = super(ShipmentOut, self)._get_inventory_move(move) -+ if new_move: -+ new_move.origin = move -+ return new_move -+ - - class ShipmentOutReturn: - __name__ = 'stock.shipment.out.return' -@@ -147,6 +177,7 @@ - @classmethod - def _get_origin(cls): - models = super(Move, cls)._get_origin() -+ models.append('stock.move') - models.append('sale.line') - return models - -diff -r f9ff7d1399d1 tests/scenario_sale.rst ---- a/trytond/trytond/modules/sale/tests/scenario_sale.rst Fri Sep 04 16:30:54 2015 +0200 -+++ b/trytond/trytond/modules/sale/tests/scenario_sale.rst Fri Sep 04 16:31:35 2015 +0200 -@@ -771,3 +771,57 @@ - 5.0 - >>> stock_move.state - u'draft' -+ -+Create a sale with the same products with diferent price to be invoiced on -+shipment and check correctly invoiced:: -+ -+ >>> sale = Sale() -+ >>> sale.party = customer -+ >>> sale.payment_term = payment_term -+ >>> sale.invoice_method = 'shipment' -+ >>> line = sale.lines.new() -+ >>> line.product = product -+ >>> line.quantity = 10.0 -+ >>> line = sale.lines.new() -+ >>> line.product = product -+ >>> line.quantity = 10.0 -+ >>> line.unit_price = Decimal('9.0000') -+ >>> sale.click('quote') -+ >>> sale.click('confirm') -+ >>> sale.click('process') -+ >>> shipment, = sale.shipments -+ >>> config.user = stock_user.id -+ >>> for move in shipment.inventory_moves: -+ ... move.quantity = 5.0 -+ >>> shipment.click('assign_try') -+ True -+ >>> shipment.click('pack') -+ >>> shipment.click('done') -+ >>> config.user = sale_user.id -+ >>> sale.reload() -+ >>> invoice, = sale.invoices -+ >>> _, shipment, = sale.shipments -+ >>> invoice.untaxed_amount -+ Decimal('95.00') -+ >>> first_line, second_line = sorted(invoice.lines, -+ ... key=lambda a: a.unit_price) -+ >>> first_line.unit_price -+ Decimal('9.0000') -+ >>> second_line.unit_price -+ Decimal('10.0000') -+ >>> config.user = stock_user.id -+ >>> shipment.click('assign_try') -+ True -+ >>> shipment.click('pack') -+ >>> shipment.click('done') -+ >>> config.user = sale_user.id -+ >>> sale.reload() -+ >>> _, invoice = sale.invoices -+ >>> invoice.untaxed_amount -+ Decimal('95.00') -+ >>> first_line, second_line = sorted(invoice.lines, -+ ... key=lambda a: a.unit_price) -+ >>> first_line.unit_price -+ Decimal('9.0000') -+ >>> second_line.unit_price -+ Decimal('10.0000') diff --git a/issue4950_stock.diff b/issue4950_stock.diff deleted file mode 100644 index d643558..0000000 --- a/issue4950_stock.diff +++ /dev/null @@ -1,81 +0,0 @@ -diff -r 8684df73e037 shipment.py ---- a/trytond/trytond/modules/stock/shipment.py Fri Sep 04 16:29:38 2015 +0200 -+++ b/trytond/trytond/modules/stock/shipment.py Fri Sep 04 16:30:32 2015 +0200 -@@ -1118,6 +1118,14 @@ - unit_price=move.unit_price, - ) - -+ @staticmethod -+ def _sync_inventory_to_outgoing_grouping_key(move, type): -+ ''' -+ Returns the key used to sync inventory and outgoing moves for move -+ Type contains outgoing or incomming to indicate the kind of move -+ ''' -+ return move.product.id -+ - @classmethod - def _sync_inventory_to_outgoing(cls, shipments, create=True, write=True): - 'Synchronise outgoing moves with inventory moves' -@@ -1132,8 +1140,10 @@ - continue - quantity = Uom.compute_qty(move.uom, move.quantity, - move.product.default_uom, round=False) -- outgoing_qty.setdefault(move.product.id, 0.0) -- outgoing_qty[move.product.id] += quantity -+ key = cls._sync_inventory_to_outgoing_grouping_key(move, -+ 'outgoing') -+ outgoing_qty.setdefault(key, 0.0) -+ outgoing_qty[key] += quantity - - to_create = [] - for move in shipment.inventory_moves: -@@ -1141,19 +1151,20 @@ - continue - qty_default_uom = Uom.compute_qty(move.uom, move.quantity, - move.product.default_uom, round=False) -+ key = cls._sync_inventory_to_outgoing_grouping_key(move, -+ 'inventory') - # Check if the outgoing move doesn't exist already -- if outgoing_qty.get(move.product.id): -+ if outgoing_qty.get(key): - # If it exist, decrease the sum -- if qty_default_uom <= outgoing_qty[move.product.id]: -- outgoing_qty[move.product.id] -= qty_default_uom -+ if qty_default_uom <= outgoing_qty[key]: -+ outgoing_qty[key] -= qty_default_uom - continue - # Else create the complement - else: -- out_quantity = (qty_default_uom -- - outgoing_qty[move.product.id]) -+ out_quantity = (qty_default_uom - outgoing_qty[key]) - out_quantity = Uom.compute_qty( - move.product.default_uom, out_quantity, move.uom) -- outgoing_qty[move.product.id] = 0.0 -+ outgoing_qty[key] = 0.0 - else: - out_quantity = move.quantity - -@@ -1171,9 +1182,11 @@ - for move in shipment.outgoing_moves: - if move.state == 'cancel': - continue -- if outgoing_qty.get(move.product.id, 0.0) > 0.0: -+ key = cls._sync_inventory_to_outgoing_grouping_key(move, -+ 'outgoing') -+ if outgoing_qty.get(key, 0.0) > 0.0: - exc_qty = Uom.compute_qty(move.product.default_uom, -- outgoing_qty[move.product.id], move.uom) -+ outgoing_qty[key], move.uom) - removed_qty = Uom.compute_qty(move.uom, - min(exc_qty, move.quantity), move.product.default_uom, - round=False) -@@ -1181,7 +1194,7 @@ - Move.write([move], { - 'quantity': max(0.0, move.quantity - exc_qty), - }) -- outgoing_qty[move.product.id] -= removed_qty -+ outgoing_qty[key] -= removed_qty - - @classmethod - @ModelView.button diff --git a/issue4986.diff b/issue4986.diff deleted file mode 100644 index a55dd04..0000000 --- a/issue4986.diff +++ /dev/null @@ -1,19 +0,0 @@ -diff -r 90cc3f4c20c9 trytond/trytond/model/modelstorage.py ---- a/trytond/trytond/model/modelstorage.py Tue Sep 22 16:39:45 2015 +0200 -+++ b/trytond/trytond/model/modelstorage.py Tue Sep 22 16:40:32 2015 +0200 -@@ -952,10 +952,11 @@ - if relations: - for sub_relations in grouped_slice(relations): - sub_relations = set(sub_relations) -- finds = Relation.search(['AND', -- [('id', 'in', [r.id for r in sub_relations])], -- domain, -- ]) -+ with Transaction().set_user(0): -+ finds = Relation.search(['AND', -+ [('id', 'in', [r.id for r in sub_relations])], -+ domain, -+ ]) - if sub_relations != set(finds): - cls.raise_user_error('domain_validation_record', - error_args=cls._get_error_args(field.name)) diff --git a/issue5118.diff b/issue5118.diff deleted file mode 100644 index faa4c46..0000000 --- a/issue5118.diff +++ /dev/null @@ -1,27 +0,0 @@ -diff -r 8dec33688c06 trytond/trytond/model/modelsql.py ---- a/trytond/trytond/model/modelsql.py Tue Nov 03 12:20:49 2015 +0100 -+++ b/trytond/trytond/model/modelsql.py Wed Nov 11 09:57:58 2015 +0100 -@@ -128,6 +128,8 @@ - def __register__(cls, module_name): - TableHandler = backend.get('TableHandler') - super(ModelSQL, cls).__register__(module_name) -+ pool = Pool() -+ ModelField = pool.get('ir.model.field') - - if cls.table_query(): - return -@@ -205,7 +207,13 @@ - if isinstance(field, fields.Many2One) \ - and field.model_name == cls.__name__ \ - and field.left and field.right: -- cls._rebuild_tree(field_name, None, 0) -+ irfields = ModelField.search([ -+ ('model.model', '=', field.model_name), -+ ('module', '=', module_name), -+ ('name', 'in', [field.left, field.right]), -+ ]) -+ if irfields: -+ cls._rebuild_tree(field_name, None, 0) - - for ident, constraint, _ in cls._sql_constraints: - table.add_constraint(ident, constraint) diff --git a/issue6021003_1.diff b/issue6021003_1.diff deleted file mode 100644 index e3c1910..0000000 --- a/issue6021003_1.diff +++ /dev/null @@ -1,148 +0,0 @@ -# HG changeset patch -# User Guillem Barba -use method to compute balance, credit and debit getters query - -issue4543 -review6021003 - -Index: account.py -=================================================================== - ---- .a/trytond/trytond/modules/analytic_account/account.py -+++ .b/trytond/trytond/modules/analytic_account/account.py -@@ -124,17 +124,8 @@ - def get_balance(cls, accounts, name): - res = {} - pool = Pool() -- Line = pool.get('analytic_account.line') -- MoveLine = pool.get('account.move.line') -- Account = pool.get('account.account') -- Company = pool.get('company.company') - Currency = pool.get('currency.currency') - cursor = Transaction().connection.cursor() -- table = cls.__table__() -- line = Line.__table__() -- move_line = MoveLine.__table__() -- a_account = Account.__table__() -- company = Company.__table__() - - ids = [a.id for a in accounts] - childs = cls.search([('parent', 'child_of', ids)]) -@@ -145,25 +136,12 @@ - for account in all_accounts: - id2account[account.id] = account - -- line_query = Line.query_get(line) -- cursor.execute(*table.join(line, 'LEFT', -- condition=table.id == line.account -- ).join(move_line, 'LEFT', -- condition=move_line.id == line.move_line -- ).join(a_account, 'LEFT', -- condition=a_account.id == move_line.account -- ).join(company, 'LEFT', -- condition=company.id == a_account.company -- ).select(table.id, -- Sum(Coalesce(line.debit, 0) - Coalesce(line.credit, 0)), -- company.currency, -- where=(table.type != 'view') -- & table.id.in_(all_ids) -- & (table.active == True) & line_query, -- group_by=(table.id, company.currency))) -+ query = cls.query_get(all_ids, [name]) -+ cursor.execute(*query) -+ - account_sum = {} - id2currency = {} -- for account_id, sum, currency_id in cursor.fetchall(): -+ for account_id, currency_id, sum in cursor.fetchall(): - account_sum.setdefault(account_id, Decimal('0.0')) - # SQLite uses float for SUM - if not isinstance(sum, Decimal): -@@ -200,17 +178,8 @@ - @classmethod - def get_credit_debit(cls, accounts, names): - pool = Pool() -- Line = pool.get('analytic_account.line') -- MoveLine = pool.get('account.move.line') -- Account = pool.get('account.account') -- Company = pool.get('company.company') - Currency = pool.get('currency.currency') - cursor = Transaction().connection.cursor() -- table = cls.__table__() -- line = Line.__table__() -- move_line = MoveLine.__table__() -- a_account = Account.__table__() -- company = Company.__table__() - - result = {} - ids = [a.id for a in accounts] -@@ -223,23 +192,8 @@ - for account in accounts: - id2account[account.id] = account - -- line_query = Line.query_get(line) -- columns = [table.id, company.currency] -- for name in names: -- columns.append(Sum(Coalesce(Column(line, name), 0))) -- cursor.execute(*table.join(line, 'LEFT', -- condition=table.id == line.account -- ).join(move_line, 'LEFT', -- condition=move_line.id == line.move_line -- ).join(a_account, 'LEFT', -- condition=a_account.id == move_line.account -- ).join(company, 'LEFT', -- condition=company.id == a_account.company -- ).select(*columns, -- where=(table.type != 'view') -- & table.id.in_(ids) -- & (table.active == True) & line_query, -- group_by=(table.id, company.currency))) -+ query = cls.query_get(ids, names) -+ cursor.execute(*query) - - id2currency = {} - for row in cursor.fetchall(): -@@ -263,6 +217,43 @@ - result[name][account.id] += account.currency.round(sum) - return result - -+ @classmethod -+ def query_get(cls, ids, names): -+ pool = Pool() -+ Line = pool.get('analytic_account.line') -+ MoveLine = pool.get('account.move.line') -+ Account = pool.get('account.account') -+ Company = pool.get('company.company') -+ table = cls.__table__() -+ line = Line.__table__() -+ move_line = MoveLine.__table__() -+ a_account = Account.__table__() -+ company = Company.__table__() -+ -+ line_query = Line.query_get(line) -+ -+ columns = [table.id, company.currency] -+ for name in names: -+ if name == 'balance': -+ columns.append( -+ Sum(Coalesce(line.debit, 0) - Coalesce(line.credit, 0))) -+ else: -+ columns.append(Sum(Coalesce(Column(line, name), 0))) -+ query = table.join(line, 'LEFT', -+ condition=table.id == line.account -+ ).join(move_line, 'LEFT', -+ condition=move_line.id == line.move_line -+ ).join(a_account, 'LEFT', -+ condition=a_account.id == move_line.account -+ ).join(company, 'LEFT', -+ condition=company.id == a_account.company -+ ).select(*columns, -+ where=(table.type != 'view') -+ & table.id.in_(ids) -+ & table.active & line_query, -+ group_by=(table.id, company.currency)) -+ return query -+ - def get_rec_name(self, name): - if self.code: - return self.code + ' - ' + unicode(self.name) diff --git a/issue6341003_1.diff b/issue6341003_1.diff deleted file mode 100644 index 50141b6..0000000 --- a/issue6341003_1.diff +++ /dev/null @@ -1,22 +0,0 @@ -Index: trytond/trytond/modules/account_asset/asset.xml -=================================================================== - ---- a/trytond/trytond/modules/account_asset/asset.xml -+++ b/trytond/trytond/modules/account_asset/asset.xml -@@ -139,6 +139,16 @@ - asset_line_tree - - -+ -+ -+ -+ -+ -+ -+ -+ -+ -+ - - - diff --git a/issue9231002_20001.diff b/issue9231002_20001.diff deleted file mode 100644 index 31f0c3e..0000000 --- a/issue9231002_20001.diff +++ /dev/null @@ -1,29 +0,0 @@ -# HG changeset patch -# User Sergi Almacellas Abellana -Fix copy of translated fields when records aren't read in order - -issue4720 -review9231002 - -Index: trytond/trytond/model/modelstorage.py -=================================================================== - ---- a/trytond/trytond/model/modelstorage.py -+++ b/trytond/trytond/model/modelstorage.py -@@ -301,11 +301,12 @@ - if (not isinstance(f, fields.Function) - or isinstance(f, fields.Property))] - ids = map(int, records) -- datas = cls.read(ids, fields_names=fields_names) -+ datas = dict((d['id'], d) for d in cls.read(ids, -+ fields_names=fields_names)) - field_defs = cls.fields_get(fields_names=fields_names) - to_create = [] -- for data in datas: -- data = convert_data(field_defs, data) -+ for id in ids: -+ data = convert_data(field_defs, datas[id]) - to_create.append(data) - new_records = cls.create(to_create) - new_ids = dict(izip(ids, map(int, new_records))) - diff --git a/limit_invoices_in_creit_note_action_by_domain.diff b/limit_invoices_in_creit_note_action_by_domain.diff deleted file mode 100644 index 55467e2..0000000 --- a/limit_invoices_in_creit_note_action_by_domain.diff +++ /dev/null @@ -1,22 +0,0 @@ -diff -r 80fed5f82f06 invoice.py ---- a/trytond/trytond/modules/account_invoice/invoice.py Fri Nov 27 14:42:58 2015 +0100 -+++ b/trytond/trytond/modules/account_invoice/invoice.py Fri Nov 27 14:43:25 2015 +0100 -@@ -14,7 +14,7 @@ - from trytond.wizard import Wizard, StateView, StateTransition, StateAction, \ - Button - from trytond import backend --from trytond.pyson import If, Eval, Bool, Id -+from trytond.pyson import PYSONEncoder, If, Eval, Bool, Id - from trytond.tools import reduce_ids, grouped_slice - from trytond.transaction import Transaction - from trytond.pool import Pool -@@ -2773,6 +2773,9 @@ - credit_invoices = Invoice.credit(invoices, refund=refund) - - data = {'res_id': [i.id for i in credit_invoices]} -+ action['pyson_domain'] = PYSONEncoder().encode([ -+ ('id', 'in', [i.id for i in credit_invoices]), -+ ]) - if len(credit_invoices) == 1: - action['views'].reverse() - return action, data diff --git a/multicompany_cron.diff b/multicompany_cron.diff deleted file mode 100644 index e8fa7a5..0000000 --- a/multicompany_cron.diff +++ /dev/null @@ -1,13 +0,0 @@ -diff -r 7658cd8c2e7f cron.py ---- a/trytond/trytond/modules/company/cron.py Fri Oct 02 08:56:51 2015 +0200 -+++ b/trytond/trytond/modules/company/cron.py Mon Nov 23 12:35:33 2015 +0100 -@@ -23,7 +23,8 @@ - for company in cron.companies: - User.write([cron.user], { - 'company': company.id, -- 'main_company': company.id, -+ 'main_company': (company.parent.id if company.parent -+ else company.id), - }) - with Transaction().set_context(company=company.id): - super(Cron, cls)._callback(cron) diff --git a/purchase_fix_get_move_done_rounding.diff b/purchase_fix_get_move_done_rounding.diff deleted file mode 100644 index 558cf50..0000000 --- a/purchase_fix_get_move_done_rounding.diff +++ /dev/null @@ -1,12 +0,0 @@ -diff -r 39138b20bd95 purchase.py ---- a/trytond/trytond/modules/purchase/purchase.py Mon Nov 02 16:10:40 2015 +0100 -+++ b/trytond/trytond/modules/purchase/purchase.py Wed Nov 11 11:44:30 2015 +0100 -@@ -1011,7 +1011,7 @@ - break - quantity -= Uom.compute_qty(move.uom, move.quantity, self.unit) - if done: -- if quantity > 0.0: -+ if quantity > self.unit.rounding: - done = False - return done - diff --git a/sao_nantic_theme.diff b/sao_nantic_theme.diff deleted file mode 100644 index a1245b8..0000000 --- a/sao_nantic_theme.diff +++ /dev/null @@ -1,147 +0,0 @@ -diff -r 1e58052bb56f public_html/sao/index.html ---- a/public_html/sao/index.html Thu May 12 09:42:53 2016 +0200 -+++ b/public_html/sao/index.html Fri May 20 10:17:38 2016 +0200 -@@ -25,6 +25,7 @@ - - -+ - - - --