package cn.iocoder.yudao.module.order.dto;

import cn.iocoder.yudao.framework.excel.annotations.DictFormat;
import cn.iocoder.yudao.framework.excel.convert.DictConvert;
import cn.iocoder.yudao.module.depository.dto.LogisticsInfoDto;
import com.alibaba.excel.annotation.ExcelIgnore;
import com.alibaba.excel.annotation.ExcelProperty;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Objects;

import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;
import static cn.iocoder.yudao.module.bpm.enums.DictTypeConstants.TRANSPORT_TYPE;

/**
 * 根据自编号的维度统计数据：
 * 1.是否结算：结算节点状态
 * 2.NO. 柜号：自编号，非货柜号
 * 3.应收款：自编号下所有订单的（收费数据*原价）+其他费用
 * 4.目的港实收金额：统计自编号下到付的费用明细累加
 * 5.中国实收金额：统计自编号下所有订单预付费用明细累加
 * 6.折扣：自编号下所有订单（所有品名线路原始价格*收费数据）-（成交单价*收费数据）
 */
@Data
@ApiModel("订单费用汇总")
public class OrderCostSummaryDto {

    @ExcelProperty(value = "序号", index = 0)
    @ApiModelProperty(value = "序号")
    private String no;

    @ExcelIgnore
    @ApiModelProperty(value = "主键ID", required = true)
    private Long orderId;

    @ExcelProperty(value = "订单号", index = 1)
    @ApiModelProperty(value = "订单编号", required = true)
    private String orderNo;

    @ExcelIgnore
    @ApiModelProperty(value = "快递单号")
    private String number;

    @ExcelIgnore
    @ApiModelProperty(value = "提单编号")
    private String tidanNo;

    @ExcelIgnore
    @ApiModelProperty(value = "父订单id")
    private Long parentOrderId;

    @ExcelIgnore
    @ApiModelProperty(value = "旧编号")
    private String oldNumbers;

    @ExcelIgnore
    @ApiModelProperty(value = "货柜自编号")
    private String containerNumber;

    @ExcelProperty(value = "唛头", index = 2)
    @ApiModelProperty(value = "唛头")
    private String marks;

    @ExcelIgnore
    @ApiModelProperty(value = "产品备案属性：1有牌,2无牌,3中性,4混牌")
    private Integer productRecord;

    @ExcelIgnore
    @ApiModelProperty(value = "是否控货")
    private Boolean isCargoControl;

    //    @ExcelIgnore
    @ExcelProperty(value = "订单入仓时间", index = 29)
    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
    @ApiModelProperty(value = "首次入仓时间")
    private Date inTime;

    @ExcelIgnore
//    @ExcelProperty(value = "订单入仓时间",  index = 29)
    @ApiModelProperty(value = "订单入仓时间")
    private String orderInTime;

    //    @ExcelIgnore
    @ExcelProperty(value = "订单装柜时间", index = 28)
    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
    @ApiModelProperty(value = "已装柜时间")
    private Date loadTime;

    @ExcelIgnore
//    @ExcelProperty(value = "订单装柜时间",  index = 28)
    @ApiModelProperty(value = "订单装柜时间")
    private String orderLoadTime;

    @ExcelProperty(value = "客户经理", index = 27)
    @ApiModelProperty(value = "业务经理")
    private String salesmanName;

    /*** 费用信息 ***/

    @ExcelIgnore
    @ApiModelProperty(value = "实收运费")
    private BigDecimal netReceiptsFreightFee;

    @ExcelIgnore
    @ApiModelProperty(value = "实收运费货币分组列表")
    private List<FeeGroupDto> netReceiptsFreightFeeGroupDtoList;

    @ExcelProperty(value = "实收运费", index = 16)
    @ApiModelProperty(value = "实收运费(货币分组列表转换字符串)")
    private String netReceiptsFreightFeeGroup;

    @ExcelIgnore
    @ApiModelProperty(value = "应收运费")
    private BigDecimal receivableFreightFee;

