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.

71 lines
2.6 KiB

4 years ago
  1. # Copyright 2020 Coop IT Easy SCRL fs
  2. # Robin Keunen <robin@coopiteasy.be>
  3. # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
  4. from odoo import _, api, fields, models
  5. from odoo.exceptions import ValidationError
  6. class ProductTemplate(models.Model):
  7. _inherit = "product.template"
  8. @api.multi
  9. @api.constrains("computation_range")
  10. def _check_computation_range(self):
  11. for template in self:
  12. if template.computation_range <= 0:
  13. raise ValidationError(
  14. _("Computation range must be greater than 0.")
  15. )
  16. computation_range = fields.Integer("Computation range (days)", default=14)
  17. range_sales = fields.Float(
  18. string="Sales over Range",
  19. compute="_compute_stock_coverage",
  20. store=True,
  21. )
  22. daily_sales = fields.Float(
  23. string="Daily Sales", compute="_compute_stock_coverage", store=True,
  24. )
  25. stock_coverage = fields.Float(
  26. string="Stock Coverage (days)",
  27. compute="_compute_stock_coverage",
  28. store=True,
  29. )
  30. @api.multi
  31. @api.depends("computation_range", "virtual_available", "active")
  32. def _compute_stock_coverage(self):
  33. query = """
  34. select template.id as product_template_id,
  35. sum(pol.qty) as total_sales,
  36. sum(pol.qty) / template.computation_range as daily_sales
  37. from pos_order_line pol
  38. join pos_order po ON pol.order_id = po.id
  39. join product_product product ON pol.product_id = product.id
  40. join product_template template
  41. ON product.product_tmpl_id = template.id
  42. where po.state in ('done', 'invoiced', 'paid')
  43. and template.active
  44. and po.date_order
  45. BETWEEN now() - template.computation_range * interval '1 days'
  46. and now()
  47. and template.id in %(template_ids)s
  48. group by product_template_id
  49. """
  50. template_ids = tuple(self.ids) if self.ids else (self._origin.id,)
  51. self.env.cr.execute(query, {"template_ids": template_ids})
  52. results = {pid: (qty, avg) for pid, qty, avg in self.env.cr.fetchall()}
  53. for template in self:
  54. qty, avg = results.get(template.id, (0, 0))
  55. template.range_sales = qty
  56. template.daily_sales = avg
  57. if avg != 0:
  58. template.stock_coverage = template.virtual_available / avg
  59. else:
  60. template.stock_coverage = 9999
  61. @api.model
  62. def cron_compute_stock_coverage(self):
  63. templates = self.env["product.template"].search([])
  64. templates._compute_stock_coverage()