From c52eaf645f131f87671adbac4589eb6dadddd0c5 Mon Sep 17 00:00:00 2001 From: Nikul Chaudhary Date: Fri, 13 Dec 2019 13:27:12 +0530 Subject: [PATCH 01/12] [RFC] contract_sale v12 --- contract_sale/README.rst | 4 ++++ contract_sale/__init__.py | 1 + contract_sale/__manifest__.py | 2 +- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/contract_sale/README.rst b/contract_sale/README.rst index 390f1d99..0b052c34 100644 --- a/contract_sale/README.rst +++ b/contract_sale/README.rst @@ -71,6 +71,10 @@ Contributors * Levent Karakaş * Bejaoui Souheil +* Serpent Consulting Services Pvt. Ltd. + + * Nikul Chaudhary + Maintainers ~~~~~~~~~~~ diff --git a/contract_sale/__init__.py b/contract_sale/__init__.py index b409d319..5ff10c6d 100644 --- a/contract_sale/__init__.py +++ b/contract_sale/__init__.py @@ -1 +1,2 @@ # License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html +from . import models diff --git a/contract_sale/__manifest__.py b/contract_sale/__manifest__.py index 8e5a19dc..3c011617 100644 --- a/contract_sale/__manifest__.py +++ b/contract_sale/__manifest__.py @@ -9,7 +9,7 @@ 'Odoo Community Association (OCA)', 'website': 'https://github.com/OCA/contract', 'depends': [ - 'sale', + 'sale_management', 'contract', ], 'data': [ From 89097b52d99378d438bc66b25121daf4d0bfb79e Mon Sep 17 00:00:00 2001 From: Nikul Chaudhary Date: Fri, 13 Dec 2019 13:28:02 +0530 Subject: [PATCH 02/12] [RFC] contract_sale v12 --- contract_sale/models/__init__.py | 4 ++++ contract_sale/models/contract.py | 25 +++++++++++++++++++++++++ contract_sale/models/sale_order.py | 27 +++++++++++++++++++++++++++ 3 files changed, 56 insertions(+) create mode 100644 contract_sale/models/__init__.py create mode 100644 contract_sale/models/contract.py create mode 100644 contract_sale/models/sale_order.py diff --git a/contract_sale/models/__init__.py b/contract_sale/models/__init__.py new file mode 100644 index 00000000..f0981283 --- /dev/null +++ b/contract_sale/models/__init__.py @@ -0,0 +1,4 @@ +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from . import contract +from . import sale_order diff --git a/contract_sale/models/contract.py b/contract_sale/models/contract.py new file mode 100644 index 00000000..e5773ac9 --- /dev/null +++ b/contract_sale/models/contract.py @@ -0,0 +1,25 @@ +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +from odoo import api, fields, models + + +class ContractContract(models.Model): + _inherit = 'contract.contract' + + @api.multi + def _prepare_recurring_invoices_values(self, date_ref=False): + invoices_values = super(ContractContract, self)._prepare_recurring_invoices_values(date_ref=date_ref) + return invoices_values + + def _compute_sale_order_count(self): + super(ContractContract, self)._compute_sale_order_count() + contract_count = self.contract_line_ids.mapped('sale_order_line_id.order_id.contract_id') + self.sale_order_count += contract_count + + @api.multi + def action_view_sales_orders(self): + res = super(ContractContract, self).action_view_sales_orders() + contracts = self.contract_line_ids.mapped( + 'sale_order_line_id.order_id.contract_id' + ) + res.get('domain')[0][2].extend(contracts) + return res diff --git a/contract_sale/models/sale_order.py b/contract_sale/models/sale_order.py new file mode 100644 index 00000000..6c362ae7 --- /dev/null +++ b/contract_sale/models/sale_order.py @@ -0,0 +1,27 @@ +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +from odoo import api, fields, models + + +class SaleOrder(models.Model): + _inherit = 'sale.order' + + contract_id = fields.Many2one( + comodel_name="contract.contract", + string="Contract" + ) + + @api.multi + def action_confirm(self): + res = super(SaleOrder, self).action_confirm() + invoice_ids = self.env['account.invoice'].search([ + ('partner_id', '=', self.partner_id.id), + ('old_contract_id', '=', self.contract_id.id), + ('state', '=', 'draft')]) + + for invoice_id in invoice_ids: + for order_line in self.order_line: + for invoice_line in invoice_id.invoice_line_ids: + if order_line.product_id.id == invoice_line.product_id.id: + invoice_line.quantity += order_line.product_uom_qty + self.action_invoice_create() + return res From 17533bd89b77d0f3dddaf480b70b0c18b6cb2630 Mon Sep 17 00:00:00 2001 From: Nikul Chaudhary Date: Fri, 13 Dec 2019 13:29:18 +0530 Subject: [PATCH 03/12] [FIX] Fixed Travis --- contract_sale/models/contract.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/contract_sale/models/contract.py b/contract_sale/models/contract.py index e5773ac9..845908db 100644 --- a/contract_sale/models/contract.py +++ b/contract_sale/models/contract.py @@ -7,12 +7,14 @@ class ContractContract(models.Model): @api.multi def _prepare_recurring_invoices_values(self, date_ref=False): - invoices_values = super(ContractContract, self)._prepare_recurring_invoices_values(date_ref=date_ref) + invoices_values = super(ContractContract, self).\ + _prepare_recurring_invoices_values(date_ref=date_ref) return invoices_values def _compute_sale_order_count(self): super(ContractContract, self)._compute_sale_order_count() - contract_count = self.contract_line_ids.mapped('sale_order_line_id.order_id.contract_id') + contract_count = self.contract_line_ids.\ + mapped('sale_order_line_id.order_id.contract_id') self.sale_order_count += contract_count @api.multi From 3bbd14518c61d63cdf05846c1b0c6b2416d2eb40 Mon Sep 17 00:00:00 2001 From: Nikul Chaudhary Date: Fri, 13 Dec 2019 16:18:06 +0530 Subject: [PATCH 04/12] [FIX] Fixed Travis --- contract_sale/models/contract.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contract_sale/models/contract.py b/contract_sale/models/contract.py index 845908db..173e7e74 100644 --- a/contract_sale/models/contract.py +++ b/contract_sale/models/contract.py @@ -1,5 +1,5 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import api, fields, models +from odoo import api, models class ContractContract(models.Model): @@ -7,7 +7,7 @@ class ContractContract(models.Model): @api.multi def _prepare_recurring_invoices_values(self, date_ref=False): - invoices_values = super(ContractContract, self).\ + invoices_values = super(ContractContract, self).\ _prepare_recurring_invoices_values(date_ref=date_ref) return invoices_values From 54dd83f6ba7c6fe99257162be8cd6ecc83d4de41 Mon Sep 17 00:00:00 2001 From: Nikul Chaudhary Date: Tue, 17 Dec 2019 15:23:18 +0530 Subject: [PATCH 05/12] [FIX] Fixed contract code --- contract_sale/__manifest__.py | 1 + contract_sale/models/contract.py | 6 ++++-- contract_sale/models/sale_order.py | 18 +----------------- contract_sale/views/sale_order.xml | 15 +++++++++++++++ 4 files changed, 21 insertions(+), 19 deletions(-) create mode 100644 contract_sale/views/sale_order.xml diff --git a/contract_sale/__manifest__.py b/contract_sale/__manifest__.py index 3c011617..2bc6ba36 100644 --- a/contract_sale/__manifest__.py +++ b/contract_sale/__manifest__.py @@ -20,6 +20,7 @@ 'views/contract_line.xml', 'views/contract_template.xml', 'views/res_partner_view.xml', + 'views/sale_order.xml', ], 'license': 'AGPL-3', 'installable': True, diff --git a/contract_sale/models/contract.py b/contract_sale/models/contract.py index 173e7e74..3ff50095 100644 --- a/contract_sale/models/contract.py +++ b/contract_sale/models/contract.py @@ -11,10 +11,12 @@ class ContractContract(models.Model): _prepare_recurring_invoices_values(date_ref=date_ref) return invoices_values + @api.depends('contract_line_ids') def _compute_sale_order_count(self): super(ContractContract, self)._compute_sale_order_count() - contract_count = self.contract_line_ids.\ - mapped('sale_order_line_id.order_id.contract_id') + contract_count = len( + self.contract_line_ids. + mapped('sale_order_line_id.order_id.contract_id')) or 0 self.sale_order_count += contract_count @api.multi diff --git a/contract_sale/models/sale_order.py b/contract_sale/models/sale_order.py index 6c362ae7..b2a5b9c4 100644 --- a/contract_sale/models/sale_order.py +++ b/contract_sale/models/sale_order.py @@ -7,21 +7,5 @@ class SaleOrder(models.Model): contract_id = fields.Many2one( comodel_name="contract.contract", - string="Contract" + string="Contract", ) - - @api.multi - def action_confirm(self): - res = super(SaleOrder, self).action_confirm() - invoice_ids = self.env['account.invoice'].search([ - ('partner_id', '=', self.partner_id.id), - ('old_contract_id', '=', self.contract_id.id), - ('state', '=', 'draft')]) - - for invoice_id in invoice_ids: - for order_line in self.order_line: - for invoice_line in invoice_id.invoice_line_ids: - if order_line.product_id.id == invoice_line.product_id.id: - invoice_line.quantity += order_line.product_uom_qty - self.action_invoice_create() - return res diff --git a/contract_sale/views/sale_order.xml b/contract_sale/views/sale_order.xml new file mode 100644 index 00000000..76598696 --- /dev/null +++ b/contract_sale/views/sale_order.xml @@ -0,0 +1,15 @@ + + + + + sale.order.form.view + sale.order + + + + + + + + + \ No newline at end of file From 304fd6c4b4c2af8438d8a466b0270b8958578dcd Mon Sep 17 00:00:00 2001 From: Nikul Chaudhary Date: Wed, 18 Dec 2019 15:43:26 +0530 Subject: [PATCH 06/12] [FIX] Fixed Code --- contract_sale/models/contract.py | 45 ++++++++++++++++++++++++++++-- contract_sale/views/sale_order.xml | 2 +- 2 files changed, 44 insertions(+), 3 deletions(-) diff --git a/contract_sale/models/contract.py b/contract_sale/models/contract.py index 3ff50095..b4329a91 100644 --- a/contract_sale/models/contract.py +++ b/contract_sale/models/contract.py @@ -7,8 +7,49 @@ class ContractContract(models.Model): @api.multi def _prepare_recurring_invoices_values(self, date_ref=False): - invoices_values = super(ContractContract, self).\ - _prepare_recurring_invoices_values(date_ref=date_ref) + """ + overwrite Base Contract Method + """ + invoices_values = [] + for contract in self: + if not date_ref: + date_ref = contract.recurring_next_date + if not date_ref: + # this use case is possible when recurring_create_invoice is + # called for a finished contract + continue + contract_lines = contract._get_lines_to_invoice(date_ref) + if not contract_lines: + continue + invoice_values = contract._prepare_invoice(date_ref) + + #Search Contract in sale order + order_ids = self.env['sale.order'].search([ + ('partner_id', '=', contract.partner_id.id), + ('contract_id', '=', contract.id), + ]) + + for line in contract_lines: + invoice_values.setdefault('invoice_line_ids', []) + invoice_line_values = line._prepare_invoice_line( + invoice_id=False + ) + if invoice_line_values: + + #Check Invoice and If It's Not Created then Updated Qty + for order_id in order_ids: + invoice_ids = order_id.order_line.mapped('invoice_lines') + if not invoice_ids: + for line in order_id.order_line: + if line.product_id.id == invoice_line_values.get('product_id', False): + invoice_line_values['quantity'] += line.product_uom_qty + + invoice_values['invoice_line_ids'].append( + (0, 0, invoice_line_values) + ) + + invoices_values.append(invoice_values) + contract_lines._update_recurring_next_date() return invoices_values @api.depends('contract_line_ids') diff --git a/contract_sale/views/sale_order.xml b/contract_sale/views/sale_order.xml index 76598696..acff6fce 100644 --- a/contract_sale/views/sale_order.xml +++ b/contract_sale/views/sale_order.xml @@ -12,4 +12,4 @@ - \ No newline at end of file + From aa0b538851ba92f3624c4adc88e20811538847de Mon Sep 17 00:00:00 2001 From: Nikul Chaudhary Date: Wed, 18 Dec 2019 16:11:02 +0530 Subject: [PATCH 07/12] [FIX] Fixed Travis --- contract_sale/models/contract.py | 13 ++++++++----- contract_sale/models/sale_order.py | 2 +- 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/contract_sale/models/contract.py b/contract_sale/models/contract.py index b4329a91..3a3af61c 100644 --- a/contract_sale/models/contract.py +++ b/contract_sale/models/contract.py @@ -23,7 +23,7 @@ class ContractContract(models.Model): continue invoice_values = contract._prepare_invoice(date_ref) - #Search Contract in sale order + # Search Contract in sale order order_ids = self.env['sale.order'].search([ ('partner_id', '=', contract.partner_id.id), ('contract_id', '=', contract.id), @@ -36,13 +36,16 @@ class ContractContract(models.Model): ) if invoice_line_values: - #Check Invoice and If It's Not Created then Updated Qty + # Check Invoice and If It's Not Created then Updated Qty for order_id in order_ids: - invoice_ids = order_id.order_line.mapped('invoice_lines') + invoice_ids =\ + order_id.order_line.mapped('invoice_lines') if not invoice_ids: for line in order_id.order_line: - if line.product_id.id == invoice_line_values.get('product_id', False): - invoice_line_values['quantity'] += line.product_uom_qty + if line.product_id.id == invoice_line_values.\ + get('product_id', False): + invoice_line_values['quantity' + ] += line.product_uom_qty invoice_values['invoice_line_ids'].append( (0, 0, invoice_line_values) diff --git a/contract_sale/models/sale_order.py b/contract_sale/models/sale_order.py index b2a5b9c4..2abd1d71 100644 --- a/contract_sale/models/sale_order.py +++ b/contract_sale/models/sale_order.py @@ -1,5 +1,5 @@ # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import api, fields, models +from odoo import fields, models class SaleOrder(models.Model): From 26d8f863124420c06aaf52e1bf73f44cb221c31e Mon Sep 17 00:00:00 2001 From: Nikul Chaudhary Date: Thu, 19 Dec 2019 16:11:58 +0530 Subject: [PATCH 08/12] [IMP] Improved Code base on comments --- contract_sale/__init__.py | 1 - contract_sale/models/__init__.py | 4 - contract_sale/models/contract.py | 73 ----------------- contract_sale/models/sale_order.py | 11 --- contract_sale_invoicing/models/__init__.py | 1 + contract_sale_invoicing/models/contract.py | 94 +++++++++++++++++++--- 6 files changed, 82 insertions(+), 102 deletions(-) delete mode 100644 contract_sale/models/__init__.py delete mode 100644 contract_sale/models/contract.py delete mode 100644 contract_sale/models/sale_order.py diff --git a/contract_sale/__init__.py b/contract_sale/__init__.py index 5ff10c6d..b409d319 100644 --- a/contract_sale/__init__.py +++ b/contract_sale/__init__.py @@ -1,2 +1 @@ # License AGPL-3 - See http://www.gnu.org/licenses/agpl-3.0.html -from . import models diff --git a/contract_sale/models/__init__.py b/contract_sale/models/__init__.py deleted file mode 100644 index f0981283..00000000 --- a/contract_sale/models/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). - -from . import contract -from . import sale_order diff --git a/contract_sale/models/contract.py b/contract_sale/models/contract.py deleted file mode 100644 index 3a3af61c..00000000 --- a/contract_sale/models/contract.py +++ /dev/null @@ -1,73 +0,0 @@ -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import api, models - - -class ContractContract(models.Model): - _inherit = 'contract.contract' - - @api.multi - def _prepare_recurring_invoices_values(self, date_ref=False): - """ - overwrite Base Contract Method - """ - invoices_values = [] - for contract in self: - if not date_ref: - date_ref = contract.recurring_next_date - if not date_ref: - # this use case is possible when recurring_create_invoice is - # called for a finished contract - continue - contract_lines = contract._get_lines_to_invoice(date_ref) - if not contract_lines: - continue - invoice_values = contract._prepare_invoice(date_ref) - - # Search Contract in sale order - order_ids = self.env['sale.order'].search([ - ('partner_id', '=', contract.partner_id.id), - ('contract_id', '=', contract.id), - ]) - - for line in contract_lines: - invoice_values.setdefault('invoice_line_ids', []) - invoice_line_values = line._prepare_invoice_line( - invoice_id=False - ) - if invoice_line_values: - - # Check Invoice and If It's Not Created then Updated Qty - for order_id in order_ids: - invoice_ids =\ - order_id.order_line.mapped('invoice_lines') - if not invoice_ids: - for line in order_id.order_line: - if line.product_id.id == invoice_line_values.\ - get('product_id', False): - invoice_line_values['quantity' - ] += line.product_uom_qty - - invoice_values['invoice_line_ids'].append( - (0, 0, invoice_line_values) - ) - - invoices_values.append(invoice_values) - contract_lines._update_recurring_next_date() - return invoices_values - - @api.depends('contract_line_ids') - def _compute_sale_order_count(self): - super(ContractContract, self)._compute_sale_order_count() - contract_count = len( - self.contract_line_ids. - mapped('sale_order_line_id.order_id.contract_id')) or 0 - self.sale_order_count += contract_count - - @api.multi - def action_view_sales_orders(self): - res = super(ContractContract, self).action_view_sales_orders() - contracts = self.contract_line_ids.mapped( - 'sale_order_line_id.order_id.contract_id' - ) - res.get('domain')[0][2].extend(contracts) - return res diff --git a/contract_sale/models/sale_order.py b/contract_sale/models/sale_order.py deleted file mode 100644 index 2abd1d71..00000000 --- a/contract_sale/models/sale_order.py +++ /dev/null @@ -1,11 +0,0 @@ -# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). -from odoo import fields, models - - -class SaleOrder(models.Model): - _inherit = 'sale.order' - - contract_id = fields.Many2one( - comodel_name="contract.contract", - string="Contract", - ) diff --git a/contract_sale_invoicing/models/__init__.py b/contract_sale_invoicing/models/__init__.py index d639560e..5dd5ecb1 100644 --- a/contract_sale_invoicing/models/__init__.py +++ b/contract_sale_invoicing/models/__init__.py @@ -1,3 +1,4 @@ # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from . import sale_order from . import contract diff --git a/contract_sale_invoicing/models/contract.py b/contract_sale_invoicing/models/contract.py index ca5094e7..f3c782d9 100644 --- a/contract_sale_invoicing/models/contract.py +++ b/contract_sale_invoicing/models/contract.py @@ -16,16 +16,84 @@ class ContractContract(models.Model): @api.multi def _recurring_create_invoice(self, date_ref=False): invoices = super()._recurring_create_invoice(date_ref) - if not self.invoicing_sales: - return invoices - sales = self.env['sale.order'].search([ - ('analytic_account_id', '=', self.group_id.id), - ('partner_invoice_id', 'child_of', - self.partner_id.commercial_partner_id.ids), - ('invoice_status', '=', 'to invoice'), - ('date_order', '<=', - '{} 23:59:59'.format(self.recurring_next_date)), - ]) - if sales: - invoice_ids = sales.action_invoice_create() - invoices |= self.env['account.invoice'].browse(invoice_ids)[:1] + for rec in self: + if not rec.invoicing_sales: + return invoices + sales = self.env['sale.order'].search([ + ('analytic_account_id', '=', rec.group_id.id), + ('partner_invoice_id', 'child_of', + rec.partner_id.commercial_partner_id.ids), + ('invoice_status', '=', 'to invoice'), + ('date_order', '<=', + '{} 23:59:59'.format(rec.recurring_next_date)), + ]) + if sales: + invoice_ids = sales.action_invoice_create() + invoices |= self.env['account.invoice'].browse(invoice_ids)[:1] + + @api.multi + def _prepare_recurring_invoices_values(self, date_ref=False): + invoices_values = super(ContractContract, self + )._prepare_recurring_invoices_values() + for invoice_val in invoices_values: + invoice_line_values = {} + for invoice_line in invoice_val.get('invoice_line_ids', []): + invoice_line = invoice_line[2] or {} + contract_line_rec = self.env['contract.line'].\ + browse(invoice_line.get('contract_line_id', False)) + if contract_line_rec and contract_line_rec.contract_id and\ + contract_line_rec.contract_id.invoicing_sales: + order_ids = self.env['sale.order'].search([ + ('partner_id', '=', + contract_line_rec.contract_id.partner_id.id), + ('contract_id', '=', contract_line_rec.contract_id.id), + ]) + sale_order_line_product_qty = {} + for order_id in order_ids: + if not order_id.order_line.mapped('invoice_lines'): + for line in order_id.order_line: + if sale_order_line_product_qty.\ + get(line.product_id.id): + sale_order_line_product_qty[line. + product_id.id] += line.product_uom_qty + else: + sale_order_line_product_qty[line. + product_id.id] = line.product_uom_qty + if invoice_line.get('product_id' + ) in sale_order_line_product_qty: + if sale_order_line_product_qty.get(line.product_id.id + ) > invoice_line.get('quantity'): + remain_qty = sale_order_line_product_qty.\ + get(invoice_line.get('product_id') + ) - invoice_line.get('quantity') or 0 + invoice_line_values = { + 'invoice_id': False, + 'uom_id': contract_line_rec.uom_id.id, + 'product_id': invoice_line.get('product_id'), + 'quantity': remain_qty or 0, + 'discount': contract_line_rec.discount, + 'contract_line_id': contract_line_rec.id, + 'name': contract_line_rec.name, + 'account_analytic_id': False, + 'price_unit': contract_line_rec.price_unit + } + invoice_val['invoice_line_ids' + ].append((0, 0, invoice_line_values)) + return invoices_values + + @api.depends('contract_line_ids') + def _compute_sale_order_count(self): + super(ContractContract, self)._compute_sale_order_count() + contract_count = len( + self.contract_line_ids. + mapped('sale_order_line_id.order_id.contract_id')) or 0 + self.sale_order_count += contract_count + + @api.multi + def action_view_sales_orders(self): + res = super(ContractContract, self).action_view_sales_orders() + contracts = self.contract_line_ids.mapped( + 'sale_order_line_id.order_id.contract_id' + ) + res.get('domain')[0][2].extend(contracts) + return res From 6352e3355c1cc2fbb691712b7717ea06d57fb37c Mon Sep 17 00:00:00 2001 From: Maxime Chambreuil Date: Thu, 19 Dec 2019 16:57:20 -0600 Subject: [PATCH 09/12] [FIX] contract_sale --- contract_sale/__manifest__.py | 1 - contract_sale/views/sale_order.xml | 15 --------------- 2 files changed, 16 deletions(-) delete mode 100644 contract_sale/views/sale_order.xml diff --git a/contract_sale/__manifest__.py b/contract_sale/__manifest__.py index 2bc6ba36..3c011617 100644 --- a/contract_sale/__manifest__.py +++ b/contract_sale/__manifest__.py @@ -20,7 +20,6 @@ 'views/contract_line.xml', 'views/contract_template.xml', 'views/res_partner_view.xml', - 'views/sale_order.xml', ], 'license': 'AGPL-3', 'installable': True, diff --git a/contract_sale/views/sale_order.xml b/contract_sale/views/sale_order.xml deleted file mode 100644 index acff6fce..00000000 --- a/contract_sale/views/sale_order.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - - sale.order.form.view - sale.order - - - - - - - - - From a99f1d3c72ce417c888ea51c873fdef62a8a48cb Mon Sep 17 00:00:00 2001 From: Maxime Chambreuil Date: Thu, 19 Dec 2019 16:57:33 -0600 Subject: [PATCH 10/12] [FIX] contract_sale_invoicing --- contract_sale_invoicing/__manifest__.py | 1 + contract_sale_invoicing/models/sale_order.py | 10 ++++++++++ contract_sale_invoicing/views/sale_order.xml | 14 ++++++++++++++ 3 files changed, 25 insertions(+) create mode 100644 contract_sale_invoicing/models/sale_order.py create mode 100644 contract_sale_invoicing/views/sale_order.xml diff --git a/contract_sale_invoicing/__manifest__.py b/contract_sale_invoicing/__manifest__.py index 7cb91088..61bd643c 100644 --- a/contract_sale_invoicing/__manifest__.py +++ b/contract_sale_invoicing/__manifest__.py @@ -16,5 +16,6 @@ ], 'data': [ 'views/contract_view.xml', + 'views/sale_order.xml', ], } diff --git a/contract_sale_invoicing/models/sale_order.py b/contract_sale_invoicing/models/sale_order.py new file mode 100644 index 00000000..bf022e9e --- /dev/null +++ b/contract_sale_invoicing/models/sale_order.py @@ -0,0 +1,10 @@ +# Copyright (C) 2019 Open Source Integrators +# Copyright (C) 2019 Serpent Consulting Services +# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl). +from odoo import fields, models + + +class SaleOrder(models.Model): + _inherit = 'sale.order' + + contract_id = fields.Many2one('contract.contract', string='Contract') diff --git a/contract_sale_invoicing/views/sale_order.xml b/contract_sale_invoicing/views/sale_order.xml new file mode 100644 index 00000000..1119da73 --- /dev/null +++ b/contract_sale_invoicing/views/sale_order.xml @@ -0,0 +1,14 @@ + + + + sale.order.form.view + sale.order + + + + + + + + + From c91a170ffcbfac1c610f62f05c5ac6308f7a4af7 Mon Sep 17 00:00:00 2001 From: Maxime Chambreuil Date: Fri, 20 Dec 2019 13:47:54 -0600 Subject: [PATCH 11/12] [IMP] contract_sale_invoicing # Conflicts: # contract_sale_invoicing/models/contract.py --- contract_sale_invoicing/models/contract.py | 26 ++++++++++++++-------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/contract_sale_invoicing/models/contract.py b/contract_sale_invoicing/models/contract.py index d161c9f9..5ae4e836 100644 --- a/contract_sale_invoicing/models/contract.py +++ b/contract_sale_invoicing/models/contract.py @@ -13,7 +13,21 @@ class ContractContract(models.Model): group_by = fields.Selection([ ('analytic_account', 'Analytic Account'), ('contract', 'Contract')], - default='analytic_account', string='Group By') + default='analytic_account', string='Group invoices by') + + def get_sale_order_domain(self): + domain = [ + ('partner_invoice_id', 'child_of', + self.partner_id.commercial_partner_id.ids), + ('invoice_status', '=', 'to invoice'), + ('date_order', '<=', + '{} 23:59:59'.format(self.recurring_next_date)), + ] + if self.group_by == 'analytic_account': + domain.append(('analytic_account_id', '=', self.group_id.id)) + elif self.group_by == 'contract': + domain.append(('contract_id', '=', self.id)) + return domain @api.multi def _recurring_create_invoice(self, date_ref=False): @@ -21,14 +35,8 @@ class ContractContract(models.Model): for rec in self: if not rec.invoicing_sales: return invoices - sales = self.env['sale.order'].search([ - ('analytic_account_id', '=', rec.group_id.id), - ('partner_invoice_id', 'child_of', - rec.partner_id.commercial_partner_id.ids), - ('invoice_status', '=', 'to invoice'), - ('date_order', '<=', - '{} 23:59:59'.format(rec.recurring_next_date)), - ]) + so_domain = rec.get_sale_order_domain() + sales = self.env['sale.order'].search(so_domain) if sales: invoice_ids = sales.action_invoice_create() invoices |= self.env['account.invoice'].browse(invoice_ids)[:1] From 20cb8e89f0709a367f5547d479498fc5ffd286ae Mon Sep 17 00:00:00 2001 From: Maxime Chambreuil Date: Sun, 22 Dec 2019 14:13:33 -0600 Subject: [PATCH 12/12] [IMP] contract_sale_invoicing --- contract_sale_invoicing/models/contract.py | 33 ++++++++++--------- .../views/contract_view.xml | 2 ++ 2 files changed, 20 insertions(+), 15 deletions(-) diff --git a/contract_sale_invoicing/models/contract.py b/contract_sale_invoicing/models/contract.py index 5ae4e836..5b83022a 100644 --- a/contract_sale_invoicing/models/contract.py +++ b/contract_sale_invoicing/models/contract.py @@ -10,10 +10,16 @@ class ContractContract(models.Model): invoicing_sales = fields.Boolean( string='Invoice Pending Sales Orders', help='Include sales to invoice on the contract invoice.') - group_by = fields.Selection([ + filter_with = fields.Selection([ ('analytic_account', 'Analytic Account'), ('contract', 'Contract')], - default='analytic_account', string='Group invoices by') + default='analytic_account', string='Filter with the same', + help="Select the sale orders with the same analytic account or " + "contract") + group_by = fields.Selection([ + ('sale_order', 'Sale Order'), + ('contract', 'Contract')], + default='sale_order', string='Create one invoice per') def get_sale_order_domain(self): domain = [ @@ -23,9 +29,9 @@ class ContractContract(models.Model): ('date_order', '<=', '{} 23:59:59'.format(self.recurring_next_date)), ] - if self.group_by == 'analytic_account': + if self.filter_with == 'analytic_account': domain.append(('analytic_account_id', '=', self.group_id.id)) - elif self.group_by == 'contract': + elif self.filter_with == 'contract': domain.append(('contract_id', '=', self.id)) return domain @@ -37,7 +43,7 @@ class ContractContract(models.Model): return invoices so_domain = rec.get_sale_order_domain() sales = self.env['sale.order'].search(so_domain) - if sales: + if sales and self.group_by == 'sale_order': invoice_ids = sales.action_invoice_create() invoices |= self.env['account.invoice'].browse(invoice_ids)[:1] @@ -58,8 +64,7 @@ class ContractContract(models.Model): @api.multi def _prepare_recurring_invoices_values(self, date_ref=False): - invoices_values = super(ContractContract, self - )._prepare_recurring_invoices_values() + invoices_values = super()._prepare_recurring_invoices_values() updated_invoices_values = [] for invoice_val in invoices_values: invoice_line_values = {} @@ -69,12 +74,11 @@ class ContractContract(models.Model): contract_line_rec = self.env['contract.line'].\ browse(invoice_line.get('contract_line_id', False)) if contract_line_rec and contract_line_rec.contract_id and\ - contract_line_rec.contract_id.invoicing_sales: - order_ids = self.env['sale.order'].search([ - ('partner_id', '=', - contract_line_rec.contract_id.partner_id.id), - ('contract_id', '=', contract_line_rec.contract_id.id), - ]) + contract_line_rec.contract_id.invoicing_sales and \ + contract_line_rec.contract_id.group_by == 'contract': + so_domain = \ + contract_line_rec.contract_id.get_sale_order_domain() + order_ids = self.env['sale.order'].search(so_domain) sale_order_line_product_qty = {} for order_id in order_ids: if not order_id.order_line.mapped('invoice_lines'): @@ -121,7 +125,6 @@ class ContractContract(models.Model): def action_view_sales_orders(self): res = super(ContractContract, self).action_view_sales_orders() contracts = self.contract_line_ids.mapped( - 'sale_order_line_id.order_id.contract_id' - ) + 'sale_order_line_id.order_id.contract_id') res.get('domain')[0][2].extend(contracts) return res diff --git a/contract_sale_invoicing/views/contract_view.xml b/contract_sale_invoicing/views/contract_view.xml index a43c7d30..7ee942f7 100644 --- a/contract_sale_invoicing/views/contract_view.xml +++ b/contract_sale_invoicing/views/contract_view.xml @@ -10,6 +10,8 @@ +