    @ExcelIgnore
    @ApiModelProperty(value = "应收运费货币分组列表")
    private List<FeeGroupDto> receivableFreightFeeGroupDtoList;

    @ExcelProperty(value = "应收运费", index = 14)
    @ApiModelProperty(value = "应收运费(货币分组列表转换字符串)")
    private String receivableFreightFeeGroup;

    @ExcelIgnore
    @ApiModelProperty(value = "运费货币单位ID")
    private Integer seaFreightCurrency;

    @ExcelIgnore
    @ApiModelProperty(value = "运费优惠金额")
    private BigDecimal discountFreightTotalPrice = BigDecimal.ZERO;

    @ExcelIgnore
    @ApiModelProperty(value = "运费优惠金额货币分组列表")
    private List<FeeGroupDto> discountFreightFeeGroupDtoList;

    @ExcelProperty(value = "运费优惠金额", index = 15)
    @ApiModelProperty(value = "运费优惠金额(货币分组列表转换字符串)")
    private String discountFreightFeeGroup;

    @ExcelIgnore
    @ApiModelProperty(value = "已收运费货币分组列表")
    private List<FeeGroupDto> writeOffFreightFeeGroupDtoList;

    @ExcelProperty(value = "已收运费", index = 17)
    @ApiModelProperty(value = "已收运费(货币分组列表转换字符串)")
    private String writeOffFreightFeeGroup;

    @ExcelIgnore
    @ApiModelProperty(value = "实收清关费")
    private BigDecimal netReceiptsClearanceFee;

    @ExcelIgnore
    @ApiModelProperty(value = "实收清关费货币分组列表")
    private List<FeeGroupDto> netReceiptsClearanceFeeGroupDtoList;

    @ExcelProperty(value = "实收清关费", index = 19)
    @ApiModelProperty(value = "实收清关费(货币分组列表转换字符串)")
    private String netReceiptsClearanceFeeGroup;

    @ExcelIgnore
    @ApiModelProperty(value = "应收清关费")
    private BigDecimal receivableClearanceFee;

    @ExcelIgnore
    @ApiModelProperty(value = "应收清关费货币分组列表")
    private List<FeeGroupDto> receivableClearanceFeeGroupDtoList;

    @ExcelProperty(value = "应收清关费", index = 18)
    @ApiModelProperty(value = "应收清关费(货币分组列表转换字符串)")
    private String receivableClearanceFeeGroup;

    @ExcelIgnore
    @ApiModelProperty(value = "清关费货币单位ID")
    private Integer clearanceFreightCurrency;

    @ExcelIgnore
    @ApiModelProperty(value = "清关费优惠金额")
    private BigDecimal discountClearanceFee = BigDecimal.ZERO;

    @ExcelIgnore
    @ApiModelProperty(value = "清关费优惠金额货币分组列表")
    private List<FeeGroupDto> discountClearanceFeeGroupDtoList;

    @ExcelProperty(value = "清关费优惠金额", index = 20)
    @ApiModelProperty(value = "清关费优惠金额(货币分组列表转换字符串)")
    private String discountClearanceFeeGroup;

    @ExcelIgnore
    @ApiModelProperty(value = "已收清关费货币分组列表")
    private List<FeeGroupDto> writeOffClearanceFeeGroupDtoList;

    @ExcelProperty(value = "已收清关费", index = 21)
    @ApiModelProperty(value = "已收额外费用(货币分组列表转换字符串)")
    private String writeOffClearanceFeeGroup;

    @ExcelIgnore
    @ApiModelProperty(value = "实收额外费用")
    private BigDecimal netReceiptsOtherFee;

    @ExcelIgnore
    @ApiModelProperty(value = "实收额外费用货币分组列表")
    private List<FeeGroupDto> netReceiptsOtherFeeGroupDtoList;

