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.

116 lines
4.2 KiB

  1. # -*- coding: utf-8 -*-
  2. # Copyright 2017 LasLabs Inc.
  3. # Copyright 2017 ACSONE SA/NV.
  4. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html).
  5. from odoo import api, fields, models, _
  6. from odoo.exceptions import ValidationError
  7. class SaleOrderLine(models.Model):
  8. _inherit = 'sale.order.line'
  9. is_contract = fields.Boolean(
  10. string='Is a contract', related="product_id.is_contract"
  11. )
  12. contract_id = fields.Many2one(
  13. comodel_name='account.analytic.account', string='Contract', copy=False
  14. )
  15. contract_template_id = fields.Many2one(
  16. comodel_name='account.analytic.contract',
  17. string='Contract Template',
  18. related='product_id.product_tmpl_id.contract_template_id',
  19. readonly=True
  20. )
  21. recurring_rule_type = fields.Selection(
  22. [
  23. ('daily', 'Day(s)'),
  24. ('weekly', 'Week(s)'),
  25. ('monthly', 'Month(s)'),
  26. ('monthlylastday', 'Month(s) last day'),
  27. ('yearly', 'Year(s)'),
  28. ],
  29. default='monthly',
  30. string='Recurrence',
  31. help="Specify Interval for automatic invoice generation.",
  32. copy=False,
  33. )
  34. recurring_invoicing_type = fields.Selection(
  35. [('pre-paid', 'Pre-paid'), ('post-paid', 'Post-paid')],
  36. default='pre-paid',
  37. string='Invoicing type',
  38. help="Specify if process date is 'from' or 'to' invoicing date",
  39. copy=False,
  40. )
  41. recurring_interval = fields.Integer(
  42. default=1,
  43. string='Repeat Every',
  44. help="Repeat every (Days/Week/Month/Year)",
  45. copy=False,
  46. )
  47. date_start = fields.Date(string='Date Start', default=fields.Date.today())
  48. date_end = fields.Date(string='Date End', index=True)
  49. recurring_next_date = fields.Date(
  50. default=fields.Date.today(), copy=False, string='Date of Next Invoice'
  51. )
  52. @api.onchange('product_id')
  53. def onchange_product(self):
  54. if self.product_id.is_contract:
  55. self.recurring_rule_type = self.product_id.recurring_rule_type
  56. self.recurring_invoicing_type = (
  57. self.product_id.recurring_invoicing_type
  58. )
  59. self.recurring_interval = self.product_id.recurring_interval
  60. @api.multi
  61. def _prepare_contract_line_values(self, contract):
  62. self.ensure_one()
  63. return {
  64. 'sequence': self.sequence,
  65. 'product_id': self.product_id.id,
  66. 'name': self.name,
  67. 'quantity': self.product_uom_qty,
  68. 'uom_id': self.product_uom.id,
  69. 'price_unit': self.price_unit,
  70. 'discount': self.discount,
  71. 'recurring_next_date': self.recurring_next_date
  72. or fields.Date.today(),
  73. 'date_end': self.date_end,
  74. 'date_start': self.date_start or fields.Date.today(),
  75. 'recurring_interval': self.recurring_interval,
  76. 'recurring_invoicing_type': self.recurring_invoicing_type,
  77. 'recurring_rule_type': self.recurring_rule_type,
  78. 'contract_id': contract.id,
  79. 'sale_order_line_id': self.id,
  80. }
  81. @api.multi
  82. def create_contract_line(self, contract):
  83. contract_line = self.env['account.analytic.invoice.line']
  84. for rec in self:
  85. contract_line.create(rec._prepare_contract_line_values(contract))
  86. @api.constrains('contract_id')
  87. def _check_contract_sale_partner(self):
  88. for rec in self:
  89. if rec.contract_id:
  90. if rec.order_id.partner_id != rec.contract_id.partner_id:
  91. raise ValidationError(
  92. _(
  93. "Sale Order and contract should be "
  94. "linked to the same partner"
  95. )
  96. )
  97. @api.constrains('product_id', 'contract_id')
  98. def _check_contract_sale_contract_template(self):
  99. for rec in self:
  100. if rec.contract_id:
  101. if (
  102. rec.contract_template_id
  103. != rec.contract_id.contract_template_id
  104. ):
  105. raise ValidationError(
  106. _("Contract product has different contract template")
  107. )