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.

131 lines
4.8 KiB

  1. # -*- coding: utf-8 -*-
  2. # © 2004-2010 OpenERP SA
  3. # © 2014 Angel Moya <angel.moya@domatix.com>
  4. # © 2015 Pedro M. Baeza <pedro.baeza@tecnativa.com>
  5. # © 2016 Carlos Dauden <carlos.dauden@tecnativa.com>
  6. # Copyright 2016-2017 LasLabs Inc.
  7. # Copyright 2017 Pesol (<http://pesol.es>)
  8. # Copyright 2017 Angel Moya <angel.moya@pesol.es>
  9. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
  10. from odoo import api, models, fields
  11. from odoo.exceptions import ValidationError
  12. from odoo.tools.translate import _
  13. class AccountAnalyticAccount(models.Model):
  14. _inherit = 'account.analytic.account'
  15. @api.model
  16. def _prepare_sale_line(self, line, order_id):
  17. sale_line = self.env['sale.order.line'].new({
  18. 'order_id': order_id,
  19. 'product_id': line.product_id.id,
  20. 'proudct_uom_qty': line.quantity,
  21. 'proudct_uom_id': line.uom_id.id,
  22. })
  23. # Get other invoice line values from product onchange
  24. sale_line.product_id_change()
  25. sale_line_vals = sale_line._convert_to_write(sale_line._cache)
  26. # Insert markers
  27. name = line.name
  28. contract = line.analytic_account_id
  29. if 'old_date' in self.env.context and 'next_date' in self.env.context:
  30. lang_obj = self.env['res.lang']
  31. lang = lang_obj.search(
  32. [('code', '=', contract.partner_id.lang)])
  33. date_format = lang.date_format or '%m/%d/%Y'
  34. name = self._insert_markers(
  35. line, self.env.context['old_date'],
  36. self.env.context['next_date'], date_format)
  37. sale_line_vals.update({
  38. 'name': name,
  39. 'discount': line.discount,
  40. 'price_unit': line.price_unit,
  41. })
  42. return sale_line_vals
  43. @api.multi
  44. def _prepare_sale(self):
  45. self.ensure_one()
  46. if not self.partner_id:
  47. raise ValidationError(
  48. _("You must first select a Customer for Contract %s!") %
  49. self.name)
  50. sale = self.env['sale.order'].new({
  51. 'partner_id': self.partner_id,
  52. 'date_order': self.recurring_next_date,
  53. 'origin': self.name,
  54. 'company_id': self.company_id.id,
  55. 'user_id': self.partner_id.user_id.id,
  56. 'project_id': self.id
  57. })
  58. # Get other invoice values from partner onchange
  59. sale.onchange_partner_id()
  60. return sale._convert_to_write(sale._cache)
  61. @api.multi
  62. def _create_invoice(self):
  63. self.ensure_one()
  64. if self.type == 'invoice':
  65. return super(AccountAnalyticAccount, self)._create_invoice()
  66. else:
  67. return self.env['account.invoice']
  68. @api.multi
  69. def _create_sale(self):
  70. self.ensure_one()
  71. if self.type == 'sale':
  72. sale_vals = self._prepare_sale()
  73. sale = self.env['sale.order'].create(sale_vals)
  74. for line in self.recurring_invoice_line_ids:
  75. sale_line_vals = self._prepare_sale_line(line, sale.id)
  76. self.env['sale.order.line'].create(sale_line_vals)
  77. if self.sale_autoconfirm:
  78. sale.action_confirm()
  79. return sale
  80. else:
  81. return self.env['sale.order']
  82. @api.multi
  83. def recurring_create_sale(self):
  84. """
  85. Create sales from contracts
  86. :return: sales created
  87. """
  88. sales = self.env['sale.order']
  89. for contract in self:
  90. ref_date = contract.recurring_next_date or fields.Date.today()
  91. if (contract.date_start > ref_date or
  92. contract.date_end and contract.date_end < ref_date):
  93. raise ValidationError(
  94. _("You must review start and end dates!\n%s") %
  95. contract.name)
  96. old_date = fields.Date.from_string(ref_date)
  97. new_date = old_date + self.get_relative_delta(
  98. contract.recurring_rule_type, contract.recurring_interval)
  99. ctx = self.env.context.copy()
  100. ctx.update({
  101. 'old_date': old_date,
  102. 'next_date': new_date,
  103. # Force company for correct evaluate domain access rules
  104. 'force_company': contract.company_id.id,
  105. })
  106. # Re-read contract with correct company
  107. sales |= contract.with_context(ctx)._create_sale()
  108. contract.write({
  109. 'recurring_next_date': new_date.strftime('%Y-%m-%d')
  110. })
  111. return sales
  112. @api.model
  113. def cron_recurring_create_sale(self):
  114. today = fields.Date.today()
  115. contracts = self.search([
  116. ('recurring_invoices', '=', True),
  117. ('recurring_next_date', '<=', today),
  118. '|',
  119. ('date_end', '=', False),
  120. ('date_end', '>=', today),
  121. ])
  122. return contracts.recurring_create_sale()