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

import cn.hutool.core.collection.CollectionUtil;
import cn.iocoder.yudao.framework.common.validation.Marks;
import cn.iocoder.yudao.framework.i18n.core.I18nMessage;
import cn.iocoder.yudao.module.order.dto.ExternalWarehouseDto;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.fastjson.JSONObject;
import com.fasterxml.jackson.annotation.JsonFormat;
import lombok.*;

import java.math.BigDecimal;
import java.util.*;

import io.swagger.annotations.*;

import javax.validation.constraints.*;

import org.apache.commons.lang3.StringUtils;
import org.hibernate.validator.constraints.Length;
import org.springframework.format.annotation.DateTimeFormat;

import static cn.iocoder.yudao.framework.common.util.date.DateUtils.FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND;

/**
 * 订单 Base VO，提供给添加、修改、详细的子 VO 使用
 * 如果子 VO 存在差异的字段，请不要添加到这里，影响 Swagger 文档生成
 */
@Data
public class OrderBaseVO {

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

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

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

    @ApiModelProperty(value = "父编号")
    private String parentNumber;

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

    @ApiModelProperty(value = "初始母订单id")
    private Long initialParentOrderId;

    @ApiModelProperty(value = "初始母订单编号")
    private String initialParentOrderNo;

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

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

    @ApiModelProperty(value = "运输方式id", required = true)
    @NotNull(message = "运输方式id不能为空")
    private Integer transportId;

    @ApiModelProperty(value = "线路ID", required = true)
    @NotNull(message = "线路ID不能为空")
    private Long lineId;

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

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

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

    @ApiModelProperty(value = "下单会员id", required = true)
    private Long userId = 0L;

    @ApiModelProperty(value = "客户经理ID")
    private Long salesmanId;

    @ApiModelProperty(value = "客户经理所属部门ID")
    private Long deptId;

    @ApiModelProperty(value = "唛头")
    @NotBlank(message = "marks.not.null")
    @Length(max = 20, message = "marks.length.max")
//    @Marks(message = "marks.format.incorrect")
    private String marks;

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

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

    @ApiModelProperty(value = "0 控货中；1 已放完货；2 部分控货")
    private Integer cargoControlStatus;

    @ApiModelProperty(value = "报关类别：我司全代：1，自单代报：2，混合报关：3")
    private Integer customsType;

    @ApiModelProperty(value = "上传文件")
    private String upFile;

    @ApiModelProperty(value = "付款类型")
    private Integer payType;

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

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

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

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

    @ApiModelProperty(value = "上次订单主状态值")
    private Integer oldStatus;

    @ApiModelProperty(value = "上次订单入仓状态值")
    private Integer oldInWarehouseState;

    @ApiModelProperty(value = "上次订单出货状态值")
    private Integer oldShipmentState;

    @ApiModelProperty(value = "审核类型(字典 order_approval_type) 0 为正常")
    private Integer auditType;

    @ApiModelProperty(value = "审核结果")
    private String auditResult;

    @ApiModelProperty(value = "是否被删掉 1 删掉；0正常")
    private Boolean isDel;

    @ApiModelProperty(value = "代收金额")
    private BigDecimal collectionProxy;

    @ApiModelProperty(value = "代收货币ID")
    private Integer collectionProxyCurrency;

    @ApiModelProperty(value = "是否代收货款收款 0为否 1为是", required = true)
    private Boolean isCollection;

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

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

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

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

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

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

    @ApiModelProperty(value = "计算使用的重货标准基数")
    private BigDecimal useWeightUnit;

    @ApiModelProperty(value = "计算使用的泡货标准基数")
    private BigDecimal useVolumeUnit;

    @ApiModelProperty(value = "入仓类型")
    private Integer warehouseType;

    @ApiModelProperty(value = "是否发送过入仓短信 已发送：1，未发送：0")
    private Boolean sendsms;

    @ApiModelProperty(value = "单证资料")
    private String documentsFile;

    @ApiModelProperty(value = "备注")
    private String remarks;

    @ApiModelProperty(value = "调仓始发仓")
    private Long adjustToStartWarehouseId = 0L;

    @ApiModelProperty(value = "调仓目的仓")
    private Long adjustToDestWarehouseId = 0L;

