package com.xiaomai.cases.polar.goods;

import com.alibaba.fastjson.JSONObject;
import com.xiaomai.cases.lunar.goods.GoodCTools;
import com.xiaomai.cases.lunar.user.UserTools;
import com.xiaomai.cases.polar.admin.AdminTools;
import com.xiaomai.cases.polar.data.financeData.FinanceDataTools;
import com.xiaomai.cases.polar.finance.order.OrderTools;
import com.xiaomai.cases.polar.goods.Tools.GoodTools;
import com.xiaomai.client.DataUserInfo;
import com.xiaomai.enums.ApiModule;
import com.xiaomai.enums.LoginAccount;
import com.xiaomai.enums.Terminal;
import com.xiaomai.utils.RandomStringUtil;
import com.xiaomai.utils.TimeUtils;
import com.xiaomai.utils.XMBaseTest;
import org.testng.Assert;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;

import java.math.BigDecimal;
import java.math.RoundingMode;

public class TestRefundGoods extends XMBaseTest {

    GoodTools goodTools=new GoodTools();
    GoodCTools goodCTools=new GoodCTools();



    DataUserInfo info =new DataUserInfo();
    UserTools userTools=new UserTools();

    OrderTools orderTools=new OrderTools();

    FinanceDataTools financeDataTools=new FinanceDataTools();
    AdminTools adminTools=new AdminTools();

    String memberId;



    @BeforeMethod
    public void beforeTest() {
        xmAppApi.setApiModule(ApiModule.Polar_Goods)
                .setApiName("API_refundGoods")
                .setLoginUser(LoginAccount.GYM_PROD)
                .setTerminal(Terminal.B);

        dal.setCase_owner("yff")
                .setCase_name(Thread.currentThread().getStackTrace()[1].getFileName().split("\\.")[0]);
        super.beforeTest();
    }

    @Test(description = "退物品：购买多规格&退货退款->作废退&仅退款->作废退&作废购买")
    public void testRefundGoods() {

        //涉及到订单的都使用存量物品数据，因为购买过物品就不能被删除了，所以不会买一次新建一个

//        "id": "1874413681302990849",
//                "name": "自动化禁用-购买订单单规格1元",
//        "id": "1874413587237335042",
//                "name": "自动化禁用-购买订单多规格1元",


        //case1：购买非0订单->待支付->已完成

        //切换端位
        info.setTerminal(Terminal.minApp);
        info.setLoginUser(LoginAccount.GYM_MINIAPPC);

        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }


        //获取会员信息
        //获取用户
        memberId = userTools.getMemberInfo(info).getString("memberId");

        String goodsId1="1874413587237335042";


