From 295b96c0b39959d053c3b74edd515879c873c722 Mon Sep 17 00:00:00 2001 From: Denis Ledoux Date: Thu, 24 Nov 2016 16:03:10 +0100 Subject: [PATCH 1/4] [FIX] product: store triggers for related stored `company_id` in pricelists When changing the company of a pricelist, the change was not propagated to the related, stored, company fields of the `product.pricelist.version` and the `product.pricelist.item` These triggers makes that happen. opw-694683 --- addons/product/pricelist.py | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/addons/product/pricelist.py b/addons/product/pricelist.py index 4f79a438462..4646bb0e517 100644 --- a/addons/product/pricelist.py +++ b/addons/product/pricelist.py @@ -380,6 +380,14 @@ class product_pricelist(osv.osv): class product_pricelist_version(osv.osv): _name = "product.pricelist.version" _description = "Pricelist Version" + + def _get_product_pricelist(self, cr, uid, ids, context=None): + result = set() + for pricelist in self.pool['product.pricelist'].browse(cr, uid, ids, context=context): + for version_id in pricelist.version_id: + result.add(version_id.id) + return list(result) + _columns = { 'pricelist_id': fields.many2one('product.pricelist', 'Price List', required=True, select=True, ondelete='cascade'), @@ -393,7 +401,9 @@ class product_pricelist_version(osv.osv): 'date_start': fields.date('Start Date', help="First valid date for the version."), 'date_end': fields.date('End Date', help="Last valid date for the version."), 'company_id': fields.related('pricelist_id','company_id',type='many2one', - readonly=True, relation='res.company', string='Company', store=True) + readonly=True, relation='res.company', string='Company', store={ + 'product.pricelist': (_get_product_pricelist, ['company_id'], 20), + }) } _defaults = { 'active': lambda *a: 1, @@ -486,6 +496,14 @@ class product_pricelist_item(osv.osv): return False return True + def _get_product_pricelist(self, cr, uid, ids, context=None): + result = set() + for pricelist in self.pool['product.pricelist'].browse(cr, uid, ids, context=context): + for version_id in pricelist.version_id: + for item_id in version_id.items_id: + result.add(item_id.id) + return list(result) + _columns = { 'name': fields.char('Rule Name', help="Explicit rule name for this pricelist line."), 'price_version_id': fields.many2one('product.pricelist.version', 'Price List Version', required=True, select=True, ondelete='cascade'), @@ -515,7 +533,9 @@ class product_pricelist_item(osv.osv): 'price_max_margin': fields.float('Max. Price Margin', digits_compute= dp.get_precision('Product Price'), help='Specify the maximum amount of margin over the base price.'), 'company_id': fields.related('price_version_id','company_id',type='many2one', - readonly=True, relation='res.company', string='Company', store=True) + readonly=True, relation='res.company', string='Company', store={ + 'product.pricelist': (_get_product_pricelist, ['company_id'], 30), + }) } _constraints = [ From 456d7b38f1f6c889ab24e391154dbe1d21f34371 Mon Sep 17 00:00:00 2001 From: Denis Ledoux Date: Thu, 24 Nov 2016 16:13:27 +0100 Subject: [PATCH 2/4] [FIX] sale: store triggers for related stored `company_id` sale orders When changing the company of a sales order, the change was not propagated to the related, stored, company field of its sale order lines These triggers makes that happen. opw-694683 --- addons/sale/sale.py | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/addons/sale/sale.py b/addons/sale/sale.py index 9ca0a33ac84..2fe8948f81a 100644 --- a/addons/sale/sale.py +++ b/addons/sale/sale.py @@ -910,6 +910,13 @@ class sale_order_line(osv.osv): res[line.id] = line.price_subtotal / line.product_uom_qty if line.product_uom_qty else 0.0 return res + def _get_sale_order(self, cr, uid, ids, context=None): + result = set() + for order in self.pool['sale.order'].browse(cr, uid, ids, context=context): + for line in order.order_line: + result.add(line.id) + return list(result) + _name = 'sale.order.line' _description = 'Sales Order Line' _columns = { @@ -944,7 +951,9 @@ class sale_order_line(osv.osv): \n* The \'Cancelled\' status is set when a user cancel the sales order related.'), 'order_partner_id': fields.related('order_id', 'partner_id', type='many2one', relation='res.partner', store=True, string='Customer'), 'salesman_id':fields.related('order_id', 'user_id', type='many2one', relation='res.users', store=True, string='Salesperson'), - 'company_id': fields.related('order_id', 'company_id', type='many2one', relation='res.company', string='Company', store=True, readonly=True), + 'company_id': fields.related('order_id', 'company_id', type='many2one', relation='res.company', string='Company', store={ + 'sale.order': (_get_sale_order, ['company_id'], 20), + }, readonly=True), 'delay': fields.float('Delivery Lead Time', required=True, help="Number of days between the order confirmation and the shipping of the products to the customer", readonly=True, states={'draft': [('readonly', False)]}), 'procurement_ids': fields.one2many('procurement.order', 'sale_line_id', 'Procurements'), } From 623d61872db7bb275ae3c17a29ff899f39360a0d Mon Sep 17 00:00:00 2001 From: Zambu Date: Mon, 21 Nov 2016 10:33:28 +0100 Subject: [PATCH 3/4] [CLA] Corporate signature for Diagram Software Closes #14409 --- doc/cla/corporate/diagram-software.md | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 doc/cla/corporate/diagram-software.md diff --git a/doc/cla/corporate/diagram-software.md b/doc/cla/corporate/diagram-software.md new file mode 100644 index 00000000000..93dd9623a62 --- /dev/null +++ b/doc/cla/corporate/diagram-software.md @@ -0,0 +1,20 @@ +Spain, 2016-11-21 + +Diagram Software, S.L. agrees to the terms of the Odoo Corporate Contributor License +Agreement v1.0. + +I declare that I am authorized and able to make this agreement and sign this +declaration. + +Signed, + +Jose Zambudio jose.zambudio@diagram.es https://github.com/zamberjo + +List of contributors: + +Cristian Moncho cristian.moncho@diagram.es https://github.com/crimoniv +Jose Zambudio jose.zambudio@diagram.es https://github.com/zamberjo +Almudena de la Puente almudena.delapuente@diagram.es https://github.com/almumu +Mauro Cebriá mauro.cebria@diagram.es https://github.com/maurochip +Pedro Albujer pedro.albujer.rico@diagram.es https://github.com/P4R +Rubén Cerdà ruben.cerda.roig@diagram.es https://github.com/rubencr7 From cd440312cec71b851a233b39e091089b9b226d99 Mon Sep 17 00:00:00 2001 From: Nicolas Martinelli Date: Tue, 22 Nov 2016 11:56:51 +0100 Subject: [PATCH 4/4] [FIX] account: partial payment reconciliation When processing a partial reconciliation in a foreign currency, a currency exchange difference might be generated during the reconciliation process (see OPW for a detailed use case). This prevents the user to process the reconciliation since he will get the error: 'You have to provide an account for the write off/exchange difference entry.' The fix is to use the company-related foreign echange gain and loss accounts automatically to book this difference. opw-687975 --- addons/account/account_bank_statement.py | 3 ++- addons/account/account_move_line.py | 32 ++++++++++++++++++------ 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/addons/account/account_bank_statement.py b/addons/account/account_bank_statement.py index 56b30800e65..b120da9f3cc 100644 --- a/addons/account/account_bank_statement.py +++ b/addons/account/account_bank_statement.py @@ -920,7 +920,8 @@ class account_bank_statement_line(osv.osv): move_line_pairs_to_reconcile.append([new_aml_id, counterpart_move_line_id]) # Reconcile for pair in move_line_pairs_to_reconcile: - aml_obj.reconcile_partial(cr, uid, pair, context=context) + # DO NOT FORWARD PORT + aml_obj.reconcile_partial(cr, uid, pair, context=dict(context, bs_move_id=move_id)) # Mark the statement line as reconciled self.write(cr, uid, id, {'journal_entry_id': move_id}, context=context) diff --git a/addons/account/account_move_line.py b/addons/account/account_move_line.py index 143c8ff5468..c4042625691 100644 --- a/addons/account/account_move_line.py +++ b/addons/account/account_move_line.py @@ -1004,6 +1004,12 @@ class account_move_line(osv.osv): if (not currency_obj.is_zero(cr, uid, account.company_id.currency_id, writeoff)) or \ (account.currency_id and (not currency_obj.is_zero(cr, uid, account.currency_id, currency))): + # DO NOT FORWARD PORT + if not writeoff_acc_id: + if writeoff > 0: + writeoff_acc_id = account.company_id.expense_currency_exchange_account_id.id + else: + writeoff_acc_id = account.company_id.income_currency_exchange_account_id.id if not writeoff_acc_id: raise osv.except_osv(_('Warning!'), _('You have to provide an account for the write off/exchange difference entry.')) if writeoff > 0: @@ -1057,14 +1063,24 @@ class account_move_line(osv.osv): 'amount_currency': amount_currency_writeoff and amount_currency_writeoff or (account.currency_id.id and currency or 0.0) }) ] - - writeoff_move_id = move_obj.create(cr, uid, { - 'period_id': writeoff_period_id, - 'journal_id': writeoff_journal_id, - 'date':date, - 'state': 'draft', - 'line_id': writeoff_lines - }) + # DO NOT FORWARD PORT + # In some exceptional situations (partial payment from a bank statement in foreign + # currency), a write-off can be introduced at the very last moment due to currency + # conversion. We record it on the bank statement account move. + if context.get('bs_move_id'): + writeoff_move_id = context['bs_move_id'] + for l in writeoff_lines: + self.create(cr, uid, dict(l[2], move_id=writeoff_move_id), dict(context, novalidate=True)) + if not move_obj.validate(cr, uid, writeoff_move_id, context=context): + raise osv.except_osv(_('Error!'), _('You cannot validate a non-balanced entry.')) + else: + writeoff_move_id = move_obj.create(cr, uid, { + 'period_id': writeoff_period_id, + 'journal_id': writeoff_journal_id, + 'date':date, + 'state': 'draft', + 'line_id': writeoff_lines + }) writeoff_line_ids = self.search(cr, uid, [('move_id', '=', writeoff_move_id), ('account_id', '=', account_id)]) if account_id == writeoff_acc_id: