package com.jwipc.finance.dto;


import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import com.jwipc.finance.entity.FinPaymentConfirmLog;
import com.jwipc.finance.entity.PaymentCodApplyDetail;
import com.jwipc.finance.entity.PaymentCodApply;
import lombok.Data;
import org.apache.commons.lang3.StringUtils;
import org.springframework.format.annotation.DateTimeFormat;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;

/**
 * <p>
 *     对账付款申请数据保存实体类
 * </p>
 *
 * @author li.kui
 * @version 1.0
 * @since 2020/9/27
 */
@Data
public class PaymentCodApplySaveDTO {
    /**
     * 保存类型 1:新增 2:编辑
     */
    private Integer saveType;
    private BigDecimal refundAmount;

    /**
     * 变更单审批状态；0-审批中  1-审批通过  2-审批驳回
     */
    private Integer changeStatus;
    /**
     * 是否推送OA 0:否 1:是
     */
    private Integer isPushOa;

    /**
     * 对账付款申请ID
     */
    private Long id;
    private Integer urgentFlag;
    /**
     * 对账付款申请单号
     */
    private String cpApplyNo;
    /**
     * 申请付款金额
     */
    private BigDecimal applyPaymentAmount;
    /**
     * 付款公司代码
     */
    private String companyCode;
    /**
     * 付款公司名称
     */
    private String companyName;
    /**
     * 工厂代码
     */
    private String factoryCode;
    /**
     * 工厂名称
     */
    private String factoryName;
    /**
     * 供应商编码
     */
    private String supplierCode;
    /**
     * 供应商名称
     */
    private String supplierName;
    /**
     * 供应商编码
     */
    private String paymentSupplierCode;
    /**
     * 供应商名称
     */
    private String paymentSupplierName;
    private Integer collectionFlag;
    /**
     * 供应商银行代码/供应商开户行代码/供应商联行号
     */
    private String supBankCode;
    /**
     * 供应商银行名称/供应商开户行名称
     */
    private String supBankName;
    /**
     * 供应商银行账号
     */
    private String supBankAccount;
    /**
     * 付款委托书附件
     */
    private String paymentFiles;
    /**
     * 供应商银行代码
     */
    private String bankCode;
    /**
     * 供应商银行国际代码
     */
    private String bankInterCode;
    /**
     * 币种
     */
    private String currencyCode;
    /**
     * 付款方式编码
     */
    private String paymentWayCode;
    /**
     * 付款方式描述
     */
    private String paymentWayDesc;
    /**
     * 申请备注
     */
    private String applyRemark;

    /**
     * 项目经理
     */
    private String oaProjectManager;
    /**
     * 项目经理编码
     */
    private String oaProjectManagerCode;

    private BigDecimal budInnerMoney;

    private BigDecimal budOutMoney;
    private String oaSubKey;
    private String oaDepKey;
    private String oaYear;
    private String oaDemandDep;
    private String oaAleradyPayMoney;
    private String oaPlantArea;
    private String oaContract;
    private String oaDeviceName;
    private String oaSpecs;
    private String oaUnit;
    private BigDecimal oaNum;
    private BigDecimal oaQuaeterBud;
    private BigDecimal oaBudInnerMoney;
    private BigDecimal oaBudOutMoney;
    private BigDecimal oaBalance;
    private String oaUrgencyDegree;
    private String oaSubName;
    private String oaCode;
    private String oaDepName;
    private String oaQuarter;
    private String oaType;
    private String files;
    private BigDecimal oaContractMoney;

    /**
     * 实际应付金额
     */
    private BigDecimal actualityPayMoney;
    /**
     * 付款计划金额，如果没有则为0
     */
    private BigDecimal payPlanMoney =  BigDecimal.ZERO;

    /**
     * 付款用途
     */
    private String paymentPurpose;

    /**
     * 付款用途描述
     */
    private String paymentPurposeDesc;

    /**
     * 供应商退款（1：是，0：否）
     */
    private String supplierReturn;
    /**
     * 创建时间
     */
    @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")
    private Date createTime;

    /**
     * 费用部门编码
     */
    private String costDeptCode;

    /**
     * 费用部门名称
     */
    private String costDeptName;


    /**
     * 使用人编码
     */
    private String useCode;

    /**
     * 使用人名称
     */
    private String useName;


    /**
     * 主管BP经理编码
     */
    private String BPCode;

    /**
     * 主管BP经理名称
     */
    private String BPName;

