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

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

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

import com.dev.swms.server.model.abstractEntity.AbstractMoveDoc;
import com.dev.swms.server.model.abstractEntity.AbstractMoveDocDetail;
import com.dev.swms.server.model.base.Item;
import com.dev.swms.server.model.base.ItemKey;
import com.dev.swms.server.model.base.Location;
import com.dev.swms.server.model.base.LocationType;
import com.dev.swms.server.model.base.LotInfo;
import com.dev.swms.server.model.base.NewLotInfo;
import com.dev.swms.server.model.base.PackageUnit;
import com.dev.swms.server.model.inventory.Inventory;
import com.dev.swms.server.model.inventory.Stock;
import com.dev.swms.server.model.inventory.Task;
import com.dev.swms.server.model.inventory.TaskType;
import com.dev.swms.server.service.GlobalParamUtils;
import com.dev.swms.server.utils.DoubleUtils;
import com.dev.energy.server.exception.BusinessException;
import com.dev.energy.server.model.Entity;
import com.dev.energy.server.model.EntityFactory;

public class MoveObjectDetail  extends Entity{
	private static final long serialVersionUID = 8145995443689714504L;
	/** 移位计划 */
	private MoveObject moveObject;
	/** 商品属性 */
	private ItemKey itemKey;
	/** 存货日期 */
	private Date storageDate;
	/** SOI */
	private String SOI;
	/** 源库位 */
	private Location srcLoc;
	/** 目标库位 */
	private Location dstLoc;
	/** 计划数量 */
	private double planQuantity;
	/** 计划数量(MU) */
	private double planQuantityOfMU;
	/** 分配数量 */
	private double allocateQuantity;
	/** 移位数量 */
	private double moveQuantity;
	/** 源托盘 */
	private Stock srcLP;
	/** 源托盘号 */
	private String srcLPCode;
	/** 目标托盘 */
	private Stock dstLP;
	/** 目标托盘号 */
	private String dstLPCode;
	/** 包装单位 */
	private PackageUnit packageUnit;
	/** 库存状态 */
	private String inventoryStatus;
	/** 批次属性 */
	private NewLotInfo newLotInfo;
	private int lineNo;
	private Long invId;
	

	public Long getInvId() {
		return invId;
	}

	public void setInvId(Long invId) {
		this.invId = invId;
	}

	public int getLineNo() {
		return lineNo;
	}

	public void setLineNo(int lineNo) {
		this.lineNo = lineNo;
	}

	@Override
	public boolean equals(final Object other) {
		if (!(other instanceof MoveObjectDetail))
			return false;
		MoveObjectDetail castOther = (MoveObjectDetail) other;
		return new EqualsBuilder().append(moveObject, castOther.getMoveObject())
			.append(itemKey, castOther.getItemKey())
			.append(storageDate, castOther.getStorageDate())
			.append(SOI, castOther.getSOI())
			.append(srcLoc, castOther.getSrcLoc())
			.append(dstLoc, castOther.getDstLoc())
			.append(srcLP, castOther.getSrcLP())
			.append(srcLPCode, castOther.getSrcLPCode())
			.append(dstLP, castOther.getDstLP())
			.append(dstLPCode, castOther.getDstLPCode())
			.append(packageUnit, castOther.getPackageUnit())
			.append(inventoryStatus, castOther.getInventoryStatus())
			.append(newLotInfo, castOther.getNewLotInfo())
			.append(lineNo, castOther.lineNo)
			.isEquals();
	}

	@Override
	public int hashCode() {
		return new HashCodeBuilder().append(moveObject).append(itemKey).append(
				storageDate).append(SOI).append(srcLoc).append(dstLoc).append(
				srcLP).append(srcLPCode).append(dstLP).append(dstLPCode)
				.append(packageUnit).append(inventoryStatus)
				.append(newLotInfo).append(lineNo).toHashCode();
	}

	protected MoveObjectDetail() {
		super();
	}
	
	public String getSrcLPCode() {
		return srcLPCode;
	}
	public void setSrcLPCode(String srcLPCode) {
		this.srcLPCode = srcLPCode;
	}
	public String getDstLPCode() {
		return dstLPCode;
	}
	public void setDstLPCode(String dstLPCode) {
		this.dstLPCode = dstLPCode;
	}
	public Date getStorageDate() {
		return storageDate;
	}
	public void setStorageDate(Date storageDate) {
		this.storageDate = storageDate;
	}
	public String getSOI() {
		return SOI;
	}
	public void setSOI(String soi) {
		SOI = soi;
	}
	public double getPlanQuantityOfMU() {
		return planQuantityOfMU;
	}
	public void setPlanQuantityOfMU(double planQuantityOfMU) {
		this.planQuantityOfMU = planQuantityOfMU;
	}
	public Stock getDstLP() {
		return dstLP;
	}
	public void setDstLP(Stock dstLP) {
		this.dstLP = dstLP;
	}
	public Stock getSrcLP() {
		return srcLP;
	}
	public void setSrcLP(Stock srcLP) {
		this.srcLP = srcLP;
	}
	public Location getDstLoc() {
		return dstLoc;
	}
	public void setDstLoc(Location dstLoc) {
		this.dstLoc = dstLoc;
	}
	public ItemKey getItemKey() {
		return itemKey;
	}
	public void setItemKey(ItemKey itemKey) {
		this.itemKey = itemKey;
	}
	public NewLotInfo getNewLotInfo() {
		return newLotInfo;
	}
	public void setNewLotInfo(NewLotInfo newLotInfo) {
		this.newLotInfo = newLotInfo;
	}
	