        //获取B端商品详情
        JSONObject getDetail_goods=goodTools.getDetail_goods(goodsId1);
        String id=getDetail_goods.getJSONObject("result").getJSONObject("multiSpecInfo").getJSONArray("specCombinationList").getJSONObject(0).getString("id");
        BigDecimal price=new BigDecimal(getDetail_goods.getJSONObject("result").getJSONObject("multiSpecInfo").getJSONArray("specCombinationList").getJSONObject(0).getString("price"));
        int beforeInventory=Integer.parseInt(getDetail_goods.getJSONObject("result").getJSONObject("multiSpecInfo").getJSONArray("specCombinationList").getJSONObject(0).getString("inventory"));

        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }

        //获取数据中心-财务中心-营收明细-物品的确认收入
        JSONObject beforeGetCostData_type=financeDataTools.getCostData_type("DAY","GOODS", TimeUtils.getTodayTime(),TimeUtils.getTodayEndTime());
        BigDecimal beforeConfirmedAmount=new BigDecimal(beforeGetCostData_type.getJSONObject("result").getString("confirmedAmount"));//确认收入

        boolean checkAllowPurchase=Boolean.parseBoolean(goodCTools.checkAllowPurchase(id,memberId,price,beforeInventory,info).getJSONObject("result").getString("success"));

        //校验一下物品购买是否可以通过，为true才可以
        if(checkAllowPurchase==true) {

            JSONObject purchaseGoods = goodCTools.purchaseGoods("0.00", null, memberId, "", String.valueOf(price), id, price, 1, info);
            String signOrderId1 = purchaseGoods.getJSONObject("result").getString("id");

            //生成待支付订单后，去B端继续收款

            //获取B端订单详情：待支付状态
            JSONObject getDetailResult = orderTools.getDetail(signOrderId1, info);
            String state = getDetailResult.getJSONObject("result").getString("state");
            BigDecimal unpaidAmount = new BigDecimal(getDetailResult.getJSONObject("result").getString("unpaidAmount"));
            Assert.assertEquals(state, "WAITING", "未生成待支付物品订单");


            //B端变更为已完成物品订单
            //继续收款为已完成
            JSONObject pay = orderTools.pay(unpaidAmount, "1", signOrderId1);

            //校验1：获取B端订单详情：已完成状态
            JSONObject getDetailResult_delinquent = orderTools.getDetail(signOrderId1);
            String state_delinquent = getDetailResult_delinquent.getJSONObject("result").getString("state");
            Assert.assertEquals(state_delinquent, "PAID", "B端继续收款后订单状态由待支付变为已完成");


            //获取B端商品详情库存数
            JSONObject lastGetDetail_goods = goodTools.getDetail_goods(goodsId1);
            int refundBeforeInventory = Integer.parseInt(lastGetDetail_goods.getJSONObject("result").getJSONObject("multiSpecInfo").getJSONArray("specCombinationList").getJSONObject(0).getString("inventory"));

            try {
                Thread.sleep(20000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }

            //获取数据中心-财务中心-营收明细-物品的确认收入
            JSONObject refundBeforeGetCostData_type = financeDataTools.getCostData_type("DAY", "GOODS", TimeUtils.getTodayTime(), TimeUtils.getTodayEndTime());
            BigDecimal refundBeforeConfirmedAmount = new BigDecimal(refundBeforeGetCostData_type.getJSONObject("result").getString("confirmedAmount"));//确认收入



            //case2：已完成->退货退款

            //拉取这个会员的物品列表
            JSONObject listLeftGoodsItem=goodTools.listLeftGoodsItem(memberId);
            String refundId=listLeftGoodsItem.getJSONArray("result").getJSONObject(0).getString("id");

            //B端退单时获取订单可退物品（退单界面）
            JSONObject getLeftGoodsItem=goodTools.getLeftGoodsItem(refundId);
            int quantity=Integer.parseInt(getLeftGoodsItem.getJSONObject("result").getString("leftQuantity"));
            BigDecimal refundAmount=new BigDecimal(getLeftGoodsItem.getJSONObject("result").getString("leftConsumeAmount"));
            String voucherItemId=getLeftGoodsItem.getJSONObject("result").getString("id");
            BigDecimal receivableAmount=new BigDecimal(getLeftGoodsItem.getJSONObject("result").getString("leftConsumeAmount"));
            BigDecimal amount=new BigDecimal(getLeftGoodsItem.getJSONObject("result").getString("leftConsumeAmount"));
            String voucherId=getLeftGoodsItem.getJSONObject("result").getString("voucherId");


            String ownerName=adminTools.getStudioAdmin(xmAppApi.getLoginInfo().getAdminId()).getJSONObject("result").getString("nickName");


            Boolean success=Boolean.parseBoolean(orderTools.checkRefundableAmount(voucherId, amount.floatValue()).getString("success"));

            if (success==true){
            //退货退款物品
            JSONObject refundGoods=goodTools.refundGoods(xmAppApi.getLoginInfo().getAdminId(),ownerName,quantity,refundAmount,true,voucherItemId,memberId,receivableAmount,amount,"1",new BigDecimal("0.00"),new BigDecimal("0.00"),"",0,amount,amount);
            String refundOrderId1=refundGoods.getString("result");

            //校验：
            //校验1：获取B端订单详情：退单已完成状态
            JSONObject getDetailResult_refund = orderTools.getDetail(refundOrderId1);
            String state_refund = getDetailResult_refund.getJSONObject("result").getString("state");
            Assert.assertEquals(state_refund, "PAID", "B端退货退款成功后退单订单状态变为已完成");


            //校验2：商品详情库存数+1
            JSONObject refundAfterGetDetail_goods = goodTools.getDetail_goods(goodsId1);
            int refundAfterInventory = Integer.parseInt(refundAfterGetDetail_goods.getJSONObject("result").getJSONObject("multiSpecInfo").getJSONArray("specCombinationList").getJSONObject(0).getString("inventory"));
            Assert.assertEquals(refundAfterInventory,refundBeforeInventory+1,"退货退款成功后，库存数应+1");

            try {
                Thread.sleep(20000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }

            //校验3：数据中心-财务中心-营收明细-物品的确认收入应减少
            JSONObject refundAfterGetCostData_type = financeDataTools.getCostData_type("DAY", "GOODS", TimeUtils.getTodayTime(), TimeUtils.getTodayEndTime());
            BigDecimal refundAfterConfirmedAmount = new BigDecimal(refundAfterGetCostData_type.getJSONObject("result").getString("confirmedAmount"));//确认收入
            Assert.assertEquals(refundAfterConfirmedAmount,refundBeforeConfirmedAmount.subtract(refundAmount.setScale(2, RoundingMode.HALF_UP)),"退货退款成功后，数据中心-财务中心-营收明细-物品的确认收入应减少对应的金额");




            //case3：作废退货退款订单


            JSONObject discardRefundOrder=orderTools.discard(refundOrderId1, "重复录入", "已作废物品退货退款订单" + RandomStringUtil.randomString(10));

            //校验：
            //校验1：获取B端订单详情：退单已作废状态
            JSONObject getDetailResult_discardRefund = orderTools.getDetail(refundOrderId1);
            String state_discardRefund = getDetailResult_discardRefund.getJSONObject("result").getString("state");
            Assert.assertEquals(state_discardRefund, "DISCARD", "B端作废退货退款订单后，订单状态由已完成变为已作废");


            //校验2：商品详情库存数-1
            JSONObject discardRefundAfterGetDetail_goods = goodTools.getDetail_goods(goodsId1);
            int discardRefundAfterInventory = Integer.parseInt(discardRefundAfterGetDetail_goods.getJSONObject("result").getJSONObject("multiSpecInfo").getJSONArray("specCombinationList").getJSONObject(0).getString("inventory"));
            Assert.assertEquals(discardRefundAfterInventory,refundAfterInventory-1,"作废退货退款订单成功后，库存数应-1");

            try {
                Thread.sleep(5000);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }

            //校验3：数据中心-财务中心-营收明细-物品的确认收入应增加
            JSONObject discardRefundAfterGetCostData_type = financeDataTools.getCostData_type("DAY", "GOODS", TimeUtils.getTodayTime(), TimeUtils.getTodayEndTime());
            BigDecimal discardRefundAfterConfirmedAmount = new BigDecimal(discardRefundAfterGetCostData_type.getJSONObject("result").getString("confirmedAmount"));//确认收入
            Assert.assertEquals(discardRefundAfterConfirmedAmount,refundAfterConfirmedAmount.add(refundAmount.setScale(2, RoundingMode.HALF_UP)),"作废退货退款订单成功后，数据中心-财务中心-营收明细-物品的确认收入应增加对应的金额");



            //case4：仅退款物品

            //拉取这个会员的物品列表
            JSONObject listLeftGoodsItem_onlyAmount=goodTools.listLeftGoodsItem(memberId);
            String refundId_onlyAmount=listLeftGoodsItem_onlyAmount.getJSONArray("result").getJSONObject(0).getString("id");

            //B端退单时获取订单可退物品（退单界面）
            JSONObject getLeftGoodsItem_onlyAmount=goodTools.getLeftGoodsItem(refundId_onlyAmount);
            int quantity_onlyAmount=Integer.parseInt(getLeftGoodsItem.getJSONObject("result").getString("leftQuantity"));
            BigDecimal refundAmount_onlyAmount=new BigDecimal(getLeftGoodsItem_onlyAmount.getJSONObject("result").getString("leftConsumeAmount"));
            String voucherItemId_onlyAmount=getLeftGoodsItem_onlyAmount.getJSONObject("result").getString("id");
            BigDecimal receivableAmount_onlyAmount=new BigDecimal(getLeftGoodsItem_onlyAmount.getJSONObject("result").getString("leftConsumeAmount"));
            BigDecimal amount_onlyAmount=new BigDecimal(getLeftGoodsItem_onlyAmount.getJSONObject("result").getString("leftConsumeAmount"));
            String voucherId1=getLeftGoodsItem.getJSONObject("result").getString("voucherId");

            Boolean success1=Boolean.parseBoolean(orderTools.checkRefundableAmount(voucherId1, amount_onlyAmount.floatValue()).getString("success"));

            if (success1==true) {
                //仅退款物品
                JSONObject refundGoods_onlyAmount = goodTools.refundGoods(xmAppApi.getLoginInfo().getAdminId(), ownerName, quantity_onlyAmount, refundAmount_onlyAmount, false, voucherItemId_onlyAmount, memberId, receivableAmount_onlyAmount, amount_onlyAmount, "1", new BigDecimal("0.00"), new BigDecimal("0.00"), "", 0, amount_onlyAmount, amount_onlyAmount);
                String refundOrderId2_onlyAmount = refundGoods_onlyAmount.getString("result");


                //校验：
                //校验1：获取B端订单详情：退单已完成状态
                JSONObject getDetailResult_refund_onlyAmount = orderTools.getDetail(refundOrderId2_onlyAmount);
                String state_refund_onlyAmount = getDetailResult_refund_onlyAmount.getJSONObject("result").getString("state");
                Assert.assertEquals(state_refund_onlyAmount, "PAID", "B端退货退款成功后退单订单状态变为已完成");


                //校验2：商品详情库存数不变
                JSONObject refundAfterGetDetail_goods_onlyAmount = goodTools.getDetail_goods(goodsId1);
                int refundAfterInventory_onlyAmount = Integer.parseInt(refundAfterGetDetail_goods_onlyAmount.getJSONObject("result").getJSONObject("multiSpecInfo").getJSONArray("specCombinationList").getJSONObject(0).getString("inventory"));
                Assert.assertEquals(refundAfterInventory_onlyAmount, discardRefundAfterInventory, "仅退款成功后，库存数应不变");

                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }

                //校验3：数据中心-财务中心-营收明细-物品的确认收入应减少
                JSONObject refundAfterGetCostData_type_onlyAmount = financeDataTools.getCostData_type("DAY", "GOODS", TimeUtils.getTodayTime(), TimeUtils.getTodayEndTime());
                BigDecimal refundAfterConfirmedAmount_onlyAmount = new BigDecimal(refundAfterGetCostData_type_onlyAmount.getJSONObject("result").getString("confirmedAmount"));//确认收入
                Assert.assertEquals(refundAfterConfirmedAmount_onlyAmount, discardRefundAfterConfirmedAmount.subtract(refundAmount_onlyAmount.setScale(2, RoundingMode.HALF_UP)), "仅退款成功后，数据中心-财务中心-营收明细-物品的确认收入应减少对应的金额");


                //case5：作废仅退款订单


                JSONObject discardRefundOrder_onlyAmount = orderTools.discard(refundOrderId2_onlyAmount, "重复录入", "已作废物品仅退款订单" + RandomStringUtil.randomString(10));

                //校验：
                //校验1：获取B端订单详情：退单已作废状态
                JSONObject getDetailResult_discardRefund_onlyAmount = orderTools.getDetail(refundOrderId2_onlyAmount);
                String state_discardRefund_onlyAmount = getDetailResult_discardRefund_onlyAmount.getJSONObject("result").getString("state");
                Assert.assertEquals(state_discardRefund_onlyAmount, "DISCARD", "B端作废仅退款订单后，订单状态由已完成变为已作废");


                //校验2：商品详情库存数不变
                JSONObject discardRefundAfterGetDetail_goods_onlyAmount = goodTools.getDetail_goods(goodsId1);
                int discardRefundAfterInventory_onlyAmount = Integer.parseInt(discardRefundAfterGetDetail_goods_onlyAmount.getJSONObject("result").getJSONObject("multiSpecInfo").getJSONArray("specCombinationList").getJSONObject(0).getString("inventory"));
                Assert.assertEquals(discardRefundAfterInventory_onlyAmount, refundAfterInventory_onlyAmount, "作废仅退款订单成功后，库存数应不变");

                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }

                //校验3：数据中心-财务中心-营收明细-物品的确认收入应增加
                JSONObject discardRefundAfterGetCostData_type_onlyAmount = financeDataTools.getCostData_type("DAY", "GOODS", TimeUtils.getTodayTime(), TimeUtils.getTodayEndTime());
                BigDecimal discardRefundAfterConfirmedAmount_onlyAmount = new BigDecimal(discardRefundAfterGetCostData_type_onlyAmount.getJSONObject("result").getString("confirmedAmount"));//确认收入
                Assert.assertEquals(discardRefundAfterConfirmedAmount_onlyAmount, refundAfterConfirmedAmount_onlyAmount.add(refundAmount_onlyAmount.setScale(2, RoundingMode.HALF_UP)), "作废仅退款订单成功后，数据中心-财务中心-营收明细-物品的确认收入应增加对应的金额");


                //case6：作废购买订单


                JSONObject discardSignOrder = orderTools.discard(signOrderId1, "重复录入", "已作废物品购买订单" + RandomStringUtil.randomString(10));

                //校验：
                //校验1：获取B端订单详情：购买订单已作废状态
                JSONObject getDetailResult_discardSign = orderTools.getDetail(signOrderId1);
                String state_discardRefund_discardSign = getDetailResult_discardSign.getJSONObject("result").getString("state");
                Assert.assertEquals(state_discardRefund_discardSign, "DISCARD", "B端作废购买订单后，签单订单状态由已完成变为已作废");


                //校验2：商品详情库存数+1
                JSONObject discardSignAfterGetDetail_goods = goodTools.getDetail_goods(goodsId1);
                int discardSignAfterInventory = Integer.parseInt(discardSignAfterGetDetail_goods.getJSONObject("result").getJSONObject("multiSpecInfo").getJSONArray("specCombinationList").getJSONObject(0).getString("inventory"));
                Assert.assertEquals(discardSignAfterInventory, discardRefundAfterInventory_onlyAmount + 1, "作废购买订单成功后，库存数应+1");

                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    throw new RuntimeException(e);
                }

                //校验3：数据中心-财务中心-营收明细-物品的确认收入应减少
                JSONObject discardSignAfterGetCostData_type = financeDataTools.getCostData_type("DAY", "GOODS", TimeUtils.getTodayTime(), TimeUtils.getTodayEndTime());
                BigDecimal discardSignAfterConfirmedAmount = new BigDecimal(discardSignAfterGetCostData_type.getJSONObject("result").getString("confirmedAmount"));//确认收入
                Assert.assertEquals(discardSignAfterConfirmedAmount, discardRefundAfterConfirmedAmount_onlyAmount.subtract(unpaidAmount.setScale(2, RoundingMode.HALF_UP)), "作废购买订单成功后，数据中心-财务中心-营收明细-物品的确认收入应减少对应的金额");
            }
        }

        }

        }

    }