    @ExcelProperty(value = "实收额外费用", index = 23)
    @ApiModelProperty(value = "实收额外费用(货币分组列表转换字符串)")
    private String netReceiptsOtherFeeGroup;

    @ExcelIgnore
    @ApiModelProperty(value = "应收额外费用")
    private BigDecimal receivableOtherFee;

    @ExcelIgnore
    @ApiModelProperty(value = "应收额外费用货币分组列表")
    private List<FeeGroupDto> receivableOtherFeeGroupDtoList;

    @ExcelProperty(value = "应收额外费用", index = 22)
    @ApiModelProperty(value = "应收额外费用(货币分组列表转换字符串)")
    private String receivableOtherFeeGroup;

    @ExcelIgnore
    @ApiModelProperty(value = "额外费用货币单位ID")
    private Integer otherFeeCurrency;

    @ExcelIgnore
    @ApiModelProperty(value = "额外费用优惠金额")
    private BigDecimal discountOtherFee = BigDecimal.ZERO;

    @ExcelIgnore
    @ApiModelProperty(value = "额外费用优惠金额货币分组列表")
    private List<FeeGroupDto> discountOtherFeeGroupDtoList;

    @ExcelProperty(value = "额外费用优惠金额", index = 24)
    @ApiModelProperty(value = "额外费用优惠金额(货币分组列表转换字符串)")
    private String discountOtherFeeGroup;

    @ExcelIgnore
    @ApiModelProperty(value = "已收额外费用货币分组列表")
    private List<FeeGroupDto> writeOffOtherFeeGroupDtoList;

    @ExcelProperty(value = "已收额外费用", index = 25)
    @ApiModelProperty(value = "已收额外费用(货币分组列表转换字符串)")
    private String writeOffOtherFeeGroup;

    @ExcelIgnore
    @ApiModelProperty(value = "核销币种(总额计算统一币种，当币种有多个时，以美元计算，否则以当前单一币种计算)")
    private Long writeOffCurrencyId;

    @ExcelIgnore
    @ApiModelProperty(value = "应收总金额= 订单原价*收费数据+其他费用")
    private BigDecimal receivableTotalAmount;

    @ExcelIgnore
    @ApiModelProperty(value = "应收总金额货币分组列表")
    private List<FeeGroupDto> receivableTotalFeeGroupDtoList;

    @ExcelProperty(value = "应收总金额", index = 10)
    @ApiModelProperty(value = "应收总金额(货币分组列表转换字符串)")
    private String receivableTotalFeeGroup;

    @ExcelIgnore
    @ApiModelProperty(value = "优惠总金额= 所有费用原价-所有费用成交价")
    private BigDecimal discountTotalAmount;

    @ExcelIgnore
    @ApiModelProperty(value = "优惠总金额货币分组列表")
    private List<FeeGroupDto> discountTotalFeeGroupDtoList;

    @ExcelProperty(value = "订单优惠金额", index = 11)
    @ApiModelProperty(value = "订单优惠金额(货币分组列表转换字符串)")
    private String discountTotalFeeGroup;

    @ExcelIgnore
    @ApiModelProperty(value = "实收总金额 =（订单成交单价*收费数据）+额外费用")
    private BigDecimal netReceiptsTotalAmount;

    @ExcelIgnore
    private List<FeeGroupDto> netReceiptsTotalFeeGroupDtoList;

    @ExcelProperty(value = "实收总金额", index = 12)
    @ApiModelProperty(value = "实收总金额(货币分组列表转换字符串)")
    private String netReceiptsTotalFeeGroup;

    @ExcelIgnore
    @ApiModelProperty(value = "核销比例传值要乘以100")
    private BigDecimal writeOffProportion;

    @ExcelIgnore
    @ApiModelProperty(value = "核销比例")
    private String writeOffRatio;

    @ExcelIgnore
    @ApiModelProperty(value = "已收总金额=已核销金额")
    private BigDecimal writeOffAmount;