    @ApiModelProperty(value = "入仓数量", required = true)
    private Integer sumQuantity;

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

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

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

    @ApiModelProperty(value = "重货比", required = true)
    private BigDecimal weightRatio;

    @ApiModelProperty(value = "发货人的客户id", required = true)
//    @NotNull(message = "发货人的客户id不能为空")
    private Long customerId;

    @ApiModelProperty(value = "航空公司id")
    private Long airlineCompany;

    @ApiModelProperty(value = "船公司id")
    private Long shippingCompany;

    @ApiModelProperty(value = "清关证书：0 否 1 是")
    private Boolean customsClearCert;

    @ApiModelProperty(value = "出单方式：1 电放 2 正本")
    private Integer issuingMethod;

    @ApiModelProperty(value = "是否拆包：0 否 1 是")
    private Boolean isUnpack;

    @ApiModelProperty(value = "是否单票立刻转运：0 否 1 是")
    private Boolean isSingleTicketTransport;

    @ApiModelProperty(value = "费用清单")
    private String cost;

    @ApiModelProperty(value = "费用清单VO")
    private CostVO costVO;

    @ApiModelProperty(value = "付款人： 1 发货人 2 收货人 3 自定义")
    private Integer drawee = 1;

    @ApiModelProperty(value = "自定义付款人信息")
    private String customDrawee;

    @ApiModelProperty(value = "优惠信息列表")
    private List<OrderCoupon> orderCouponList;

    @ApiModelProperty(value = "入仓时间")
    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
    private Date rucangTime;

    @ApiModelProperty(value = "到港时间")
    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
    private Date daogangTime;

    @ApiModelProperty(value = "清关时间")
    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
    private Date qingguanTime;

    @ApiModelProperty(value = "已预装时间")
    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
    private Date preLoadTime;

    @ApiModelProperty(value = "已装柜时间")
    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
    private Date loadTime;

    @ApiModelProperty(value = "已卸柜时间")
    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
    private Date unloadTime;

    @ApiModelProperty(value = "提货时间")
    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
    private Date takeTime;

    @ApiModelProperty(value = "拆单时间")
    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
    private Date splitTime;

    @DateTimeFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
    @JsonFormat(pattern = FORMAT_YEAR_MONTH_DAY_HOUR_MINUTE_SECOND)
    @ApiModelProperty(value = "送货时间", required = true)
//    @NotNull(message = "送货时间不能为空")
    private Date deliveryDate;

    @ApiModelProperty(value = "收货方式：1 自提 2 送货上门 ")
    private Integer harvestMethod;

    @ApiModelProperty(value = "收货地址的国家")
    private Long country;

    @ApiModelProperty(value = "收货地址的省")
    private Long province;

    @ApiModelProperty(value = "收货地址的市")
    private Long city;

    @ApiModelProperty(value = "收货地址")
    private String consigneeAddress;

    @ApiModelProperty(value = "特需类型ids")
    private String packageType;

    @ApiModelProperty(value = "包装备注")
    private String packageRemarks;

    @ApiModelProperty(value = "是否双清：1 客户自清 2 我司双清")
    private Integer doubleClear;

    @ApiModelProperty(value = "装箱单url")
    private String packingListUrl;

    @ApiModelProperty(value = "是否外部仓")
    private Boolean isExternalWarehouse = false;

    /**
     * 关联订单状态
     */
    @ApiModelProperty(value = "关联订单状态")
    private String guanlianOrderStatus;

    @ApiModelProperty(value = "关联订单状态")
    private List<GuanLianOrderStatusVO> guanLianOrderStatusVOList;

    @ApiModelProperty(value = "外部仓信息")
    private String externalWarehouseJson;

    @ApiModelProperty(value = "外部仓信息")
    private List<ExternalWarehouseDto> externalWarehouseDtoList;

    @ApiModelProperty(value = "不阻塞流程的异常说明(支持多个异常说明)")
    private String exceptionReason;

    @ApiModelProperty(value = "是否有异常(此处为不阻塞流程的异常)")
    private Boolean isException = Boolean.FALSE;

