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.

118 lines
4.4 KiB

  1. # Copyright 2017 LasLabs Inc.
  2. # Copyright 2018 ACSONE SA/NV.
  3. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
  4. from odoo import fields, api, models
  5. class SaleOrder(models.Model):
  6. _inherit = 'sale.order'
  7. is_contract = fields.Boolean(
  8. string='Is a contract', compute='_compute_is_contract'
  9. )
  10. contract_count = fields.Integer(compute='_compute_contract_count')
  11. need_contract_creation = fields.Boolean(
  12. compute='_compute_need_contract_creation'
  13. )
  14. @api.depends('order_line.contract_id', 'state')
  15. def _compute_need_contract_creation(self):
  16. for rec in self:
  17. if rec.state in ('sale', 'done'):
  18. line_to_create_contract = rec.order_line.filtered(
  19. lambda r: not r.contract_id and r.product_id.is_contract
  20. )
  21. line_to_update_contract = rec.order_line.filtered(
  22. lambda r: r.contract_id
  23. and r.product_id.is_contract
  24. and r
  25. not in r.contract_id.contract_line_ids.mapped(
  26. 'sale_order_line_id'
  27. )
  28. )
  29. if line_to_create_contract or line_to_update_contract:
  30. rec.need_contract_creation = True
  31. @api.depends('order_line')
  32. def _compute_is_contract(self):
  33. self.is_contract = any(self.order_line.mapped('is_contract'))
  34. @api.multi
  35. def _prepare_contract_value(self, contract_template):
  36. self.ensure_one()
  37. return {
  38. 'name': '{template_name}: {sale_name}'.format(
  39. template_name=contract_template.name, sale_name=self.name
  40. ),
  41. 'partner_id': self.partner_id.id,
  42. 'contract_template_id': contract_template.id,
  43. 'user_id': self.user_id.id,
  44. 'payment_term_id': self.payment_term_id.id,
  45. 'fiscal_position_id': self.fiscal_position_id.id,
  46. 'invoice_partner_id': self.partner_invoice_id.id,
  47. }
  48. @api.multi
  49. def action_create_contract(self):
  50. contract_model = self.env['contract.contract']
  51. contracts = self.env['contract.contract']
  52. for rec in self.filtered('is_contract'):
  53. line_to_create_contract = rec.order_line.filtered(
  54. lambda r: not r.contract_id and r.product_id.is_contract
  55. )
  56. line_to_update_contract = rec.order_line.filtered(
  57. lambda r: r.contract_id
  58. and r.product_id.is_contract
  59. and r
  60. not in r.contract_id.contract_line_ids.mapped(
  61. 'sale_order_line_id'
  62. )
  63. )
  64. for contract_template in line_to_create_contract.mapped(
  65. 'product_id.contract_template_id'
  66. ):
  67. order_lines = line_to_create_contract.filtered(
  68. lambda r, template=contract_template:
  69. r.product_id.contract_template_id == template
  70. )
  71. contract = contract_model.create(
  72. rec._prepare_contract_value(contract_template)
  73. )
  74. contracts |= contract
  75. contract._onchange_contract_template_id()
  76. order_lines.create_contract_line(contract)
  77. order_lines.write({'contract_id': contract.id})
  78. for line in line_to_update_contract:
  79. line.create_contract_line(line.contract_id)
  80. return contracts
  81. @api.multi
  82. def action_confirm(self):
  83. """ If we have a contract in the order, set it up """
  84. self.filtered(
  85. lambda order: (
  86. order.company_id.create_contract_at_sale_order_confirmation
  87. )
  88. ).action_create_contract()
  89. return super(SaleOrder, self).action_confirm()
  90. @api.multi
  91. @api.depends("order_line")
  92. def _compute_contract_count(self):
  93. for rec in self:
  94. rec.contract_count = len(rec.order_line.mapped('contract_id'))
  95. @api.multi
  96. def action_show_contracts(self):
  97. self.ensure_one()
  98. action = self.env.ref(
  99. "contract.action_customer_contract"
  100. ).read()[0]
  101. contracts = (
  102. self.env['contract.line']
  103. .search([('sale_order_line_id', 'in', self.order_line.ids)])
  104. .mapped('contract_id')
  105. )
  106. action["domain"] = [("id", "in", contracts.ids)]
  107. return action