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.

142 lines
5.2 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. 'product_qty': line.quantity,
  21. 'product_uom_qty': line.quantity,
  22. 'product_uom': line.uom_id.id,
  23. })
  24. # Get other sale line values from product onchange
  25. sale_line.product_id_change()
  26. sale_line_vals = sale_line._convert_to_write(sale_line._cache)
  27. # Insert markers
  28. name = line.name
  29. contract = line.analytic_account_id
  30. if 'old_date' in self.env.context and 'next_date' in self.env.context:
  31. lang_obj = self.env['res.lang']
  32. lang = lang_obj.search(
  33. [('code', '=', contract.partner_id.lang)])
  34. date_format = lang.date_format or '%m/%d/%Y'
  35. name = self._insert_markers(
  36. line, self.env.context['old_date'],
  37. self.env.context['next_date'], date_format)
  38. sale_line_vals.update({
  39. 'name': name,
  40. 'discount': line.discount,
  41. 'price_unit': line.price_unit,
  42. })
  43. return sale_line_vals
  44. @api.multi
  45. def _prepare_sale(self):
  46. self.ensure_one()
  47. if not self.partner_id:
  48. raise ValidationError(
  49. _("You must first select a Customer for Contract %s!") %
  50. self.name)
  51. sale = self.env['sale.order'].new({
  52. 'partner_id': self.partner_id,
  53. 'date_order': self.recurring_next_date,
  54. 'origin': self.name,
  55. 'company_id': self.company_id.id,
  56. 'user_id': self.partner_id.user_id.id,
  57. 'project_id': self.id
  58. })
  59. # Get other invoice values from partner onchange
  60. sale.onchange_partner_id()
  61. return sale._convert_to_write(sale._cache)
  62. @api.multi
  63. def _create_invoice(self):
  64. """
  65. Create invoices
  66. @param self: single record of account.invoice
  67. @return: MUST return an invoice recordset
  68. """
  69. self.ensure_one()
  70. if self.type == 'invoice':
  71. return super(AccountAnalyticAccount, self)._create_invoice()
  72. else:
  73. return self.env['account.invoice']
  74. @api.multi
  75. def _create_sale(self):
  76. """
  77. Create Sale orders
  78. @param self: single record of sale.order
  79. @return: MUST return a sale.order recordset
  80. """
  81. self.ensure_one()
  82. if self.type == 'sale':
  83. sale_vals = self._prepare_sale()
  84. sale = self.env['sale.order'].create(sale_vals)
  85. for line in self.recurring_invoice_line_ids:
  86. sale_line_vals = self._prepare_sale_line(line, sale.id)
  87. self.env['sale.order.line'].create(sale_line_vals)
  88. if self.sale_autoconfirm:
  89. sale.action_confirm()
  90. return sale
  91. else:
  92. return self.env['sale.order']
  93. @api.multi
  94. def recurring_create_sale(self):
  95. """
  96. Create sales from contracts
  97. :return: sales created
  98. """
  99. sales = self.env['sale.order']
  100. for contract in self:
  101. ref_date = contract.recurring_next_date or fields.Date.today()
  102. if (contract.date_start > ref_date or
  103. contract.date_end and contract.date_end < ref_date):
  104. raise ValidationError(
  105. _("You must review start and end dates!\n%s") %
  106. contract.name)
  107. old_date = fields.Date.from_string(ref_date)
  108. new_date = old_date + self.get_relative_delta(
  109. contract.recurring_rule_type, contract.recurring_interval)
  110. ctx = self.env.context.copy()
  111. ctx.update({
  112. 'old_date': old_date,
  113. 'next_date': new_date,
  114. # Force company for correct evaluate domain access rules
  115. 'force_company': contract.company_id.id,
  116. })
  117. # Re-read contract with correct company
  118. sales |= contract.with_context(ctx)._create_sale()
  119. contract.write({
  120. 'recurring_next_date': new_date.strftime('%Y-%m-%d')
  121. })
  122. return sales
  123. @api.model
  124. def cron_recurring_create_sale(self):
  125. today = fields.Date.today()
  126. contracts = self.search([
  127. ('recurring_invoices', '=', True),
  128. ('recurring_next_date', '<=', today),
  129. '|',
  130. ('date_end', '=', False),
  131. ('date_end', '>=', today),
  132. ])
  133. return contracts.recurring_create_sale()