    @ApiModelProperty(value = "目的港清关：1 我司 2 客户")
    private Integer portDestCustomsClear;

    @ApiModelProperty(value = "发货方式：1 多票 2 单票")
    private Integer deliveryWay;

    @ApiModelProperty(value = "清关证书备注")
    private String customsClearCertRemarks;

    @ApiModelProperty(value = "空运可出货状态： 0 默认值 1 待出 2 可出 3 备货中 4 已备货")
    private Integer airShipment;

    @ApiModelProperty(value = "特价泡重")
    private BigDecimal specialVWeight;

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

    @ApiModelProperty(value = "打包前入仓重量")
    private BigDecimal weightBeforePack;


    @ApiModelProperty(value = "打包后入仓重量")
    private BigDecimal weightAfterPack;

    @ApiModelProperty(value = "备货重量阀值")
    private BigDecimal stockOverWeightLimit;

    @ApiModelProperty(value = "拆单子订单是作为独立订单计算(拆单业务只要涉及到空运即将所有拆单后的子订单作为独立订单来计算)")
    private Boolean splitSeparateOrder = false;

    @ApiModelProperty(value = "是否显示提单金额")
    private Boolean displayBillLadingPrice;

    @ApiModelProperty(value = "是否在公海")
    private Boolean isInOpenSea;

    @ApiModelProperty(value = "提货状态：0 未提货 1 部分提货 2 已提货")
    private Integer pickState;

    @ApiModelProperty(value = "'提货率'")
    private BigDecimal pickRatio;

    @ApiModelProperty(value = "'提货箱数'")
    private Integer pickNum;


    @ApiModelProperty(value = "放货率")
    private BigDecimal releaseRatio;

    @ApiModelProperty(value = "放货箱数")
    private Integer releaseNum;

    @ApiModelProperty(value = "是否有收货人，1-是，0-否")
    private Boolean hasConsignee = true;


    @ApiModelProperty(value = "到仓件数")
    private Integer checkNum;

    @ApiModelProperty(value = "到仓数量")
    private Integer checkQuantity;

    @ApiModelProperty(value = "到仓体积")
    private BigDecimal checkVolume;

    @ApiModelProperty(value = "到仓重量")
    private BigDecimal checkWeight;

    public void setExceptionReason(String exceptionReason) {
        this.exceptionReason = StringUtils.isNotBlank(exceptionReason) ? I18nMessage.getMessage(exceptionReason) : exceptionReason;
    }

    public void setExternalWarehouseJson(String externalWarehouseJson) {
        this.externalWarehouseJson = externalWarehouseJson;
        if (StringUtils.isNotBlank(externalWarehouseJson)) {
            this.externalWarehouseDtoList = JSONObject.parseArray(externalWarehouseJson, ExternalWarehouseDto.class);
        }
    }

    public void setGuanlianOrderStatus(String guanlianOrderStatus) {
        this.guanlianOrderStatus = guanlianOrderStatus;
        if (StringUtils.isNotBlank(guanlianOrderStatus)) {
            this.guanLianOrderStatusVOList = JSONObject.parseArray(guanlianOrderStatus, GuanLianOrderStatusVO.class);
        }
    }

    public void setGuanLianOrderStatusVOList(List<GuanLianOrderStatusVO> guanLianOrderStatusVOList) {
        this.guanLianOrderStatusVOList = guanLianOrderStatusVOList;
        if (CollectionUtil.isNotEmpty(guanLianOrderStatusVOList)) {
            this.guanlianOrderStatus = JSONObject.toJSONString(guanLianOrderStatusVOList);
        }
    }

    public void setExternalWarehouseDtoList(List<ExternalWarehouseDto> externalWarehouseDtoList) {
        this.externalWarehouseDtoList = externalWarehouseDtoList;
        if (CollectionUtil.isNotEmpty(externalWarehouseDtoList)) {
            this.externalWarehouseJson = JSONObject.toJSONString(externalWarehouseDtoList);
        }
    }

    public void setCostVO(CostVO costVO) {
        this.costVO = costVO;
        this.cost = JSONObject.toJSONString(costVO);
    }

    public CostVO getCostVO() {
        return JSONObject.parseObject(this.cost, CostVO.class);
    }


}