    /**
     * 费用科目
     */
    private String expenseAccount;

    /**
     * 费用科目名称
     */
    private String expenseAccountName;
    /**
     * 设备验收人code
     */
    private String  oaDevicePersonCode;
    /**
     * 设备验收人
     */
    private String oaDevicePerson;
    /**
     * 固定资产code
     */
    private String oaFixedAssetsCode;
    /**
     * 承兑金额
     */
    private BigDecimal oaAcceptanceMoney;
    /**
     * 转账金额
     */
    private BigDecimal oaTransferMoney;
    /**
     * 维修内容
     */
    private String oaRepairContent;
    /**
     * 会计主管
     */
    private String oaAccountantCharge;
    /**
     * 会计主管code
     */
    private String oaAccountantChargeCode;
    /**
     * 经办人
     */
    private String oaHandler;
    /**
     * 经办人code
     */
    private String oaHandlerCode;
    /**
     * 费用归属
     */
    private String oaCostAttribution;
    /**
     * 合同号
     */
    private String contractNo;
    /**
     * 流程类型
     */
    private Integer processId;
    /**
     * 研发项目
     */
    private String rdProject;
    /**
     * 用途
     */
    private String purpose;
    /**
     * 借款金额
     */
    private BigDecimal oaBorrowMoney;

    private Integer isSafeProductionCost;

    private Integer isOa;

    private String oaProcessCode;

    private String oaProjectName;
    private String oaChildProjectName;

    private String codFjid;

    private Integer oaHireType;
    /**
     * 年度预算代码
     */
    private String oaYearBudget;
    /**
     * 申请人工号
     */
    private String oaApplyUserCode;
    /**
     * 申请人名称
     */
    private String oaApplyUserName;
    /**
     * OA项目
     */
    private String oaXm;
    /**
     * OA业务科目
     */
    private String oaYwkm;
    /**
     * llkzj
     */
    private String llkzj;

    /**
     * 申请明细数据
     */
    private List<ApplyDetail> itemList;


    /**
     * 编辑时删除的明细ID
     */
    private List<DelDetail> delItemIdList;


    /**
     * 是否提前付款；0-否；1-是
     */
    private Integer advancePaymentFlag;

    /**
     * 承兑期限
     */
    private String acceptanceMethod;

    /**
     * 报关公司编码
     */
    private String faSupplier;

    /**
     * 报关公司名称
     */
    private String faSupplierName;

    private String businessType;

    /**
     * 付款公司
     */
    private String paymentCompanyCode;

    /**
     * 收款单位
     */
    private String paymentCompanyName;

    /**
     * 收款地址
     */
    private String bankAddress;
    /**
     * 逾期款项
     */
    private BigDecimal overdueAmount;
    /**
     * 到期款项
     */
    private BigDecimal dueAmount;
    /**
     * 应付账款余额
     */
    private BigDecimal accountsPayableBalance;
    /**
     * 暂估余额
     */
    private BigDecimal provisionalBalance;
    private String feePayer;

    /**
     * 警告日志
     */
    private List<FinPaymentConfirmLog> logDetailList;

