package cn.iocoder.yudao.module.order.dal.dataobject.orderItem;

import cn.iocoder.yudao.framework.mybatis.core.dataobject.BaseDO;
import cn.iocoder.yudao.module.order.vo.order.ApplyInfoVO;
import cn.iocoder.yudao.module.order.vo.order.WarehouseInInfoVO;
import cn.iocoder.yudao.module.order.vo.orderSplitItem.OrderSpiltItemSpecsRecordVO;
import cn.iocoder.yudao.module.order.vo.orderWarehouseIn.OrderWarehouseInCreateReqVO;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import io.swagger.annotations.ApiModelProperty;
import lombok.*;
import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * 订单项 DO
 *
 * @author 系统管理员
 */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
@TableName("ecw_order_item")
@EqualsAndHashCode(callSuper = true)
@ToString(callSuper = true)
public class OrderItemDO extends BaseDO {

    /**
     * 主键ID
     */
    @TableId
    private Long orderItemId;
    /**
     * 订单ID
     */
    private Long orderId;
    /**
     * 订单编号
     */
    private String orderNo;


    @ApiModelProperty(value = "订单类型：1 普货 2 重货 3 泡货")
    private Integer orderItemType;
    /**
     * 运输方式id
     */
    private Integer transportId;
    /**
     * 线路ID
     */
    private Long lineId;
    /**
     * 渠道ID
     */
    private Long channelId;
    /**
     * 订单项状态详情见字典
     */
    private Integer itemStatus;
    /**
     * 商品ID
     */
    private Long prodId;
    /**
     * 产品类型
     */
    private Integer prodType;
    /**
     * 产品中文标题
     */
    private String prodTitleZh;
    /**
     * 产品英文标题
     */
    private String prodTitleEn;
    /**
     * 产品法文标题
     */
    private String prodTitleFr;

    @ApiModelProperty(value = "商品第三方链接")
    private String link;
    /**
     * 品牌ID
     */
    private Long brand;
    /**
     * 0 无牌 1 有牌 2 中性
     */
    private Integer brandType;

    /**
     * 费用模式：无牌价0，有牌价1，中性品牌价2
     */
    private Integer feeType;

    @ApiModelProperty(value = "是否预付：0 到付 1 预付")
    private Integer isPayAdvance;

    @ApiModelProperty(value = "计费方式：0 运费/清关费 1 全包价")
    private Integer charging;

    @ApiModelProperty(value = "数量")
    private Integer quantity;
    /**
     * 件数
     */
    private Integer num;
    /**
     * 包装单位
     */
    private String unit;
    /**
     * 箱规
     */
    private String boxGauge;
    /**
     * 体积
     */
    private BigDecimal volume;
    /**
     * 重量
     */
    private BigDecimal weight;
    /**
     * 货值
     */
    private BigDecimal worth;
    /**
     * 货值金额单位ID
     */
    private Integer worthCurrency;
    /**
     * 商品特性(可选多个特性ID)
     */
    private String prodAttrIds;
    /**
     * 填单商品特性(可选多个特性ID)
     */
    private String fillProdAttrIds;
    /**
     * 入仓商品特性(可选多个特性ID)
     */
    private String warehouseInProdAttrIds;

    @ApiModelProperty(value = "结果")
    private String result;

    @ApiModelProperty(value = "结果状态(多个以逗号拼接，状态详情见字典")
    private String resultStatus;

    @ApiModelProperty(value = "是否特价")
    private Boolean specialPriceType;

    @ApiModelProperty(value = "是否拆单自定义价格")
    private Boolean splitCustomPriceType;
    /**
     * 是否为渠道/单询手动定价
     */
    @ApiModelProperty(value = "是否为确认渠道/单询手动定价/重量超限异常定价")
    private Boolean channelManualPricing;

    /**
     * 运费单价(成交)
     */
    private BigDecimal oneSeaFreight;

    /**
     * 旧运费单价(成交)
     */
    private BigDecimal oldOneSeaFreight;
    /**
     * 运费(小计)
     */
    private BigDecimal seaFreight;
    /**
     * 原来运费(原始)
     */
    private BigDecimal originalSeaFreight;
    /**
     * 运费货币单位ID
     */
    private Integer seaFreightCurrency;
    /**
     * 运费体积单位
     */
    private Long seaFreightVolume;
    /**
     * 清关费单价(成交)
     */
    private BigDecimal oneClearanceFreight;
    /**
     * 旧清关费单价(成交)
     */
    private BigDecimal oldOneClearanceFreight;
    /**
     * 清关费(小计)
     */
    private BigDecimal clearanceFreight;
    /**
     * 原清关费(原始)
     */
    private BigDecimal originalClearanceFreight;
    /**
     * 清关费货币单位ID
     */
    private Integer clearanceFreightCurrency;
    /**
     * 清关费体积单位
     */
    private Long clearanceFreightVolume;

