from django.test import TestCase
from django.contrib.auth import get_user_model

from basic_info import models as basic_models
from business import models as business_models
from business import pre_order_services

from .fixtures import create_basic_fixtures


class PrePurchaseOrderServiceTestCase(TestCase):
    def setUp(self):
        (
            self.merchant,
            self.supplier,
            self.warehouse_strict,
            self.warehouse_relaxed,
            self.product,
            self.operator,
        ) = create_basic_fixtures()

        self.user = get_user_model().objects.create_user(username='purchase-user', password='pass')
        self.operator.sys_user = self.user
        self.operator.save(update_fields=['sys_user'])

    def test_create_pre_purchase_order_success(self):
        pre_purchase_order = pre_order_services.create_pre_purchase_order(
            merchant=self.merchant,
            supplier_id=self.supplier.id,
            warehouse_id=self.warehouse_relaxed.id,
            created_by=self.user,
            operator=self.operator,
            kind=business_models.PurchaseOrderKindEnum.WHOLESALE,
            items=[
                {
                    'product_id': self.product.id,
                    'quantity': '12.5',
                    'unit': '米',
                    'order_quantity': 8,
                    'remarks': 'item-remarks',
                }
            ],
            remarks='order-remarks',
        )

        self.assertEqual(pre_purchase_order.merchant_id, self.merchant.id)
        self.assertEqual(pre_purchase_order.supplier_id, self.supplier.id)
        self.assertEqual(pre_purchase_order.warehouse_id, self.warehouse_relaxed.id)
        self.assertEqual(pre_purchase_order.created_by_id, self.user.id)
        self.assertEqual(pre_purchase_order.operator_id, self.operator.id)
        self.assertEqual(pre_purchase_order.items.count(), 1)

        item = pre_purchase_order.items.first()
        self.assertEqual(item.product_id, self.product.id)
        self.assertEqual(item.unit, '米')
        self.assertEqual(item.order_quantity, 8)

    def test_create_pre_purchase_order_rejects_cross_merchant_supplier(self):
        other_merchant = basic_models.Merchant.objects.create(
            name='其他商户',
            type=basic_models.MerchantTypeEnum.FACTORY,
        )
        other_supplier = basic_models.Supplier.objects.create(
            merchant=other_merchant,
            name='其他供应商',
        )

        with self.assertRaises(ValueError):
            pre_order_services.create_pre_purchase_order(
                merchant=self.merchant,
                supplier_id=other_supplier.id,
                warehouse_id=self.warehouse_relaxed.id,
                created_by=self.user,
                operator=self.operator,
                items=[{'product_id': self.product.id, 'quantity': '1', 'unit': '米'}],
            )

    def test_update_pre_purchase_order_replaces_items(self):
        pre_purchase_order = pre_order_services.create_pre_purchase_order(
            merchant=self.merchant,
            supplier_id=self.supplier.id,
            warehouse_id=self.warehouse_relaxed.id,
            created_by=self.user,
            operator=self.operator,
            items=[{'product_id': self.product.id, 'quantity': '10', 'unit': '米'}],
        )

        updated = pre_order_services.update_pre_purchase_order(
            pre_purchase_order=pre_purchase_order,
            warehouse_id=self.warehouse_strict.id,
            items=[
                {
                    'product_id': self.product.id,
                    'quantity': '20',
                    'unit': '米',
                    'order_quantity': 3,
                }
            ],
            remarks='updated-remarks',
        )

        self.assertEqual(updated.warehouse_id, self.warehouse_strict.id)
        self.assertEqual(updated.remarks, 'updated-remarks')
        self.assertEqual(updated.items.count(), 1)
        self.assertEqual(str(updated.items.first().quantity), '20.00')
        self.assertEqual(updated.items.first().order_quantity, 3)

    def test_delete_pre_purchase_order(self):
        pre_purchase_order = pre_order_services.create_pre_purchase_order(
            merchant=self.merchant,
            supplier_id=self.supplier.id,
            warehouse_id=self.warehouse_relaxed.id,
            created_by=self.user,
            operator=self.operator,
            items=[{'product_id': self.product.id, 'quantity': '10', 'unit': '米'}],
        )
        order_id = pre_purchase_order.id

        pre_order_services.delete_pre_purchase_order(pre_purchase_order=pre_purchase_order)
        self.assertFalse(business_models.PrePurchaseOrder.objects.filter(id=order_id).exists())
