# Copyright 2018-2020 ForgeFlow, S.L.
# License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl-3.0)

from odoo import api, fields, models


class StockRule(models.Model):
    _inherit = "stock.rule"

    @api.model
    def _prepare_purchase_request_line(self, request_id, procurement):
        procurement_uom_po_qty = procurement.product_uom._compute_quantity(
            procurement.product_qty, procurement.product_id.uom_po_id
        )
        return {
            "product_id": procurement.product_id.id,
            "name": procurement.product_id.name,
            "date_required": "date_planned" in procurement.values
            and procurement.values["date_planned"]
            or fields.Datetime.now(),
            "product_uom_id": procurement.product_id.uom_po_id.id,
            "product_qty": procurement_uom_po_qty,
            "request_id": request_id.id,
            "move_dest_ids": [
                (4, x.id) for x in procurement.values.get("move_dest_ids", [])
            ],
            "orderpoint_id": procurement.values.get("orderpoint_id", False)
            and procurement.values.get("orderpoint_id").id,
        }

    @api.model
    def _prepare_purchase_request(self, origin, values):
        gpo = self.group_propagation_option
        group_id = (
            (gpo == "fixed" and self.group_id.id)
            or (gpo == "propagate" and values.get("group_id") and values["group_id"].id)
            or False
        )
        return {
            "origin": origin,
            "company_id": values["company_id"].id,
            "picking_type_id": self.picking_type_id.id,
            "group_id": group_id or False,
            "requested_by": self.env.context.get("uid", self.env.uid),
            "assigned_to": False,
        }

    @api.model
    def _make_pr_get_domain(self, values):
        """
        This method is to be implemented by other modules that can
        provide a criteria to select the appropriate purchase request to be
        extended.
        :return: False
        """
        domain = (
            ("state", "=", "draft"),
            ("picking_type_id", "=", self.picking_type_id.id),
            ("company_id", "=", values["company_id"].id),
        )
        gpo = self.group_propagation_option
        group_id = (
            (gpo == "fixed" and self.group_id.id)
            or (gpo == "propagate" and values["group_id"].id)
            or False
        )
        if group_id:
            domain += (("group_id", "=", group_id),)
        return domain

    def is_create_purchase_request_allowed(self, procurement):
        """
        Tell if current procurement order should
        create a purchase request or not.
        :return: boolean
        """
        return (
            procurement[1].action == "buy"
            and procurement[0].product_id.purchase_request
        )

    def _run_buy(self, procurements):
        indexes_to_pop = []
        for i, procurement in enumerate(procurements):
            if self.is_create_purchase_request_allowed(procurement):
                self.create_purchase_request(procurement)
                indexes_to_pop.append(i)
        if indexes_to_pop:
            indexes_to_pop.reverse()
            for index in indexes_to_pop:
                procurements.pop(index)
        if not procurements:
            return
        return super(StockRule, self)._run_buy(procurements)

    def create_purchase_request(self, procurement_group):
        """
        Create a purchase request containing procurement order product.
        """
        procurement = procurement_group[0]
        rule = procurement_group[1]
        purchase_request_model = self.env["purchase.request"]
        purchase_request_line_model = self.env["purchase.request.line"]
        cache = {}
        pr = self.env["purchase.request"]
        domain = rule._make_pr_get_domain(procurement.values)
        if domain in cache:
            pr = cache[domain]
        elif domain:
            pr = self.env["purchase.request"].search([dom for dom in domain])
            pr = pr[0] if pr else False
            cache[domain] = pr
        if not pr:
            request_data = rule._prepare_purchase_request(
                procurement.origin, procurement.values
            )
            pr = purchase_request_model.create(request_data)
            cache[domain] = pr
        elif (
            not pr.origin
            or procurement.origin not in pr.origin.split(", ")
            and procurement.origin != "/"
        ):
            if pr.origin:
                if procurement.origin:
                    pr.write({"origin": pr.origin + ", " + procurement.origin})
            else:
                pr.write({"origin": procurement.origin})
        # Create Line
        request_line_data = rule._prepare_purchase_request_line(pr, procurement)
        purchase_request_line_model.create(request_line_data)