    @Data
    public static class DelDetail {
        /**
         * 明细id
         */
        private Long id;
        /**
         * 寻源单据id
         */
        private Long sourceId;
        /**
         * 数据类型 Z001:预付款 Z003:票到付款
         */
        private String amountType;
    }
    /**
     * 申请明细
     */
    @Data
    public static class ApplyDetail {
        /**
         * 申请名细ID
         */
        private Long id;
        /**
         * 数据类型 Z001:预付款 Z003:票到付款
         */
        private String amountType;
        /**
         * 发票正负向标识 1:正向 2:负向
         */
        private Integer posNegFlag;
        /**
         * 到货付款申请ID
         */
        private Long cppId;
        /**
         * 到货付款申请单号
         */
        private String cppNo;
        /**
         * 采购订单号
         */
        private String poCode;
        /**
         * 订单行号
         */
        private String poItemNo;
        /**
         * 订单数量
         */
        private BigDecimal poNum;
        /**
         * 物料编码
         */
        private String materialCode;
        /**
         * 物料描述
         */
        private String materialDesc;
        /**
         * 单位
         */
        private String materialUnit;
        /**
         * 税率代码
         */
        private String taxCode;
        /**
         * 税率描述
         */
        private String taxDesc;
        /**
         * 税率值(0.13)
         */
        private BigDecimal taxValue;
        /**
         * 未税单价
         */
        private BigDecimal ntPrice;
        /**
         * 含税单价
         */
        private BigDecimal itPrice;
        /**
         * 未税金额
         */
        private BigDecimal ntAmount;
        /**
         * 含税金额
         */
        private BigDecimal itAmount;
        /**
         * 税额
         */
        private BigDecimal dtAmount;
        /**
         * 本次申请付款金额
         */
        private BigDecimal currApAmount;
        /**
         * 行备注
         */
        private String itemRemark;
        /**
         * 询源采购组编码
         */
        private String seekPgCode;
        /**
         * 询源采购组名称
         */
        private String seekPgName;
        /**
         * 订单付款方式编码
         */
        private String ppwCode;
        /**
         * 订单付款方式描述
         */
        private String ppwDesc;
        /**
         * 订单付款条件编码
         */
        private String ppcCode;
        /**
         * 订单付款条件描述
         */
        private String ppcDesc;
        /**
         * 物料凭证
         */
        private String mvCode;
        /**
         * 物料凭证行号
         */
        private String mvItemNo;
        /**
         * 物料凭证过账日期
         */
        private String mvPostDate;
        /**
         * 物料凭证入库数量
         */
        private BigDecimal mvNum;
        /**
         * SAP发票年度
         */
        private String invoiceYear;
        /**
         * SAP发票号
         */
        private String invoiceNo;
        /**
         * SAP发票行项目号
         */
        private String invoiceItemNo;
        /**
         * SAP发票过账日期
         */
        private String invoicePostDate;
        /**
         * SAP发票文本
         */
        private String invoiceText;
        /**
         * 发票付款方式编码
         */
        private String ipwCode;
        /**
         * 发票付款方式描述
         */
        private String ipwDesc;
        /**
         * 发票付款条件编码
         */
        private String ipcCode;
        /**
         * 发票付款条件描述
         */
        private String ipcDesc;
        /**
         * (集采)采购凭证编号
         */
        private String jcPoCode;
        /**
         * (集采)采购凭证行号
         */
        private String jcPoItemNo;
        /**
         * 集采工厂
         */
        private String jcFactoryCode;

        private Long sourceId;
        /**
         * 是否全部被消费 0：未使用完全 1：全部使用
         */
        private Integer isUsed;

        private BigDecimal budInnerMoney;
        private BigDecimal budOutMoney;

        private String contractNo;

        private String contractName;

        private String subjectTypeCode;
        private String accountStatementNo;
        private BigDecimal strikePriceAmount;
        private BigDecimal actualUnpaidAmount;
        private BigDecimal discountMoney;

        /**
         * 邮件发送标识
         */
        private Integer sendEmailCollectionFlag;
        @DateTimeFormat(pattern = "yyyy-MM-dd")
        private LocalDateTime expectationPaymentDate;


