package com.xiaomai.cases.polar.data.financeData;

import com.alibaba.fastjson.JSONObject;
import com.xiaomai.cases.polar.finance.order.OrderTools;
import com.xiaomai.cases.polar.member.Tools;
import com.xiaomai.cases.polar.memberCard.CardTools;
import com.xiaomai.enums.ApiModule;
import com.xiaomai.enums.LoginAccount;
import com.xiaomai.enums.RequestType;
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 TestGetOrderData extends XMBaseTest {

    OrderTools orderTools = new OrderTools();
    Tools tools = new Tools();

    CardTools cardTools=new CardTools();

    FinanceDataTools financeDataTools=new FinanceDataTools();

    String memberId;
    String cardId;


    @BeforeMethod
    public void beforeTest(){
        xmAppApi.setApiModule(ApiModule.Polar_Data)
                .setApiName("API_getOrderData")
                .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 testGetOrderData(){



        //先查一下数据中心-财务数据-订单数据汇总
        JSONObject beforeGetOrderData=financeDataTools.getOrderData("DAY",TimeUtils.getTodayTime(),TimeUtils.getTodayEndTime());
        BigDecimal beforeActualAmount=new BigDecimal(beforeGetOrderData.getJSONObject("result").getString("actualAmount"));//实收金额
        BigDecimal beforeReceivableAmount=new BigDecimal(beforeGetOrderData.getJSONObject("result").getString("receivableAmount"));//应收金额
        BigDecimal beforeRefundAmount=new BigDecimal(beforeGetOrderData.getJSONObject("result").getString("refundAmount"));//退款金额
        BigDecimal beforeUnpaidAmount=new BigDecimal(beforeGetOrderData.getJSONObject("result").getString("unpaidAmount"));//欠费金额

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

        //①创建部分支付订单，订单应收金额、订单实收金额和欠费金额应增加对应的数据
        //造订单相关数据
        String name = "创建订单潜在会员"+ RandomStringUtil.randomString(3);
        String phone = RandomStringUtil.randomMobile("666");

        //获取会员ID,没有则新建一个
        int memberTotal = Integer.parseInt(tools.search("NORMAL","NORMAL").getJSONObject("result").getString("total"));
        if (memberTotal == 0) {
            memberId = tools.create(name,phone).getString("result");
        }
        memberId=tools.search("NORMAL","NORMAL").getJSONObject("result").getJSONArray("records").getJSONObject(0).getString("id");

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

        //获取会员卡信息
        //获取会员卡列表,没有则新建一个
        int cardTotal = Integer.parseInt(orderTools.fetchPageOfMemberCard("次卡","MEMBER_CARD").getJSONObject("result").getString("total"));
        if (cardTotal == 0) {
            cardId = cardTools.memberCardCreate("次卡-创建订单会员卡"+TimeUtils.getCurrentTime()).getString("result");
        }
        JSONObject memberCard=orderTools.fetchPageOfMemberCard("次卡","MEMBER_CARD");
        cardId=memberCard.getJSONObject("result").getJSONArray("records").getJSONObject(0).getString("id");
        BigDecimal quantity= new BigDecimal(memberCard.getJSONObject("result").getJSONArray("records").getJSONObject(0).getJSONArray("benefitList").getJSONObject(0).getString("balance"));
        float price= Float.parseFloat(memberCard.getJSONObject("result").getJSONArray("records").getJSONObject(0).getString("price"));
        int validPeriod= Integer.parseInt(memberCard.getJSONObject("result").getJSONArray("records").getJSONObject(0).getString("validPeriod"));

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

        //获取签单要用的卡快照id
        String latestSnapshotId=orderTools.fetchDetailById(cardId,xmAppApi.getLoginInfo().getBrandId(),xmAppApi.getLoginInfo().getStudioId(),xmAppApi.getLoginInfo().getAdminId()).getJSONObject("result").getString("latestSnapshotId");

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

        //检查会员对该卡是否超出购买上限
        boolean limitResult=orderTools.checkAllowPurchase("MEMBER_CARD",cardId,memberId,"1",xmAppApi.getLoginInfo().getBrandId(),xmAppApi.getLoginInfo().getStudioId(),xmAppApi.getLoginInfo().getAdminId()).getBoolean("success");

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

        if(limitResult == true) {

            //创建部分支付订单
            JSONObject orderResult = orderTools.signOrder(cardId, latestSnapshotId, quantity, price, validPeriod, latestSnapshotId, 0, "PURCHASE",
                    "MEMBER_CARD", memberId, price, price / 2, "1");
            String getDetailId = orderResult.getString("result");

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

            //获取订单详情
            JSONObject getDetailResult = orderTools.getDetail(getDetailId);
            BigDecimal receivableAmount = new BigDecimal(getDetailResult.getJSONObject("result").getString("receivableAmount"));//应收金额
            BigDecimal paidAmount = new BigDecimal(getDetailResult.getJSONObject("result").getString("paidAmount"));//已支付金额
            BigDecimal unpaidAmount = new BigDecimal(getDetailResult.getJSONObject("result").getString("unpaidAmount"));//欠费金额


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


            JSONObject getOrderData = new JSONObject();
            getOrderData.put("dateType", "DAY");
            getOrderData.put("endTime", TimeUtils.getTodayEndTime());
            getOrderData.put("startTime", TimeUtils.getTodayTime());
            getOrderData.put("brandId", xmAppApi.getLoginInfo().getBrandId());
            getOrderData.put("studioId", xmAppApi.getLoginInfo().getStudioId());
            getOrderData.put("operatorId", xmAppApi.getLoginInfo().getAdminId());

            xmAppApi.doRequest(RequestType.JSON, params, getOrderData.toJSONString(), headers).assetsSuccess(true);
            JSONObject getOrderDataResult = xmAppApi.getBodyInJSON();
            BigDecimal afterActualAmount=new BigDecimal(getOrderDataResult.getJSONObject("result").getString("actualAmount"));//实收金额
            BigDecimal afterReceivableAmount=new BigDecimal(getOrderDataResult.getJSONObject("result").getString("receivableAmount"));//应收金额
            BigDecimal afterRefundAmount=new BigDecimal(getOrderDataResult.getJSONObject("result").getString("refundAmount"));//退款金额
            BigDecimal afterUnpaidAmount=new BigDecimal(getOrderDataResult.getJSONObject("result").getString("unpaidAmount"));//欠费金额
            Assert.assertEquals(getOrderDataResult.getString("success"), "true", "获取销售数据-数据分析-汇总失败");

            //校验新增部分支付订单之后，订单应收金额、订单实收金额、欠费金额有没有增加
            Assert.assertEquals(afterReceivableAmount, beforeReceivableAmount.add(receivableAmount.setScale(2, RoundingMode.HALF_UP)),"创建部分支付订单，数据中心-订单数据汇总没有增加对应的应收金额");
            Assert.assertEquals(afterActualAmount,beforeActualAmount.add(paidAmount.setScale(2,RoundingMode.HALF_UP)),"创建部分支付订单，数据中心-订单数据汇总没有增加对应的实收金额");
            Assert.assertEquals(afterUnpaidAmount, beforeUnpaidAmount.add(unpaidAmount.setScale(2,RoundingMode.HALF_UP)),"创建部分支付订单，数据中心-订单数据汇总没有增加对应的欠费金额");



            //②创建部分支付订单，订单实收金额应增加继续收款金额，欠费金额应减少继续收款金额
            //继续收款
            JSONObject pay=orderTools.pay(unpaidAmount,"1",getDetailId);

            //获取订单详情
            JSONObject getDetailResult1 = orderTools.getDetail(getDetailId);
            BigDecimal receivableAmount1 = new BigDecimal(getDetailResult1.getJSONObject("result").getString("receivableAmount"));//应收金额
            BigDecimal paidAmount1 = new BigDecimal(getDetailResult1.getJSONObject("result").getString("paidAmount"));//已支付金额


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

            //校验继续收款后欠费金额-继续收款支付金额，实收金额+继续收款支付金额
            JSONObject afterGetOrderData1=financeDataTools.getOrderData("DAY",TimeUtils.getTodayTime(),TimeUtils.getTodayEndTime());
            BigDecimal afterActualAmount1=new BigDecimal(afterGetOrderData1.getJSONObject("result").getString("actualAmount"));//实收金额
            BigDecimal afterReceivableAmount1=new BigDecimal(afterGetOrderData1.getJSONObject("result").getString("receivableAmount"));//应收金额
            BigDecimal afterRefundAmount1=new BigDecimal(afterGetOrderData1.getJSONObject("result").getString("refundAmount"));//退款金额
            BigDecimal afterUnpaidAmount1=new BigDecimal(afterGetOrderData1.getJSONObject("result").getString("unpaidAmount"));//欠费金额

            Assert.assertEquals(afterActualAmount1,afterActualAmount.add(unpaidAmount.setScale(2,RoundingMode.HALF_UP)),"继续收款后，订单实收金额未增加继续收款支付金额");
            Assert.assertEquals(afterUnpaidAmount1,afterUnpaidAmount.subtract(unpaidAmount.setScale(2,RoundingMode.HALF_UP)),"继续收款后，欠费金额未减少继续收款支付金额");



            //③退单之后，退款金额应增加实退金额，其余金额不变
            //退单
            //查询要退的卡id 从listUserRefundableCard-查询用户可退的会员卡列表中获取

            JSONObject listUserRefundableCardResult=orderTools.listUserRefundableCard("MEMBER","",memberId);
            String listUserRefundableId=listUserRefundableCardResult.getJSONArray("result").getJSONObject(0).getString("id");


            //查询订单或者收支可退流水金额（包含乐动收银状态信息）
            boolean checkRefundableAmountResult=orderTools.checkRefundableAmount(getDetailId,price - price / 2).getBoolean("success");

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

            if(checkRefundableAmountResult == true) {

                //退单-会员卡
                JSONObject refundOrderResult = orderTools.refundOrder(0, listUserRefundableId, quantity, price , "MEMBER_CARD",
                        memberId, price, price , "1");
                String refundOrderGetDetailId = refundOrderResult.getString("result");//退单订单ID

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

                //获取退单订单详情
                JSONObject refundOrderGetDetailResult = orderTools.getDetail(refundOrderGetDetailId);
                BigDecimal refundOrderReceivableAmount = new BigDecimal(refundOrderGetDetailResult.getJSONObject("result").getString("receivableAmount"));//退单订单的应退金额
                BigDecimal refundOrderPaidAmount = new BigDecimal(refundOrderGetDetailResult.getJSONObject("result").getString("paidAmount"));//退单订单的实退金额

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

                //校验退单之后，退款金额+实退金额，其余金额不变
                //获取财务中心-订单数据-汇总
                JSONObject afterGetOrderData2=financeDataTools.getOrderData("DAY",TimeUtils.getTodayTime(),TimeUtils.getTodayEndTime());
                BigDecimal afterActualAmount2=new BigDecimal(afterGetOrderData2.getJSONObject("result").getString("actualAmount"));//实收金额
                BigDecimal afterReceivableAmount2=new BigDecimal(afterGetOrderData2.getJSONObject("result").getString("receivableAmount"));//应收金额
                BigDecimal afterRefundAmount2=new BigDecimal(afterGetOrderData2.getJSONObject("result").getString("refundAmount"));//退款金额
                BigDecimal afterUnpaidAmount2=new BigDecimal(afterGetOrderData2.getJSONObject("result").getString("unpaidAmount"));//欠费金额

                Assert.assertEquals(afterActualAmount2,afterActualAmount1,"退单后，订单实收金额应不变");
                Assert.assertEquals(afterReceivableAmount2,afterReceivableAmount1,"退单后，订单应收金额应不变");
                Assert.assertEquals(afterRefundAmount2,afterRefundAmount1.add(refundOrderPaidAmount.setScale(2,RoundingMode.HALF_UP)),"退单后，退款金额未增加");
                Assert.assertEquals(afterUnpaidAmount2,afterUnpaidAmount1,"退单后，欠费金额应不变");



                //④退单订单作废-退款金额减掉实退金额，其余金额不变
                //退单订单作废
                //校验是否可以作废退单订单
                boolean checkDiscardRefundVoucherResult = orderTools.checkDiscardVoucher(refundOrderGetDetailId).getBoolean("success");

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

                if (checkDiscardRefundVoucherResult == true) {
                    //作废退单订单
                    JSONObject refundDiscardResult = orderTools.discard(refundOrderGetDetailId, "重复录入", "已作废退单订单" + RandomStringUtil.randomString(10));


                    //获取财务中心-订单数据-汇总
                    JSONObject afterGetOrderData3 = financeDataTools.getOrderData("DAY", TimeUtils.getTodayTime(), TimeUtils.getTodayEndTime());
                    BigDecimal afterActualAmount3 = new BigDecimal(afterGetOrderData3.getJSONObject("result").getString("actualAmount"));//实收金额
                    BigDecimal afterReceivableAmount3 = new BigDecimal(afterGetOrderData3.getJSONObject("result").getString("receivableAmount"));//应收金额
                    BigDecimal afterRefundAmount3 = new BigDecimal(afterGetOrderData3.getJSONObject("result").getString("refundAmount"));//退款金额
                    BigDecimal afterUnpaidAmount3 = new BigDecimal(afterGetOrderData3.getJSONObject("result").getString("unpaidAmount"));//欠费金额



                    //校验：
                    Assert.assertEquals(afterActualAmount3, afterActualAmount2, "退单订单作废后，订单实收金额应不变");
                    Assert.assertEquals(afterReceivableAmount3, afterReceivableAmount2, "退单订单作废后，订单应收金额应不变");
                    Assert.assertEquals(afterRefundAmount3, afterRefundAmount2.subtract(refundOrderPaidAmount.setScale(2, RoundingMode.HALF_UP)), "退单订单作废后，退款金额未减少");
                    Assert.assertEquals(afterUnpaidAmount3, afterUnpaidAmount2, "退单订单作废后，欠费金额应不变");


                    //⑤签单订单作废，订单应收金额和订单实收金额应减少，其余金额不变
                    //签单订单作废
                    //校验是否可以作废签单订单
                    boolean checkDiscardSignVoucherResult = orderTools.checkDiscardVoucher(getDetailId).getBoolean("success");

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

                    if (checkDiscardSignVoucherResult == true) {

                        //作废签单订单
                        JSONObject discardResult = orderTools.discard(getDetailId, "重复录入", "已作废签单订单" + RandomStringUtil.randomString(10));
                    }
                    try {
                        Thread.sleep(3000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }


                    //获取财务中心-订单数据-汇总
                    JSONObject afterGetOrderData4 = financeDataTools.getOrderData("DAY", TimeUtils.getTodayTime(), TimeUtils.getTodayEndTime());
                    BigDecimal afterActualAmount4 = new BigDecimal(afterGetOrderData4.getJSONObject("result").getString("actualAmount"));//实收金额
                    BigDecimal afterReceivableAmount4 = new BigDecimal(afterGetOrderData4.getJSONObject("result").getString("receivableAmount"));//应收金额
                    BigDecimal afterRefundAmount4 = new BigDecimal(afterGetOrderData4.getJSONObject("result").getString("refundAmount"));//退款金额
                    BigDecimal afterUnpaidAmount4 = new BigDecimal(afterGetOrderData4.getJSONObject("result").getString("unpaidAmount"));//欠费金额

                    //校验：
                    Assert.assertEquals(afterActualAmount4, afterActualAmount3.subtract(paidAmount1.setScale(2,RoundingMode.HALF_UP)), "签单订单作废后，订单实收金额未减少");
                    Assert.assertEquals(afterReceivableAmount4, afterReceivableAmount3.subtract(receivableAmount1.setScale(2,RoundingMode.HALF_UP)), "签单订单作废后，订单应收金额未减少");
                    Assert.assertEquals(afterRefundAmount4, afterRefundAmount3, "签单订单作废后，退款金额应不变");
                    Assert.assertEquals(afterUnpaidAmount4, afterUnpaidAmount3, "签单订单作废后，欠费金额应不变");

                }
            }
        }
    }
}