    @ApiModelProperty(value = "最小计量重量")
    private BigDecimal minMeteringWeight = BigDecimal.ZERO;

    @ApiModelProperty(value = "最小计量体积")
    private BigDecimal minMeteringVolume = BigDecimal.ZERO;

    @ApiModelProperty(value = "最小计量个数")
    private BigDecimal minMeteringQuantity = BigDecimal.ZERO;


    @ApiModelProperty(value = "收费重量")
    private BigDecimal chargeWeight;

    @ApiModelProperty(value = "收费体积")
    private BigDecimal chargeVolume;

    @ApiModelProperty(value = "收费个数")
    private BigDecimal chargeQuantity;

    @ApiModelProperty(value = "订单项属性：1 普货 2 重货 3 泡货")
    private Integer itemType;

    @ApiModelProperty(value = "货比-重货的订单比(不计算普货订单项)")
    private BigDecimal weightRatio;

    @ApiModelProperty(value = "货比-泡货的订单比(不计算普货订单项)")
    private BigDecimal volumeRatio;

    /**
     * 是否仓库入仓新品
     */
    @ApiModelProperty(value = "是否仓库入仓新品 0 下单货物  1 非下单货物-即新品 ")
    private Boolean isWarehouseInAdd;


    /**
     * 材质
     */
    private String material;

    @ApiModelProperty(value = "重货体积")
    private BigDecimal wVolume;

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

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

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


    /**
     * 入仓信息json
     */
    @ApiModelProperty(value = "入仓信息VO")
    @TableField(exist = false)
    private WarehouseInInfoVO warehouseInInfoVO;

    @ApiModelProperty(value = "重货收费总体积")
    @TableField(exist = false)
    private BigDecimal heavyCargoTotalChargeVolume = BigDecimal.ZERO;
    @ApiModelProperty(value = "普货收费总体积")
    @TableField(exist = false)
    private BigDecimal commonGoodsTotalChargeVolume = BigDecimal.ZERO;
    @ApiModelProperty(value = "泡货收费总重量")
    @TableField(exist = false)
    private BigDecimal pickledGoodsTotalChargeWeight = BigDecimal.ZERO;
    @ApiModelProperty(value = "普货收费总重量")
    @TableField(exist = false)
    private BigDecimal commonGoodsTotalChargeWeight = BigDecimal.ZERO;
    @ApiModelProperty(value = "收费总个数")
    @TableField(exist = false)
    private BigDecimal totalChargeQuantity = BigDecimal.ZERO;
    /**
     * 入仓信息json
     */
    @ApiModelProperty(value = "入仓信息json")
    private String warehouseInInfo;


    @ApiModelProperty("快递单号")
    private String expressNo;


    @ApiModelProperty("用途")
    private String usageIds;


    @ApiModelProperty(value = "佣金类型：0 无 1 明佣 2 暗佣 3 明+暗")
    private Integer commissionType = 0;

    @ApiModelProperty("明佣金额")
    private BigDecimal plainCommission = BigDecimal.ZERO;

    @ApiModelProperty("暗佣金额")
    private BigDecimal hiddenCommission = BigDecimal.ZERO;


    @ApiModelProperty(value = "活动优惠运费金额(原始单价上进行优惠)")
    private BigDecimal discountFreightPrice = BigDecimal.ZERO;

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

    @ApiModelProperty(value = "活动优惠清关费金额(原始单价上进行优惠)")
    private BigDecimal discountClearanceFeePrice = BigDecimal.ZERO;

    @ApiModelProperty(value = "活动优惠清关费总金额")
    private BigDecimal discountClearanceFeeTotalPrice = BigDecimal.ZERO;

    @ApiModelProperty(value = "是否已定价")
    private Boolean isPriced = Boolean.FALSE;

    @ApiModelProperty(value = "液体清关费单价")
    private BigDecimal liquidClearanceFeePrice = BigDecimal.ZERO;