        /**
         * 提交的数据转表结构
         *
         * @return 结果
         */
        public PaymentCodApplyDetail toPcaDetail(){
            PaymentCodApplyDetail detail = new PaymentCodApplyDetail();
            detail.setId(this.id);
            detail.setAmountType(this.amountType);
            detail.setPosNegFlag(this.posNegFlag);
            detail.setCppId(this.cppId);
            detail.setCppNo(this.cppNo);
            detail.setPoCode(this.poCode);
            detail.setPoItemNo(this.poItemNo);
            detail.setPoNum(this.poNum);
            detail.setMaterialCode(this.materialCode);
            detail.setMaterialDesc(this.materialDesc);
            detail.setMaterialUnit(this.materialUnit);
            detail.setTaxCode(this.taxCode);
            detail.setTaxDesc(this.taxDesc);
            detail.setTaxValue(this.taxValue);
            detail.setNtPrice(this.ntPrice);
            detail.setItPrice(this.itPrice);
            detail.setNtAmount(this.ntAmount);
            detail.setItAmount(this.itAmount);
            detail.setDtAmount(this.dtAmount);
            detail.setBudInnerMoney(this.budInnerMoney);
            detail.setBudOutMoney(this.budOutMoney);
            detail.setItemRemark(this.itemRemark);
            detail.setSeekPgCode(this.seekPgCode);
            detail.setSeekPgName(this.seekPgName);
            detail.setPpwCode(this.ppwCode);
            detail.setPpwDesc(this.ppwDesc);
            detail.setPpcCode(this.ppcCode);
            detail.setPpcDesc(this.ppcDesc);
            detail.setMvCode(this.mvCode);
            detail.setMvItemNo(this.mvItemNo);
            if(!"0000-00-00".equals(this.mvPostDate) && StringUtils.isNotEmpty(this.mvPostDate)){
                detail.setMvPostDate(LocalDateTimeUtil.parse(this.mvPostDate, "yyyy-MM-dd"));
            }
            detail.setMvNum(this.mvNum);
            detail.setInvoiceYear(this.invoiceYear);
            detail.setInvoiceNo(this.invoiceNo);
            detail.setInvoiceItemNo(this.invoiceItemNo);
            if(!"0000-00-00".equals(this.invoicePostDate) && StringUtils.isNotEmpty(this.invoicePostDate)){
                detail.setInvoicePostDate(LocalDateTimeUtil.parse(this.invoicePostDate, "yyyy-MM-dd"));
            }
            detail.setInvoiceText(this.invoiceText);
            detail.setIpwCode(this.ipwCode);
            detail.setIpwDesc(this.ipwDesc);
            detail.setIpcCode(this.ipcCode);
            detail.setIpcDesc(this.ipcDesc);
            detail.setJcPoCode(this.jcPoCode);
            detail.setJcPoItemNo(this.jcPoItemNo);
            detail.setJcFactoryCode(this.jcFactoryCode);
            detail.setSourceId(this.sourceId);
            detail.setContractNo(this.contractNo);
            detail.setContractName(this.contractName);
            detail.setSubjectTypeCode(this.subjectTypeCode);
            detail.setAccountStatementNo(this.accountStatementNo);
            detail.setStrikePriceAmount(this.strikePriceAmount);
            detail.setActualUnpaidAmount(this.actualUnpaidAmount);
            detail.setDiscountMoney(this.discountMoney);
            detail.setExpectationPaymentDate(this.expectationPaymentDate);
            // 数据主键: 款项类型_采购订单号_订单行号_发票年度_发票号_发票行号
//            String dataKey = this.amountType + "_" + this.posNegFlag + "_" + this.poCode + "_" +this.poItemNo + "_" +this.invoiceYear + "_" +this.invoiceNo  + "_" +this.invoiceItemNo;
            String dataKey = this.accountStatementNo;
            detail.setDataKey(dataKey);

            return detail;
        }
    }


