package com.dev.swms.server.model.base;

import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;

import com.dev.swms.server.model.rules.ItemStorageRule;
import com.dev.swms.server.model.rules.LotRule;
import com.dev.swms.server.web.filter.WarehouseHolder;
import com.dev.energy.server.model.Entity;

public class Item extends Entity {
	private static final long serialVersionUID = 3750844150633107385L;
	/** 仓库 */
	private Warehouse warehouse;
	/** 客户 */
	private Structure company;
	/** 商品代码 */
	private String code;
	/** 商品名称 */
	private String name;
	/** 简称 */
	private String shortName;
	/** 型号规格 */
	private String specs;
	/** 描述 */
	private String description;
	/** 包含包装 */
	private Set<PackageUnit> packageUnits;
	/** 是否为套件 */
	private boolean isBOM;
	/** 包含子件 */
	private Set<BOMComponent> components;
	/** 批次 */
	private LotRule lotRule;
	/** 保质期限 */
	private Integer validPeriod=0;
	/** 预警时间 */
	private Integer alertLeadingDays=0;
	/** 是否有效 */
	private boolean disabled = false;
	/**  货品存放规则 */
	private Set<ItemStorageRule> storageRules;
	/** 结算费用 */
	private String feeType;
	/** 供应商 */
	private Set<Structure> suppliers;
	// *********新增属性***********
	/** 大类 */
	private String largeClass;//大单位
	/** 中类 */
	private String centerClass;
	/** 小类 */
	private String smallClass;
	/** 单品管理 */
	private boolean singleItem;
	/** 加工费用 */
	private double price;
	/** 最后盘点日期 */
	private Date cycleDate;
	
	/**
	 * 是否发动机
	 */
	private boolean beWeight;
	
	protected String strExtend1;//库位
    protected String strExtend2;
    protected String strExtend3;//外条码
    protected String strExtend4;//转换结果
    protected String strExtend5;//是否条码管理
    
    private String goodType;//货物类型
    private String storageType;//存储类型
    private String brand;//品牌
    private String department;//部门
    private double length;//长
    private double width;//宽
    private double height;//高
    private double weight;//重量(净重)
    
    private double roughWeight;//毛重
    private double volume;//体积
    private String unit;//基本单位
    private Double CAcoefficient=1d;//小单位系数
    private String CAname;//小单位
    private int bearTime;//禁收时限
    private int saleTime;//禁售时限
    private int balanceNumber;//托系数
    private int suggest;//装盘建议
    private Location location;//补货库位--对象
    private double minimumStock;//最低库存
    private double HighestStock;//最高库存
    private String barcode;//条码
    /**是否发动机*/
    private boolean beMarkWeight;//非标重
    
    private String shipRules;//发货规则
    
    private int packNumber;//大单位系数
    
    private Double multipleOrder;//倍数订购
    
    private int codePat ;//盘点初始库存
    /**  */
	private String sourceId;
	/**  */
	private String sourceType;
	/** 是否预备货 */
	private boolean beMachin=false;//是否加工
	
	private Date produceDate;//生产日期
	private Date dueDate;//过期日期
	
	private Set<SignFile> files = new HashSet<SignFile>(); // 附件清单
	
	/** 箱体积 */
	private double boxVolume;
    
    
    public Warehouse getWarehouse() {
		return warehouse;
	}

	public void setWarehouse(Warehouse warehouse) {
		this.warehouse = warehouse;
	}

	public String getShortName() {
		return shortName;
	}

	public void setShortName(String shortName) {
		this.shortName = shortName;
	}

	public double getBoxVolume() {
		return boxVolume;
	}

	public void setBoxVolume(double boxVolume) {
		this.boxVolume = boxVolume;
	}

	public Set<SignFile> getFiles() {
		return files;
	}

	public void setFiles(Set<SignFile> files) {
		this.files = files;
	}

	public Date getDueDate() {
		return dueDate;
	}

	public void setDueDate(Date dueDate) {
		this.dueDate = dueDate;
	}

	public Date getProduceDate() {
		return produceDate;
	}

	public void setProduceDate(Date produceDate) {
		this.produceDate = produceDate;
	}

