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.

180 lines
6.0 KiB

4 years ago
4 years ago
  1. # Copyright 2020 Coop IT Easy SCRL fs
  2. # Robin Keunen <robin@coopiteasy.be>
  3. # Vincent Van Rossem <vincent@coopiteasy.be>
  4. # License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
  5. from odoo import _, api, fields, models
  6. from odoo.exceptions import ValidationError
  7. class PurchaseOrderGenerator(models.Model):
  8. _description = "Purchase Order Generator"
  9. _name = "purchase.order.generator"
  10. _order = "id desc"
  11. name = fields.Char(string="POG Reference", default="New")
  12. order_date = fields.Datetime(
  13. string="Purchase Order Date",
  14. default=fields.Datetime.now,
  15. help="Date at which the Quotation should be validated and "
  16. "converted into a purchase order.",
  17. )
  18. date_planned = fields.Datetime(
  19. string="Date Planned", default=fields.Datetime.now
  20. )
  21. supplier_id = fields.Many2one(
  22. comodel_name="res.partner",
  23. string="Supplier",
  24. readonly=True,
  25. help="Supplier of the purchase order.",
  26. )
  27. pog_line_ids = fields.One2many(
  28. comodel_name="purchase.order.generator.line",
  29. inverse_name="cpo_id",
  30. string="Order Lines",
  31. )
  32. total_amount = fields.Float(
  33. string="Total Amount (w/o VAT)", compute="_compute_pog_total"
  34. )
  35. generated_purchase_order_ids = fields.One2many(
  36. comodel_name="purchase.order",
  37. inverse_name="original_cpo_id",
  38. string="Generated Purchase Orders",
  39. )
  40. generated_po_count = fields.Integer(
  41. string="Generated Purchase Order count",
  42. compute="_compute_generated_po_count",
  43. )
  44. @api.multi
  45. @api.depends("pog_line_ids", "pog_line_ids.purchase_quantity")
  46. def _compute_pog_total(self):
  47. for cpo in self:
  48. total_amount = sum(cpol.subtotal for cpol in cpo.pog_line_ids)
  49. cpo.total_amount = total_amount
  50. @api.model
  51. def _get_selected_supplier(self):
  52. product_ids = self.env.context.get("active_ids", [])
  53. products = self.env["product.template"].browse(product_ids)
  54. suppliers = products.mapped("main_supplier_id")
  55. if not suppliers:
  56. raise ValidationError(
  57. _("No supplier is set for selected articles.")
  58. )
  59. elif len(suppliers) == 1:
  60. return suppliers
  61. else:
  62. raise ValidationError(
  63. _("You must select article from a single supplier.")
  64. )
  65. @api.model
  66. def generate_cpo(self):
  67. order_line_obj = self.env["purchase.order.generator.line"]
  68. product_ids = self.env.context.get("active_ids", [])
  69. supplier = self._get_selected_supplier()
  70. name = "POG {} {}".format(supplier.name, fields.Date.today())
  71. cpo = self.create({"name": name, "supplier_id": supplier.id})
  72. for product_id in product_ids:
  73. supplierinfo = self.env["product.supplierinfo"].search(
  74. [
  75. ("product_tmpl_id", "=", product_id),
  76. ("name", "=", supplier.id),
  77. ],
  78. order="date_start desc",
  79. limit=1,
  80. )
  81. if not supplierinfo:
  82. product_name = self.env["product.template"].browse(product_id).name
  83. raise ValidationError(
  84. _("No supplier defined for product %s") % product_name
  85. )
  86. min_qty = supplierinfo.min_qty if supplierinfo else 0
  87. order_line_obj.create(
  88. {
  89. "cpo_id": cpo.id,
  90. "product_template_id": product_id,
  91. "purchase_quantity": min_qty,
  92. }
  93. )
  94. action = {
  95. "type": "ir.actions.act_window",
  96. "res_model": "purchase.order.generator",
  97. "res_id": cpo.id,
  98. "view_type": "form",
  99. "view_mode": "form,tree",
  100. "target": "current",
  101. }
  102. return action
  103. @api.multi
  104. def create_purchase_order(self):
  105. self.ensure_one()
  106. if sum(self.pog_line_ids.mapped("purchase_quantity")) == 0:
  107. raise ValidationError(
  108. _(
  109. "You need at least a product to generate "
  110. "a Purchase Order"
  111. )
  112. )
  113. purchase_order = self.env["purchase.order"].create(
  114. {
  115. "date_order": self.order_date,
  116. "partner_id": self.supplier_id.id,
  117. "date_planned": self.date_planned,
  118. }
  119. )
  120. for cpo_line in self.pog_line_ids:
  121. if cpo_line.purchase_quantity > 0:
  122. product = cpo_line.product_template_id.product_variant_id
  123. pol = self.env["purchase.order.line"].create(
  124. {
  125. "name": cpo_line.name,
  126. "product_id": product.id,
  127. "product_qty": cpo_line.purchase_quantity,
  128. "price_unit": cpo_line.product_price,
  129. "product_uom": cpo_line.uom_po_id.id,
  130. "order_id": purchase_order.id,
  131. "date_planned": self.date_planned,
  132. }
  133. )
  134. pol.compute_taxes_id()
  135. self.generated_purchase_order_ids += purchase_order
  136. action = {
  137. "type": "ir.actions.act_window",
  138. "res_model": "purchase.order",
  139. "res_id": purchase_order.id,
  140. "view_type": "form",
  141. "view_mode": "form,tree",
  142. "target": "current",
  143. }
  144. return action
  145. @api.multi
  146. @api.depends("generated_purchase_order_ids")
  147. def _compute_generated_po_count(self):
  148. for cpo in self:
  149. cpo.generated_po_count = len(cpo.generated_purchase_order_ids)
  150. @api.multi
  151. def get_generated_po_action(self):
  152. self.ensure_one()
  153. action = {
  154. "type": "ir.actions.act_window",
  155. "res_model": "purchase.order",
  156. "view_mode": "tree,form,kanban",
  157. "target": "current",
  158. "domain": [("id", "in", self.generated_purchase_order_ids.ids)],
  159. }
  160. return action