    @ApiModelProperty(value = "液体运费单价")
    private BigDecimal liquidFreightPrice = BigDecimal.ZERO;

    @ApiModelProperty(value = "带电清关费单价")
    private BigDecimal electrifiedClearanceFeePrice = BigDecimal.ZERO;

    @ApiModelProperty(value = "带电运费单价")
    private BigDecimal electrifiedFreightPrice = BigDecimal.ZERO;

    @ApiModelProperty(value = "品牌清关费单价")
    private BigDecimal brandClearanceFeePrice = BigDecimal.ZERO;

    @ApiModelProperty(value = "品牌运费单价")
    private BigDecimal brandFreightPrice = BigDecimal.ZERO;

    @ApiModelProperty(value = "包装清关费单价")
    private BigDecimal packagingClearanceFeePrice = BigDecimal.ZERO;

    @ApiModelProperty(value = "包装运费单价")
    private BigDecimal packagingFreightPrice = BigDecimal.ZERO;

    @ApiModelProperty(value = "是否特价佣金设置")
    private Boolean specialCommission = Boolean.FALSE;

    @ApiModelProperty(value = "使用的优惠信息")
    private String couponInfo;


    @ApiModelProperty(value = "原订单项id")
    private Long orgItemId;

    @ApiModelProperty(value = "'空运加价运费单价'")
    private BigDecimal markupSeaFreight = BigDecimal.ZERO;

    @ApiModelProperty(value = "'空运加价清关费单价'")
    private BigDecimal markupClearanceFreight = BigDecimal.ZERO;
    @ApiModelProperty(value = "应收运费(成本) = 应收单价 * 原始重泡货标准的收费数据")
    private BigDecimal receivableSeaFreight;

    @ApiModelProperty(value = "应收清关费(成本) = 应收单价 * 原始重泡货标准的收费数据")
    private BigDecimal receivableClearanceFreight;

    @ApiModelProperty(value = "应收收费数量")
    private BigDecimal orgChargeQuantity = BigDecimal.ZERO;

    @ApiModelProperty(value = "应收收费件数")
    private Integer orgChargeNum = 0;

    @ApiModelProperty(value = "空运清关费来源：1 商品 2 渠道 3 商品线路价格 4 线路")
    private Integer airClearanceSource;

    @ApiModelProperty(value = "'空运清关费来源数据详情'")
    private String airClearanceInfo;
    @ApiModelProperty(value = "应收收费体积")
    private BigDecimal orgChargeVolume = BigDecimal.ZERO;

    @ApiModelProperty(value = "应收收费重量")
    private BigDecimal orgChargeWeight = BigDecimal.ZERO;


    @ApiModelProperty(value = "是否为待确认商品")
    @TableField(exist = false)
    private Boolean isProd = Boolean.FALSE;

    @ApiModelProperty(value = "最早的入仓记录")
    @TableField(exist = false)
    private OrderWarehouseInCreateReqVO orderWarehouseInCreateReqVO;

    @ApiModelProperty(value = "规格记录(拆单时封装子拆单入仓记录时使用)")
    @TableField(exist = false)
    private List<OrderSpiltItemSpecsRecordVO> specsRecordVOList;


    @ApiModelProperty(value = "打包状态 1未打包 2无需打包 3完成打包")
    private Integer packStatus;

    @ApiModelProperty(value = "是否需要单询，0-否，1-是")
    private Integer needOrderInquiry;

    @ApiModelProperty(value = "是否处理过单询异常")
    private Boolean isHandlerOrderInquiryException;

    @ApiModelProperty(value = "是否处理了渠道特性异常")
    private Boolean handlerChannelAttrException;

    @ApiModelProperty(value = "到仓商品ID")
    private Long checkProdId;

    @ApiModelProperty(value = "到仓产品类型")
    private Integer checkProdType;

    @ApiModelProperty(value = "到仓产品中文标题")
    private String checkProdTitleZh;

    @ApiModelProperty(value = "到仓产品英文标题")
    private String checkProdTitleEn;

    @ApiModelProperty(value = "到仓产品法文标题")
    private String checkProdTitleFr;

    @ApiModelProperty(value = "到仓材质")
    private String checkMaterial;

    @ApiModelProperty(value = "到仓商品特性(可选多个特性ID)")
    private String warehouseCheckProdAttrIds;

    @ApiModelProperty(value = "到仓品牌")
    private Long checkBrand;