	public boolean isBeMachin() {
		return beMachin;
	}

	public void setBeMachin(boolean beMachin) {
		this.beMachin = beMachin;
	}

	public String getSourceId() {
		return sourceId;
	}

	public void setSourceId(String sourceId) {
		this.sourceId = sourceId;
	}

	public String getSourceType() {
		return sourceType;
	}

	public void setSourceType(String sourceType) {
		this.sourceType = sourceType;
	}

	public String getShipRules() {
		return shipRules;
	}

	public void setShipRules(String shipRules) {
		this.shipRules = shipRules;
	}

	public int getPackNumber() {
		return packNumber;
	}

	public void setPackNumber(int packNumber) {
		this.packNumber = packNumber;
	}

	public Double getMultipleOrder() {
		return multipleOrder;
	}

	public void setMultipleOrder(Double multipleOrder) {
		this.multipleOrder = multipleOrder;
	}

	public int getCodePat() {
		return codePat;
	}

	public void setCodePat(int codePat) {
		this.codePat = codePat;
	}

	public boolean isBeMarkWeight() {
		return beMarkWeight;
	}

	public void setBeMarkWeight(boolean beMarkWeight) {
		this.beMarkWeight = beMarkWeight;
	}

	public String getBarcode() {
		return barcode;
	}

	public void setBarcode(String barcode) {
		this.barcode = barcode;
	}

	public double getHighestStock() {
		return HighestStock;
	}

	public void setHighestStock(double highestStock) {
		HighestStock = highestStock;
	}

	public String getGoodType() {
		return goodType;
	}

	public void setGoodType(String goodType) {
		this.goodType = goodType;
	}

	public String getStorageType() {
		return storageType;
	}

	public void setStorageType(String storageType) {
		this.storageType = storageType;
	}

	public String getBrand() {
		return brand;
	}

	public void setBrand(String brand) {
		this.brand = brand;
	}

	public String getDepartment() {
		return department;
	}

	public void setDepartment(String department) {
		this.department = department;
	}

	public double getLength() {
		return length;
	}

	public void setLength(double length) {
		this.length = length;
	}

	public double getWidth() {
		return width;
	}

	public void setWidth(double width) {
		this.width = width;
	}

	public double getHeight() {
		return height;
	}

	public void setHeight(double height) {
		this.height = height;
	}




	public double getWeight() {
		return weight;
	}

	public void setWeight(double weight) {
		this.weight = weight;
	}

	public double getVolume() {
		return volume;
	}

	public void setVolume(double volume) {
		this.volume = volume;
	}

	public String getUnit() {
		return unit;
	}

	public void setUnit(String unit) {
		this.unit = unit;
	}

	

	public Double getCAcoefficient() {
		return CAcoefficient;
	}

	public void setCAcoefficient(Double cAcoefficient) {
		CAcoefficient = cAcoefficient;
	}

	public String getCAname() {
		return CAname;
	}

	public void setCAname(String cAname) {
		CAname = cAname;
	}

	public int getBearTime() {
		return bearTime;
	}

	public void setBearTime(int bearTime) {
		this.bearTime = bearTime;
	}

	public int getSaleTime() {
		return saleTime;
	}

	public void setSaleTime(int saleTime) {
		this.saleTime = saleTime;
	}

	public int getBalanceNumber() {
		return balanceNumber;
	}

	public void setBalanceNumber(int balanceNumber) {
		this.balanceNumber = balanceNumber;
	}

	public int getSuggest() {
		return suggest;
	}

	public void setSuggest(int suggest) {
		this.suggest = suggest;
	}

	public Location getLocation() {
		return location;
	}

	public void setLocation(Location location) {
		this.location = location;
	}

	public double getMinimumStock() {
		return minimumStock;
	}

	public void setMinimumStock(double minimumStock) {
		this.minimumStock = minimumStock;
	}

	
    
    
    
    
    
	public double getRoughWeight() {
		return roughWeight;
	}

	public void setRoughWeight(double roughWeight) {
		this.roughWeight = roughWeight;
	}

	public String getStrExtend1() {
		return strExtend1;
	}

