# Copyright 2021 ForgeFlow S.L. (https://www.forgeflow.com)
# License AGPL-3.0 or later (https://www.gnu.org/licenses/lgpl.html).

from datetime import datetime as dt, timedelta as td

from odoo.addons.ddmrp.tests.common import TestDdmrpCommon


class TestDDMRPSale(TestDdmrpCommon):
    @classmethod
    def setUpClass(cls):
        super().setUpClass()
        cls.so_model = cls.env["sale.order"]

        cls.uom_dozen = cls.env.ref("uom.product_uom_dozen")

        cls.customer = cls.partner_model.create({"name": "Customer XYZ"})
        cls.buffer_internal = cls.bufferModel.create(
            {
                "buffer_profile_id": cls.buffer_profile_mmm.id,
                "product_id": cls.productA.id,
                "location_id": cls.location_shelf1.id,
                "warehouse_id": cls.warehouse.id,
                "qty_multiple": 1.0,
                "adu_calculation_method": cls.adu_fixed.id,
                "adu_fixed": 5.0,
                "lead_days": 10.0,
                "order_spike_horizon": 10.0,
            }
        )

    @classmethod
    def _refresh_involved_buffers(cls):
        cls.buffer_a.invalidate_recordset()
        cls.buffer_internal.invalidate_recordset()
        cls.buffer_a.cron_actions()
        cls.buffer_internal.cron_actions()

    def test_01_can_serve_sales(self):
        self.assertTrue(self.buffer_a.can_serve_sales)
        self.assertFalse(self.buffer_internal.can_serve_sales)

    def test_02_sales_quotation_included_as_demand(self):
        self._refresh_involved_buffers()
        self.assertEqual(
            self.buffer_a.qualified_demand, self.buffer_internal.qualified_demand
        )
        so_date = dt.today() + td(days=2)
        so = self.so_model.create(
            {
                "partner_id": self.customer.id,
                "partner_invoice_id": self.customer.id,
                "partner_shipping_id": self.customer.id,
                "commitment_date": so_date,
                "order_line": [
                    (
                        0,
                        0,
                        {
                            "product_id": self.productA.id,
                            "name": "cool product",
                            "price_unit": 100.0,
                            "product_uom_qty": 17,  # it is a spike.
                            "commitment_date": so_date,
                        },
                    )
                ],
            }
        )
        self.assertEqual(so.state, "draft")
        self._refresh_involved_buffers()
        self.assertNotEqual(
            self.buffer_a.qualified_demand, self.buffer_internal.qualified_demand
        )
        # Buffer A sees quotations because it can serve SO's.
        diff = self.buffer_a.qualified_demand - self.buffer_internal.qualified_demand
        buffer_a_prev_nfp = self.buffer_a.net_flow_position
        self.assertEqual(diff, 17)
        so.action_confirm()
        self.assertTrue(so.picking_ids)
        self._refresh_involved_buffers()
        # After confirmation we ignore the SO and rely on the picking.
        # Check that NFP does not vary. If picking is reserved OH quantity
        # should had been reduced, if not, quantity remained as qualified demand.
        self.assertEqual(self.buffer_a.net_flow_position, buffer_a_prev_nfp)

    def test_03_sol_uom(self):
        self._refresh_involved_buffers()
        so_date = dt.today() + td(days=2)
        so = self.so_model.create(
            {
                "partner_id": self.customer.id,
                "partner_invoice_id": self.customer.id,
                "partner_shipping_id": self.customer.id,
                "commitment_date": so_date,
                "order_line": [
                    (
                        0,
                        0,
                        {
                            "product_id": self.productA.id,
                            "name": "cool product",
                            "price_unit": 100.0,
                            "product_uom_qty": 2,  # 2 dozens, it is a spike.
                            "product_uom": self.uom_dozen.id,
                            "commitment_date": so_date,
                        },
                    )
                ],
            }
        )
        self.assertEqual(so.state, "draft")
        self._refresh_involved_buffers()
        diff = self.buffer_a.qualified_demand - self.buffer_internal.qualified_demand
        self.assertEqual(diff, 24)