    @ExcelIgnore
    @ApiModelProperty(value = "已收总金额货币分组列表")
    private List<FeeGroupDto> writeOffTotalFeeGroupDtoList;

    @ExcelProperty(value = "已收总金额", index = 13)
    @ApiModelProperty(value = "已收总金额(货币分组列表转换字符串)")
    private String writeOffTotalFeeGroup;


    @ExcelProperty(value = "是否全部核销", index = 26)
    @ApiModelProperty(value = "是否全部核销")
    private String writeOffStatus;


    /*** 入仓信息 ***/

    @ExcelIgnore
    @ApiModelProperty(value = "始发地ID")
    private Long departureId;

    @ExcelIgnore
    @ApiModelProperty(value = "目的地ID")
    private Long objectiveId;

    @ExcelIgnore
    @ApiModelProperty(value = "始发地名称")
    private String departureName;

    @ExcelIgnore
    @ApiModelProperty(value = "目的地名称")
    private String objectiveName;

    @ExcelIgnore
    @ApiModelProperty(value = "始发仓库ID")
    private Long startWarehouseId;

    @ExcelIgnore
    @ApiModelProperty(value = "目的仓库ID")
    private Long dstWarehouseId;

    @ExcelProperty(value = "始发仓", index = 3)
    @ApiModelProperty(value = "始发仓库")
    private String startWarehouseName;

//    @ExcelIgnore
    @ExcelProperty(value = "目的仓", index = 5)
    @ApiModelProperty(value = "目的仓库")
    private String dstWarehouseName;

    @ExcelIgnore
    @ApiModelProperty(value = "调仓始发仓id")
    private Long adjustToStartWarehouseId;

    @ExcelIgnore
    @ApiModelProperty(value = "调仓目的仓id")
    private Long adjustToDestWarehouseId;

    @ExcelIgnore
    @ApiModelProperty(value = "调仓后的始发仓")
    private String adjustToStartWarehouseName;

    @ExcelIgnore
    @ApiModelProperty(value = "调仓后的目的仓")
    private String adjustToDestWarehouseName;

    @ExcelIgnore
    @ApiModelProperty(value = "物流信息相关(订单的汇总的物流信息取这里)")
    private LogisticsInfoDto logisticsInfoDto;

    @ExcelProperty(value = "运输方式", index = 4, converter = DictConvert.class)
    @DictFormat(TRANSPORT_TYPE)
    @ApiModelProperty(value = "运输id")
    private Integer transportId;

//    @ExcelIgnore
////    @ExcelProperty(value = "运输方式", index = 4)
//    @ApiModelProperty(value = "运输方式")
//    private String transportName;

    @ExcelIgnore
    @ApiModelProperty(value = "订单服务类型(可多选)：1 集运服务 2 海外仓")
    private String type;

    @ExcelIgnore
    @ApiModelProperty(value = "特需类型")
    private String advanceType;

    @ExcelIgnore
    @ApiModelProperty(value = "线路ID", required = true)
    private Long lineId;

    @ExcelIgnore
    @ApiModelProperty(value = "渠道ID")
    private Long channelId;

    @ExcelIgnore
    @ApiModelProperty(value = "订单类型：1 普货 2 重货 3 泡货")
    private Integer orderType;

    @ExcelProperty(value = "是否重泡货", index = 7)
    @ApiModelProperty(value = "是否重泡货")
    private String orderTypeName;

    @ExcelProperty(value = "仓库实测", index = 6)
    @ApiModelProperty(value = "仓库实测")
    private String warehouseInData;

    @ExcelIgnore
    @ApiModelProperty(value = "入仓数量")
    private Integer sumQuantity = 0;

    @ExcelIgnore
    @ApiModelProperty(value = "入仓件数", required = true)
    private Integer sumNum = 0;

    @ExcelIgnore
    @ApiModelProperty(value = "入仓体积", required = true)
    private BigDecimal sumVolume = BigDecimal.ZERO;