	public MoveObject getMoveObject() {
		return moveObject;
	}

	public void setMoveObject(MoveObject moveObject) {
		this.moveObject = moveObject;
	}

	public PackageUnit getPackageUnit() {
		return packageUnit;
	}
	public void setPackageUnit(PackageUnit packageUnit) {
		this.packageUnit = packageUnit;
	}
	public double getPlanQuantity() {
		return planQuantity;
	}
	public void setPlanQuantity(double planQuantity) {
		this.planQuantity = planQuantity;
	}
	public Location getSrcLoc() {
		return srcLoc;
	}
	public void setSrcLoc(Location srcLoc) {
		this.srcLoc = srcLoc;
	}
	public double getAllocateQuantity() {
		return allocateQuantity;
	}
	public void setAllocateQuantity(double allocateQuantity) {
		this.allocateQuantity = allocateQuantity;
	}
	public double getMoveQuantity() {
		return moveQuantity;
	}
	public void setMoveQuantity(double moveQuantity) {
		this.moveQuantity = moveQuantity;
	}
	public String getInventoryStatus() {
		return inventoryStatus;
	}
	public void setInventoryStatus(String inventoryStatus) {
		this.inventoryStatus = inventoryStatus;
	}

	public boolean canMove(Location dstLocation) {
		if (dstLocation == null || dstLocation.bePutAwayLock()) {
			throw new BusinessException("putaway.destLocation.error");
		}
		if (MoveDocStatus.ACTIVE.equals(this.getMoveObject().getStatus()) 
				|| MoveDocStatus.ALLOCATE.equals(this.getMoveObject().getStatus())
				|| MoveDocStatus.MOVE.equals(this.getMoveObject().getStatus())) {
			if (LocationType.STORAGE.equals(dstLocation.getType())) {
				return true;
			}else{
				throw new BusinessException("putaway.destLocation.error");
			}
		} else {
			throw new BusinessException("putaway.status.error");
		}
	}

	public void add(Double quantity) {
		this.planQuantityOfMU += quantity;
		if (this.packageUnit.getPrecision() == 0) {
			this.planQuantity = Math.ceil(this.planQuantityOfMU / this.packageUnit.getConvertFigure());
		} else {
			this.planQuantity = DoubleUtils.formatByPrecision(this.planQuantityOfMU 
					/ this.packageUnit.getConvertFigure(), this.packageUnit.getPrecision());
		}
		this.moveObject.add(quantity);
	}

	public void allocate(Double quantity) {
		this.allocateQuantity += quantity;
		this.moveObject.allocate(quantity);
	}

	public void unallocate(Double quantity) {
		this.allocateQuantity -= quantity;
		if (this.allocateQuantity < 0) {
			throw new BusinessException("moveDoc.allocate.quantity.error");
		}
		this.moveObject.unallocate(quantity);
	}
	
	public double getLeftQuantity() {
		return (this.planQuantityOfMU - this.allocateQuantity);
	}
	
	public double getUnallocateQuantity() {
		return this.planQuantityOfMU - this.allocateQuantity;
	}
	
	public void moveTo(Double movedQuantity) {
		this.moveQuantity += movedQuantity;
		this.moveObject.moveTo(movedQuantity);
	}

   
	public double getPreAllocatedQuantity() {
		return planQuantityOfMU;
	}

	public void setPreAllocatedQuantity(double preAllocatedQuantity) {
		
	}

	public double getAllocatedQuantity() {
		return allocateQuantity;
	}

	public void setAllocatedQuantity(double allocatedQuantity) {
		allocateQuantity = allocatedQuantity;
	}

	public double getOrderQuantity() {
		return planQuantity;
	}

	public void setOrderQuantity(double orderQuantity) {
		planQuantity = orderQuantity;
	}

	public double getPickedQuantity() {
		return getMoveQuantity();
	}

	public void setPickedQuantity(double pickedQuantity) {
		moveQuantity = pickedQuantity;
	}

	public double getShippedQuantity() {
		return 0;
	}

	public void setShippedQuantity(double shippedQuantity) {
		
	}


	public Item getItem() {
		return this.itemKey.getItem();
	}

	public LotInfo getLotInfo() {
		return this.getItemKey().getLotInfo();
	}

	public void allocate(Inventory inventory, double quantity) {
		this.allocateQuantity += quantity;
	}

	public Location getAllocateDstLoc() {
		return this.dstLoc;
	}


}