	public void setStrExtend1(String strExtend1) {
		this.strExtend1 = strExtend1;
	}

	public String getStrExtend2() {
		return strExtend2;
	}

	public void setStrExtend2(String strExtend2) {
		this.strExtend2 = strExtend2;
	}

	public String getStrExtend3() {
		return strExtend3;
	}

	public void setStrExtend3(String strExtend3) {
		this.strExtend3 = strExtend3;
	}

	public String getStrExtend4() {
		return strExtend4;
	}

	public void setStrExtend4(String strExtend4) {
		this.strExtend4 = strExtend4;
	}

	public String getStrExtend5() {
		return strExtend5;
	}

	public void setStrExtend5(String strExtend5) {
		this.strExtend5 = strExtend5;
	}

	public boolean isBeWeight() {
		return beWeight;
	}

	public void setBeWeight(boolean beWeight) {
		this.beWeight = beWeight;
	}

	public double getPrice() {
		return price;
	}

	public void setPrice(double price) {
		this.price = price;
	}

	protected Item(){
		super();
	}
	
	public String getCenterClass() {
		return centerClass;
	}

	public void setCenterClass(String centerClass) {
		this.centerClass = centerClass;
	}

	public String getLargeClass() {
		return largeClass;
	}

	public void setLargeClass(String largeClass) {
		this.largeClass = largeClass;
	}

	public boolean isSingleItem() {
		return singleItem;
	}

	public void setSingleItem(boolean singleItem) {
		this.singleItem = singleItem;
	}

	public String getSmallClass() {
		return smallClass;
	}

	public void setSmallClass(String smallClass) {
		this.smallClass = smallClass;
	}

	public String getFeeType() {
		return feeType;
	}

	public void setFeeType(String feeType) {
		this.feeType = feeType;
	}

