# Copyright 2020 Tecnativa - Sergio Teruel
# License AGPL-3.0 or later (https://www.gnu.org/licenses/agpl.html).
from odoo.tests import Form
from odoo.tests import TransactionCase


class TestStockPickingReportUndeliveredProduct(TransactionCase):
    @classmethod
    def setUpClass(cls):
        super().setUpClass()
        cls.ResPartner = cls.env["res.partner"]
        cls.ProductProduct = cls.env["product.product"]
        cls.StockPicking = cls.env["stock.picking"]
        cls.StockQuant = cls.env["stock.quant"]
        cls.BackOrderWiz = cls.env["stock.backorder.confirmation"]
        cls.warehouse = cls.env.ref("stock.warehouse0")
        cls.picking_type_out = cls.env.ref("stock.picking_type_out")

        cls.partner_display = cls.ResPartner.create(
            {"name": "Partner for test display", "display_undelivered_in_picking": True}
        )
        cls.partner_no_display = cls.ResPartner.create(
            {
                "name": "Partner for test on display",
                "display_undelivered_in_picking": False,
            }
        )

        cls.product_display = cls.ProductProduct.create(
            {
                "name": "Test product undelivered display",
                "display_undelivered_in_picking": True,
                "type": "consu",
                "is_storable": True,
            }
        )
        cls.product_no_display = cls.ProductProduct.create(
            {
                "name": "Test product undelivered no display",
                "display_undelivered_in_picking": False,
                "type": "consu",
                "is_storable": True,
            }
        )
        cls.product_no_display_wo_stock = cls.ProductProduct.create(
            {
                "name": "Test product undelivered no display without stock",
                "display_undelivered_in_picking": False,
                "type": "consu",
                "is_storable": True,
            }
        )
        cls.StockQuant.create(
            {
                "product_id": cls.product_no_display.id,
                "location_id": cls.warehouse.lot_stock_id.id,
                "quantity": 2000,
            }
        )

    def _create_picking(self, partner):
        picking_form = Form(self.StockPicking)
        picking_form.picking_type_id = self.picking_type_out
        picking_form.partner_id = partner

        with picking_form.move_ids_without_package.new() as line:
            line.product_id = self.product_display
            line.product_uom_qty = 50.00
        with picking_form.move_ids_without_package.new() as line:
            line.product_id = self.product_no_display
            line.product_uom_qty = 20.00
        with picking_form.move_ids_without_package.new() as line:
            line.product_id = self.product_no_display_wo_stock
            line.product_uom_qty = 20.00
        return picking_form.save()

    def _transfer_picking_no_backorder(self, picking):
        # Transfer picking with no create backorder option
        picking.move_line_ids.picked = True
        backorder_wizard = self.BackOrderWiz.create({"pick_ids": [(4, picking.id)]})
        backorder_wizard.with_context(
            button_validate_picking_ids=picking.id
        ).process_cancel_backorder()

    def _render(self, picking):
        return self.env["ir.actions.report"]._render_qweb_html(
            "stock.report_deliveryslip", picking.ids
        )

    def test_displayed_customer(self):
        picking = self._create_picking(self.partner_display)
        picking.action_confirm()
        picking.action_assign()
        picking.move_line_ids.filtered(
            lambda ml: ml.product_id == self.product_display
        ).quantity = 10.00
        self._transfer_picking_no_backorder(picking)
        res = self._render(picking)
        self.assertIn("undelivered_product", str(res[0]))

    def test_no_displayed_customer(self):
        picking = self._create_picking(self.partner_no_display)
        picking.action_confirm()
        picking.action_assign()
        picking.move_line_ids.filtered(
            lambda ml: ml.product_id == self.product_display
        ).quantity = 10.00
        self._transfer_picking_no_backorder(picking)
        res = self._render(picking)
        self.assertNotIn("undelivered_product", str(res[0]))

    def test_no_displayed_product(self):
        picking = self._create_picking(self.partner_display)
        picking.move_ids.filtered(
            lambda move: move.product_id == self.product_display
        ).unlink()
        picking.action_confirm()
        picking.action_assign()
        picking.move_line_ids.quantity = 10.00
        self._transfer_picking_no_backorder(picking)
        res = self._render(picking)
        self.assertNotIn("undelivered_product", str(res[0]))

    def test_picking_report_method(self):
        product = self.ProductProduct.create(
            {
                "name": "test01",
                "display_undelivered_in_picking": True,
                "type": "consu",
                "is_storable": True,
            }
        )
        product2 = self.ProductProduct.create(
            {
                "name": "test02",
                "display_undelivered_in_picking": True,
                "type": "consu",
                "is_storable": True,
            }
        )
        self.StockQuant.create(
            {
                "product_id": product.id,
                "location_id": self.warehouse.lot_stock_id.id,
                "quantity": 2000,
            }
        )
        picking_form = Form(self.StockPicking)
        picking_form.picking_type_id = self.picking_type_out
        picking_form.partner_id = self.partner_display
        with picking_form.move_ids_without_package.new() as line:
            line.product_id = product
            line.product_uom_qty = 50.00
        with picking_form.move_ids_without_package.new() as line:
            line.product_id = product2
            line.product_uom_qty = 20.00
        picking = picking_form.save()

        picking.action_confirm()
        picking.action_assign()
        picking.move_line_ids.filtered(lambda ml: ml.product_id == product).quantity = (
            10.00
        )
        self._transfer_picking_no_backorder(picking)

        # Empty setting method field
        picking.company_id.undelivered_product_slip_report_method = False
        res = self._render(picking)
        self.assertIn("test02", str(res[0]))

        # Print all undelivered lines, partial and completely lines
        picking.company_id.undelivered_product_slip_report_method = "all"
        res = self._render(picking)
        self.assertIn("test02", str(res[0]))

        # Print only partial undelivered lines
        picking.company_id.undelivered_product_slip_report_method = (
            "partially_undelivered"
        )
        res = self._render(picking)
        self.assertNotIn("test02", str(res[0]))

        # Print only completely undelivered lines
        picking.company_id.undelivered_product_slip_report_method = (
            "completely_undelivered"
        )
        res = self._render(picking)
        self.assertNotIn("partially_undelivered_line", str(res[0]))