    /**
     * 提交数据转表结构
     *
     * @return 结果
     */
    public PaymentCodApply toPca(){
        PaymentCodApply apply = new PaymentCodApply();
        apply.setId(this.id);
        apply.setCpApplyNo(this.cpApplyNo);
        apply.setBudInnerMoney(this.budInnerMoney);
        apply.setBudOutMoney(this.budOutMoney);
        apply.setCompanyCode(this.companyCode);
        apply.setCompanyName(this.companyName);
        apply.setFactoryCode(this.factoryCode);
        apply.setRefundAmount(this.refundAmount);
        apply.setUrgentFlag(this.urgentFlag);
        apply.setFactoryName(this.factoryName);
        apply.setFeePayer(this.feePayer);
        apply.setSupplierCode(this.supplierCode);
        apply.setSupplierName(this.supplierName);
        apply.setPaymentSupplierCode(this.paymentSupplierCode);
        apply.setPaymentSupplierName(this.paymentSupplierName);
        apply.setCollectionFlag(this.collectionFlag);
        apply.setSupBankCode(this.supBankCode);
        apply.setSupBankName(this.supBankName);
        apply.setSupBankAccount(this.supBankAccount);
        apply.setBankCode(this.bankCode);
        apply.setBankInterCode(this.bankInterCode);
        apply.setCurrencyCode(this.currencyCode);
        apply.setPaymentWayCode(this.paymentWayCode);
        apply.setPaymentFiles(this.paymentFiles);
        apply.setPaymentWayDesc(this.paymentWayDesc);
        apply.setOaSubKey(this.oaSubKey);
        apply.setOaDepKey(this.oaDepKey);
        apply.setOaYear(this.oaYear);
        apply.setOaDemandDep(this.oaDemandDep);
        if(StringUtils.isNotEmpty(this.oaAleradyPayMoney)){
            apply.setOaAleradyPayMoney(new BigDecimal(this.oaAleradyPayMoney));
        }
        apply.setOaPlantArea(this.oaPlantArea);
        apply.setOaContract(this.oaContract);
        apply.setBudInnerMoney(this.budInnerMoney);
        apply.setBudOutMoney(this.budOutMoney);
        apply.setOaDeviceName(this.oaDeviceName);
        apply.setOaSpecs(this.oaSpecs);
        apply.setOaUnit(this.oaUnit);
//        apply.setOaNum(this.oaNum.toPlainString());
        apply.setOaQuaeterBud(this.oaQuaeterBud);
        apply.setOaBudOutMoney(this.oaBudOutMoney);
        apply.setOaBudInnerMoney(this.oaBudInnerMoney);
        apply.setOaBalance(this.oaBalance);
        apply.setOaUrgencyDegree(this.oaUrgencyDegree);
        apply.setOaSubName(this.oaSubName);
        apply.setOaCode(this.oaCode);
        apply.setOaDepName(this.oaDepName);
        apply.setOaQuarter(this.oaQuarter);
        apply.setOaType(this.oaType);
        apply.setApplyRemark(this.applyRemark);
        apply.setApplyRemark(this.applyRemark);
        apply.setOaDevicePersonCode(this.oaDevicePersonCode);
        apply.setOaDevicePerson(this.oaDevicePerson);
        apply.setOaFixedAssetsCode(this.oaFixedAssetsCode);
        apply.setOaAcceptanceMoney(this.oaAcceptanceMoney);
        apply.setOaTransferMoney(this.oaTransferMoney);
        apply.setOaRepairContent(this.oaRepairContent);
        apply.setOaAccountantCharge(this.oaAccountantCharge);
        apply.setOaAccountantChargeCode(this.oaAccountantChargeCode);
        apply.setOaHandler(this.oaHandler);
        apply.setOaHandlerCode(this.oaHandlerCode);
        apply.setOaCostAttribution(this.oaCostAttribution);
        apply.setContractNo(this.contractNo);
        apply.setProcessId(this.processId);
        apply.setRdProject(this.rdProject);
        apply.setPurpose(this.purpose);
        apply.setOaContractMoney(this.oaContractMoney);
        apply.setOaBorrowMoney(this.oaBorrowMoney);
//        apply.setIsSafeProductionCost(this.isSafeProductionCost.byteValue());
        apply.setIsOa(this.isOa);
        apply.setOaProcessCode(this.oaProcessCode);
        apply.setOaProjectName(this.oaProjectName);
        apply.setOaChildProjectName(this.oaChildProjectName);
//        apply.setOaHireType(this.oaHireType.toString());
        apply.setOaYearBudget(this.oaYearBudget);
        apply.setOaApplyUserCode(this.oaApplyUserCode);
        apply.setOaApplyUserName(this.oaApplyUserName);
        apply.setOaProjectManager(this.oaProjectManager);
        apply.setOaProjectManagerCode(this.oaProjectManagerCode);
        apply.setCostDeptCode(this.costDeptCode);
        apply.setCostDeptName(this.costDeptName);
        apply.setUseCode(this.useCode);
        apply.setUseName(this.useName);
        apply.setBpCode(this.BPCode);
        apply.setBpName(this.BPName);
        apply.setCreateTime(LocalDateTimeUtil.of(this.createTime));
        apply.setExpenseAccount(this.expenseAccount);
        apply.setExpenseAccountName(this.expenseAccountName);
        apply.setOaXm(this.oaXm);
        apply.setOaYwkm(this.oaYwkm);
        apply.setLlkzj(this.llkzj);
        apply.setFiles(this.files);
        apply.setAdvancePaymentFlag(this.advancePaymentFlag);
        apply.setAcceptanceMethod(this.acceptanceMethod);
        apply.setFaSupplier(this.faSupplier);
        apply.setFaSupplierName(this.faSupplierName);
        apply.setActualityPayMoney(this.actualityPayMoney);
        apply.setPayPlanMoney(this.payPlanMoney);
        apply.setPaymentPurpose(this.paymentPurpose);
        apply.setPaymentPurposeDesc(this.getPaymentPurposeDesc());
        apply.setSupplierReturn(this.supplierReturn);
        apply.setBusinessType(this.businessType);
        apply.setPaymentCompanyCode(this.paymentCompanyCode);
        apply.setPaymentCompanyName(this.paymentCompanyName);
        apply.setBankAddress(this.bankAddress);
        apply.setOverdueAmount(this.overdueAmount);
        apply.setDueAmount(this.dueAmount);
        apply.setAccountsPayableBalance(this.accountsPayableBalance);
        apply.setProvisionalBalance(this.provisionalBalance);
        return apply;
    }
}