    @ExcelIgnore
    @ApiModelProperty(value = "入仓重量", required = true)
    private BigDecimal sumWeight = BigDecimal.ZERO;

    @ExcelIgnore
    private BigDecimal orgChargeQuantity = BigDecimal.ZERO;

    @ExcelIgnore
    @ApiModelProperty(value = "原收费件数", required = true)
    private Integer orgChargeNum = 0;

    @ExcelIgnore
    @ApiModelProperty(value = "原收费体积", required = true)
    private BigDecimal orgChargeVolume = BigDecimal.ZERO;

    @ExcelIgnore
    @ApiModelProperty(value = "原收费重量", required = true)
    private BigDecimal orgChargeWeight = BigDecimal.ZERO;


    @ExcelProperty(value = "收费数据", index = 8)
    @ApiModelProperty(value = "收费数据")
    private String chargeData;

    @ExcelIgnore
    @ApiModelProperty(value = "实际收费数量")
    private BigDecimal realityChargeQuantity = BigDecimal.ZERO;

    @ExcelIgnore
    @ApiModelProperty(value = "实际收费件数", required = true)
    private Integer realityChargeNum = 0;

    @ExcelIgnore
    @ApiModelProperty(value = "实际收费体积", required = true)
    private BigDecimal realityChargeVolume = BigDecimal.ZERO;

    @ExcelIgnore
    @ApiModelProperty(value = "实际收费重量", required = true)
    private BigDecimal realityChargeWeight = BigDecimal.ZERO;

    @ExcelIgnore
    @ApiModelProperty(value = "货值", required = true)
    private BigDecimal totalWorth = BigDecimal.ZERO;

    @ExcelIgnore
    @ApiModelProperty(value = "货值金额单位ID(默认RMB)")
    private Integer worthCurrency = 3;

    @ExcelIgnore
    @ApiModelProperty(value = "重货标准基数")
    private BigDecimal weightUnit;

    @ExcelIgnore
    @ApiModelProperty(value = "泡货标准基数")
    private BigDecimal volumeUnit;

    @ExcelIgnore
    @ApiModelProperty(value = "原重货标准基数")
    private BigDecimal orgWeightUnit;

    @ExcelIgnore
    @ApiModelProperty(value = "原泡货标准基数")
    private BigDecimal orgVolumeUnit;

    @ExcelIgnore
    @ApiModelProperty(value = "重货方数")
    private BigDecimal wVolume;

    @ExcelIgnore
    @ApiModelProperty(value = "泡货重量")
    private BigDecimal vWeight;


    /*** 订单状态说明 ***/
    @ExcelIgnore
    @ApiModelProperty(value = "订单状态详情见字典：order_status")
    private Integer status;

    @ExcelIgnore
    @ApiModelProperty(value = "订单异常状态(字典 order_abnormal_state)")
    private Integer abnormalState;

    @ExcelIgnore
    @ApiModelProperty(value = "订单入仓状态(字典 order_warehouse_in_status)")
    private Integer inWarehouseState;

    @ExcelIgnore
    @ApiModelProperty(value = "订单出货状态(字典 order_shipment_state)")
    private Integer shipmentState;

    /**
     * 状态说明
     */
    @ExcelProperty(value = "订单状态", index = 9)
    @ApiModelProperty(value = "订单状态")
    private String statusMsg;


    public void setWriteOffProportion(BigDecimal writeOffProportion) {
        this.writeOffProportion = writeOffProportion;
        if (Objects.nonNull(writeOffProportion)) {
            this.writeOffStatus = writeOffProportion.compareTo(BigDecimal.ZERO) <= 0 ? "未核销" :
                    (writeOffProportion.compareTo(new BigDecimal("100")) >= 0 ? "全部核销" : "部分核销");
        }
    }

    public void setOrderType(Integer orderType) {
        this.orderType = orderType;
        if (Objects.nonNull(orderType)) {
            this.orderTypeName = orderType == 1 ? "否" : "是";
        }
    }
}
