You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

127 lines
5.8 KiB

  1. # Copyright 2018 Tecnativa - Carlos Dauden
  2. # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl).
  3. from odoo import api, fields, models
  4. class ContractContract(models.Model):
  5. _inherit = 'contract.contract'
  6. invoicing_sales = fields.Boolean(
  7. string='Invoice Pending Sales Orders',
  8. help='Include sales to invoice on the contract invoice.')
  9. group_by = fields.Selection([
  10. ('analytic_account', 'Analytic Account'),
  11. ('contract', 'Contract')],
  12. default='analytic_account', string='Group invoices by')
  13. def get_sale_order_domain(self):
  14. domain = [
  15. ('partner_invoice_id', 'child_of',
  16. self.partner_id.commercial_partner_id.ids),
  17. ('invoice_status', '=', 'to invoice'),
  18. ('date_order', '<=',
  19. '{} 23:59:59'.format(self.recurring_next_date)),
  20. ]
  21. if self.group_by == 'analytic_account':
  22. domain.append(('analytic_account_id', '=', self.group_id.id))
  23. elif self.group_by == 'contract':
  24. domain.append(('contract_id', '=', self.id))
  25. return domain
  26. @api.multi
  27. def _recurring_create_invoice(self, date_ref=False):
  28. invoices = super()._recurring_create_invoice(date_ref)
  29. for rec in self:
  30. if not rec.invoicing_sales:
  31. return invoices
  32. so_domain = rec.get_sale_order_domain()
  33. sales = self.env['sale.order'].search(so_domain)
  34. if sales:
  35. invoice_ids = sales.action_invoice_create()
  36. invoices |= self.env['account.invoice'].browse(invoice_ids)[:1]
  37. @api.multi
  38. def _prepare_invoice_line_dict(self, contract_line_rec, invoice_line,
  39. remain_qty):
  40. return {
  41. 'invoice_id': False,
  42. 'uom_id': contract_line_rec.uom_id.id,
  43. 'product_id': invoice_line.get('product_id'),
  44. 'quantity': remain_qty or 0,
  45. 'discount': contract_line_rec.discount,
  46. 'contract_line_id': contract_line_rec.id,
  47. 'name': contract_line_rec.name,
  48. 'account_analytic_id': False,
  49. 'price_unit': contract_line_rec.price_unit
  50. }
  51. @api.multi
  52. def _prepare_recurring_invoices_values(self, date_ref=False):
  53. invoices_values = super(ContractContract, self
  54. )._prepare_recurring_invoices_values()
  55. updated_invoices_values = []
  56. for invoice_val in invoices_values:
  57. invoice_line_values = {}
  58. invoice_line_list = []
  59. for invoice_line in invoice_val.get('invoice_line_ids', []):
  60. invoice_line = invoice_line[2] or {}
  61. contract_line_rec = self.env['contract.line'].\
  62. browse(invoice_line.get('contract_line_id', False))
  63. if contract_line_rec and contract_line_rec.contract_id and\
  64. contract_line_rec.contract_id.invoicing_sales:
  65. order_ids = self.env['sale.order'].search([
  66. ('partner_id', '=',
  67. contract_line_rec.contract_id.partner_id.id),
  68. ('contract_id', '=', contract_line_rec.contract_id.id),
  69. ])
  70. sale_order_line_product_qty = {}
  71. for order_id in order_ids:
  72. if not order_id.order_line.mapped('invoice_lines'):
  73. for line in order_id.order_line:
  74. if sale_order_line_product_qty.\
  75. get(line.product_id.id):
  76. sale_order_line_product_qty[
  77. line.product_id.id
  78. ] += line.product_uom_qty
  79. else:
  80. sale_order_line_product_qty[
  81. line.product_id.id
  82. ] = line.product_uom_qty
  83. if invoice_line.get('product_id'
  84. ) in sale_order_line_product_qty:
  85. if sale_order_line_product_qty.\
  86. get(line.product_id.id
  87. ) > invoice_line.get('quantity'):
  88. remain_qty = sale_order_line_product_qty.\
  89. get(invoice_line.get('product_id')
  90. ) - invoice_line.get('quantity') or 0
  91. invoice_line_values =\
  92. self._prepare_invoice_line_dict(
  93. contract_line_rec, invoice_line, remain_qty
  94. ) or {}
  95. invoice_line_list.append(invoice_line_values)
  96. sale_order_line_product_qty.\
  97. pop(invoice_line.get('product_id'))
  98. invoice_val['invoice_line_ids'] +=\
  99. [(0, 0, invoice_line_val
  100. )for invoice_line_val in invoice_line_list]
  101. updated_invoices_values.append(invoice_val)
  102. return updated_invoices_values
  103. @api.depends('contract_line_ids')
  104. def _compute_sale_order_count(self):
  105. super(ContractContract, self)._compute_sale_order_count()
  106. contract_count = len(
  107. self.contract_line_ids.
  108. mapped('sale_order_line_id.order_id.contract_id')) or 0
  109. self.sale_order_count += contract_count
  110. @api.multi
  111. def action_view_sales_orders(self):
  112. res = super(ContractContract, self).action_view_sales_orders()
  113. contracts = self.contract_line_ids.mapped(
  114. 'sale_order_line_id.order_id.contract_id'
  115. )
  116. res.get('domain')[0][2].extend(contracts)
  117. return res