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.

66 lines
2.4 KiB

  1. # -*- coding: utf-8 -*-
  2. # © 2016 Pedro M. Baeza <pedro.baeza@tecnativa.com>
  3. # License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
  4. from odoo import _, api, fields, models, exceptions
  5. from odoo.tools.safe_eval import safe_eval
  6. class AccountAnalyticAccount(models.Model):
  7. _inherit = "account.analytic.account"
  8. @api.model
  9. def _prepare_invoice_line(self, line, invoice_id):
  10. vals = super(AccountAnalyticAccount, self)._prepare_invoice_line(
  11. line, invoice_id)
  12. if line.qty_type == 'variable':
  13. eval_context = {
  14. 'env': self.env,
  15. 'context': self.env.context,
  16. 'user': self.env.user,
  17. 'line': line,
  18. 'contract': line.analytic_account_id,
  19. 'invoice': self.env['account.invoice'].browse(invoice_id),
  20. }
  21. safe_eval(line.qty_formula_id.code.strip(), eval_context,
  22. mode="exec", nocopy=True) # nocopy for returning result
  23. vals['quantity'] = eval_context.get('result', 0)
  24. return vals
  25. class AccountAnalyticContractLine(models.Model):
  26. _inherit = 'account.analytic.contract.line'
  27. qty_type = fields.Selection(
  28. selection=[
  29. ('fixed', 'Fixed quantity'),
  30. ('variable', 'Variable quantity'),
  31. ], required=True, default='fixed', string="Qty. type")
  32. qty_formula_id = fields.Many2one(
  33. comodel_name="contract.line.qty.formula", string="Qty. formula")
  34. class ContractLineFormula(models.Model):
  35. _name = 'contract.line.qty.formula'
  36. name = fields.Char(required=True)
  37. code = fields.Text(required=True, default="result = 0")
  38. @api.constrains('code')
  39. def _check_code(self):
  40. eval_context = {
  41. 'env': self.env,
  42. 'context': self.env.context,
  43. 'user': self.env.user,
  44. 'line': self.env['account.analytic.invoice.line'],
  45. 'contract': self.env['account.analytic.account'],
  46. 'invoice': self.env['account.invoice'],
  47. }
  48. try:
  49. safe_eval(
  50. self.code.strip(), eval_context, mode="exec", nocopy=True)
  51. except Exception as e:
  52. raise exceptions.ValidationError(
  53. _('Error evaluating code.\nDetails: %s') % e)
  54. if 'result' not in eval_context:
  55. raise exceptions.ValidationError(_('No valid result returned.'))