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/024726_account_payment_type_remove_company.diff b/024726_account_payment_type_remove_company.diff
deleted file mode 100644
index 05906be..0000000
--- a/024726_account_payment_type_remove_company.diff
+++ /dev/null
@@ -1,121 +0,0 @@
-diff --git a/view/payment_type_tree.xml b/view/payment_type_tree.xml
---- a/trytond/trytond/modules/account_payment_type/view/payment_type_tree.xml
-+++ b/trytond/trytond/modules/account_payment_type/view/payment_type_tree.xml
-@@ -2,7 +2,6 @@
-
-
-
--
-
-
-
-diff --git a/view/payment_type_form.xml b/view/payment_type_form.xml
---- a/trytond/trytond/modules/account_payment_type/view/payment_type_form.xml
-+++ b/trytond/trytond/modules/account_payment_type/view/payment_type_form.xml
-@@ -4,13 +4,10 @@
-
-
-
-+
-+
-
-
--
--
--
--
--
-
-
-
-diff --git a/tests/test_account_payment_type.py b/tests/test_account_payment_type.py
---- a/trytond/trytond/modules/account_payment_type/tests/test_account_payment_type.py
-+++ b/trytond/trytond/modules/account_payment_type/tests/test_account_payment_type.py
-@@ -78,12 +78,10 @@
- payment_payable, = self.payment_type.create([{
- 'name': 'Payment Payable',
- 'kind': 'payable',
-- 'company': company.id,
- }])
- payment_receivable, = self.payment_type.create([{
- 'name': 'Payment Receivable',
- 'kind': 'receivable',
-- 'company': company.id,
- }])
- move, = self.move.create([{
- 'period': period.id,
-diff --git a/payment_type.xml b/payment_type.xml
---- a/trytond/trytond/modules/account_payment_type/payment_type.xml
-+++ b/trytond/trytond/modules/account_payment_type/payment_type.xml
-@@ -54,14 +54,5 @@
-
-
-
--
--
--
--
--
--
-- [('company', '=', user.company.id if user.company else None)]
--
--
-
-
-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 @@
-
-
-+
-
-
-
--