    @ApiModelProperty(value = "到仓：0 无牌 1 有牌 2 中性")
    private Integer checkBrandType;

    @ApiModelProperty(value = "最后运费单价变更时间")
    private Date lastFreightChargePriceTime;

    @ApiModelProperty(value = "最后清关费单价变更时间")
    private Date lastClearanceChargePriceTime;
    /**
     * 到仓信息json
     */
    @ApiModelProperty(value = "到仓信息json")
    private String warehouseCheckInfo;
    /**
     * 1-未设置商品清关费, 2-区间未匹配上
     */
    @TableField(exist = false)
    private int productPriceEmptyType = 0;

    /**
     * 1-未设置渠道清关费, 2-区间未匹配上, 3-包装类型未设置
     */
    @TableField(exist = false)
    private int channelPriceEmptyType = 0;

    /**
     * 是否超出空运重量上限
     */
    @TableField(exist = false)
    private Boolean isAirWeightLimit = false;
    /**
     * 空运自定义价格变动记录
     */
    @TableField(exist = false)
    private List<ApplyInfoVO> applyInfoVOList;


    /**
     * 合计单价(比较订单品名最低单价的参数，此参数通过目的地进口运费货币计算得出)
     */
    @TableField(exist = false)
    private BigDecimal totalOnePrice;


    @ApiModelProperty(value = "混箱的入仓纪录数")
    @TableField(exist = false)
    private Integer mixCount = 0;

    @ApiModelProperty(value = "混箱状态, 1-混箱")
    @TableField(exist = false)
    private Integer mixStatus = 0;
    public Integer getMixStatus() {
        // 当混箱的入仓纪录数大于0时，就认为是混箱
        return mixCount > 0 ? 1 : 0;
    }


    @ApiModelProperty(value = "包装类型（入仓汇总的，逗号分隔）")
    @TableField(exist = false)
    private String units;

    /**
     * 关联订单数量
     */
    @ApiModelProperty(value = "关联订单数量")
    @TableField(exist = false)
    private Integer guanLianOrderCount;

//    public void setOriginalSeaFreight(BigDecimal originalSeaFreight) {
//        this.originalSeaFreight = originalSeaFreight;
//        if (Objects.nonNull(originalSeaFreight) && originalSeaFreight.compareTo(BigDecimal.ZERO) == 0){
//            // 表示当前运费没有价格，将预付状态置null
//            this.isPayAdvance = null;
//        }
//    }
//
//    public void setIsPayAdvance(Integer isPayAdvance) {
//        this.isPayAdvance = isPayAdvance;
//        if (Objects.nonNull(this.originalSeaFreight) && this.originalSeaFreight.compareTo(BigDecimal.ZERO) == 0){
//            // 表示当前运费没有价格，将预付状态置null
//            this.isPayAdvance = null;
//        }
//    }

    //    public WarehouseInInfoVO getWarehouseInInfoVO() {
//        return JSONObject.parseObject(this.warehouseInInfo, WarehouseInInfoVO.class);
//    }

    public WarehouseInInfoVO getWarehouseInInfoVO() {
        if(warehouseInInfoVO != null) return warehouseInInfoVO;
        if(StringUtils.isNotEmpty(this.warehouseInInfo)) {
            warehouseInInfoVO = JSONObject.parseObject(this.warehouseInInfo,
                    WarehouseInInfoVO.class);
        }
        return warehouseInInfoVO;
    }


    public String getUnits() {
        if(getWarehouseInInfoVO() != null) {
            units = getWarehouseInInfoVO().getUnits();
        }
        return units;
    }

    public void setWarehouseInInfo(String warehouseInInfo) {
        this.warehouseInInfo = warehouseInInfo;
        if (StringUtils.isNotBlank(warehouseInInfo)) {
            this.warehouseInInfoVO = JSONObject.parseObject(warehouseInInfo, WarehouseInInfoVO.class);
        }
    }

    public void setWarehouseInInfoVO(WarehouseInInfoVO warehouseInInfoVO) {
        this.warehouseInInfoVO = warehouseInInfoVO;
        if (Objects.nonNull(warehouseInInfoVO)) {
            this.warehouseInInfo = JSONObject.toJSONString(warehouseInInfoVO);
        }
    }


    public void set(String field, Object value) {
        try {
            Field f = getClass().getDeclaredField(field);
            f.setAccessible(true);
            f.set(this, value);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