	public Set<ItemStorageRule> getStorageRules() {
		return storageRules;
	}
	public void setStorageRules(Set<ItemStorageRule> storageRules) {
		this.storageRules = storageRules;
	}
	public boolean isDisabled() {
		return disabled;
	}
	public void setDisabled(boolean disabled) {
		this.disabled = disabled;
	}
	public boolean isBOM() {
		return isBOM;
	}
	public boolean getIsBOM() {
		return isBOM;
	}
	public void setIsBOM(boolean isBOM) {
		this.isBOM = isBOM;
	}
	public String getCode() {
		return code;
	}
	public void setCode(String code) {
		this.code = code;
	}
	public Structure getCompany() {
		return company;
	}
	public void setCompany(Structure company) {
		this.company = company;
	}
	public String getDescription() {
		return description;
	}
	public void setDescription(String description) {
		this.description = description;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getSpecs() {
		return specs;
	}
	public void setSpecs(String specs) {
		this.specs = specs;
	}	
	public Set<PackageUnit> getPackageUnits() {
		return packageUnits;
	}
	public void setPackageUnits(Set<PackageUnit> packageUnits) {
		this.packageUnits = packageUnits;
	}	
	public Set<BOMComponent> getComponents() {
		return components;
	}
	public void setComponents(Set<BOMComponent> components) {
		this.components = components;
	}	
	public void addComponent(BOMComponent bomComponent){
		bomComponent.setBom(this);
		this.components.add(bomComponent);
	}	
	public void deleteComponent(BOMComponent bomComponent){
		this.components.remove(bomComponent);
	}
	public Integer getValidPeriod() {
		return validPeriod;
	}
	public void setValidPeriod(Integer validPeriod) {
		this.validPeriod = validPeriod;
	}
	
	public Integer getAlertLeadingDays() {
		return alertLeadingDays;
	}

	public void setAlertLeadingDays(Integer alertLeadingDays) {
		this.alertLeadingDays = alertLeadingDays;
	}

	public boolean equals(final Object other) {
		if (!(other instanceof Item))
			return false;
		Item castOther = (Item) other;
		return new EqualsBuilder().append(company, castOther.getCompany())
				.append(code, castOther.getCode()).isEquals();
	}
	public int hashCode() {
		return new HashCodeBuilder().append(company).append(code).toHashCode();
	}
	
	/**
	 * 检查商品包装清单中有无与指定包装相同折算系数的包装存在
	 * @param packageUnit 包装单位
	 * @return null－未找到；PackageUnit－与指定包装折算系数相同的包装
	 */
	public PackageUnit getPackageUnit(PackageUnit packageUnit) {
		if (this.getPackageUnits() != null) {
			for (PackageUnit unit : this.getPackageUnits()) {
				if (unit.getConvertFigure() == packageUnit.getConvertFigure()) {
					return unit;
				}
			}
		}
		return null;
	}

	/**
	 * 获取商品的最小包装单位（折算系数为1的包装单位）
	 * @return null－未找到；PackageUnit－折算系数为1的包装单位
	 */
	public PackageUnit getMinPackageUnit() {
		if (this.getPackageUnits() != null) {
			for (PackageUnit unit : this.getPackageUnits()) {
				if (unit.getConvertFigure() == 1) {
					return unit;
				}
			}
		}
		return null;
	}
	/**
	 * 获取商品货品的可码托的包装单位
	 * @return null－未找到；PackageUnit－可码托的包装单位
	 */
	public PackageUnit getLPPackageUnit() {
		if (this.getPackageUnits() != null) {
			for (PackageUnit unit : this.getPackageUnits()) {
				if (unit.isAllowLP()) {
					return unit;
				}
			}
		}
		return null;
	}
	
	/**
	 * 增加商品的包装单位
	 * @param packageUnit 商品包装单位
	 */
	public void addPackageUnit(PackageUnit packageUnit) {
		packageUnit.setItem(this);
		if (this.getPackageUnits() == null) {
			this.setPackageUnits(new HashSet<PackageUnit>());
		}
		this.getPackageUnits().add(packageUnit);
	}

	public ItemStorageRule getWarehouseItemStorageRule() {
		if (this.storageRules == null || this.storageRules.size() == 0) {
			return null;
		}
		for (ItemStorageRule rule : this.storageRules) {
			if (WarehouseHolder.getWarehouse().getId().equals(rule.getWarehouse().getId())) {
				return rule;
			}
		}
		return null;
	}

	public LotRule getLotRule() {
		return lotRule;
	}
	
	public LotRule getDefaultLotRule() {
		if(this.lotRule==null){
			if(this.company.getLotRule()==null){
				return null;
			}else{
				return this.company.getLotRule();
			}
		}
		return lotRule;
	}

	public void setLotRule(LotRule lotRule) {
		this.lotRule = lotRule;
	}

	public Set<Structure> getSuppliers() {
		return suppliers;
	}

	public void setSuppliers(Set<Structure> suppliers) {
		this.suppliers = suppliers;
	}

	public Date getCycleDate() {
		return cycleDate;
	}

	public void setCycleDate(Date cycleDate) {
		this.cycleDate = cycleDate;
	}
	
	/**
	 * 依据拆箱级别取不大于拆箱级别的最大包装
	 * @param lineNo
	 * @return
	 */
	public PackageUnit getPackageUnitByLineNo(int lineNo){
		if (this.getPackageUnits() != null) {
			PackageUnit pu = null;
			for (PackageUnit unit : packageUnits) {
				if (unit.getLineNO() == lineNo) {
					return unit;
				}
				if(pu == null || pu.getLineNO()<unit.getLineNO()){
					pu = unit;
				}
			}
			return pu;
		}
		return null;
	}
	
	public Map<Integer,Boolean> getLotRuleMap(){
		LotRule rule = this.getLotRule();
		if(rule == null) {
			rule = this.getCompany().getLotRule();
		}
		return rule.getLotRuleMap();
	}
	
	public Map<Integer,String> getLotInfo(){
		Map<Integer,String> lotInfoValue = new HashMap<Integer, String>();
		Map<Integer,Boolean> lotRule = getLotRuleMap();
		for(int i = 1; i <= 18; i++){
			if(lotRule.get(i)){
				lotInfoValue.put(i, null);
			}
		}
		return lotInfoValue;
	}
	
	/**
	 * 移除和附件的关联关系
	 * 
	 * @author  dev
	 */
	public void removeFiles(SignFile signFile) {
		this.getFiles().remove(signFile);
	}
}
