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

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.LotInfo;
import com.dev.swms.server.model.base.NewLotInfo;
import com.dev.swms.server.model.base.PackageUnit;
import com.dev.swms.server.service.GlobalParamUtils;
import com.dev.energy.server.exception.BusinessException;
import com.dev.energy.server.model.EntityFactory;

public class ProcessDocBOMDetail extends AbstractMoveDocDetail {
	private static final long serialVersionUID = 8863406219981534750L;
	/** 加工单 */
	private ProcessDoc processDoc; 
	/** 具体商品 */
	private Item item;
	/** 批次属性 */
	private NewLotInfo newLotInfo;
	/** 计划数量 */
	private double orderQuantity;
	/** 预分配数量 */
	private double preAllocatedQuantity;
	/** 预分配批次 */
	private String preAllocatedLot;
	/** 已分配数量 */
	private double allocatedQuantity;
	/** 拣货数量 */
	private double pickedQuantity;
	/** 加工数量 */
	private double processQuantity; 
	/** 包装单位 */
	private PackageUnit packageUnit;
	/** 拣货任务 */
	private Set<Task> tasks;
	/** 存货日期 */
	private Date storageDate;
	/** SOI */
	private String SOI;
	
	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 getAllocatedQuantity() {
		return allocatedQuantity;
	}
	public void setAllocatedQuantity(double allocatedQuantity) {
		this.allocatedQuantity = allocatedQuantity;
	}
	public Item getItem() {
		return item;
	}
	public void setItem(Item item) {
		this.item = item;
	}
	public NewLotInfo getNewLotInfo() {
		return newLotInfo;
	}
	public void setNewLotInfo(NewLotInfo newLotInfo) {
		this.newLotInfo = newLotInfo;
	}
	public double getOrderQuantity() {
		return orderQuantity;
	}
	public void setOrderQuantity(double orderQuantity) {
		this.orderQuantity = orderQuantity;
	}
	public PackageUnit getPackageUnit() {
		return packageUnit;
	}
	public void setPackageUnit(PackageUnit packageUnit) {
		this.packageUnit = packageUnit;
	}
	public double getPickedQuantity() {
		return pickedQuantity;
	}
	public void setPickedQuantity(double pickedQuantity) {
		this.pickedQuantity = pickedQuantity;
	}
	public String getPreAllocatedLot() {
		return preAllocatedLot;
	}
	public void setPreAllocatedLot(String preAllocatedLot) {
		this.preAllocatedLot = preAllocatedLot;
	}
	public double getPreAllocatedQuantity() {
		return preAllocatedQuantity;
	}
	public void setPreAllocatedQuantity(double preAllocatedQuantity) {
		this.preAllocatedQuantity = preAllocatedQuantity;
	}
	public ProcessDoc getProcessDoc() {
		return processDoc;
	}
	public void setProcessDoc(ProcessDoc processDoc) {
		this.processDoc = processDoc;
	}
	public double getProcessQuantity() {
		return processQuantity;
	}
	public void setProcessQuantity(double processQuantity) {
		this.processQuantity = processQuantity;
	}
	public Set<Task> getTasks() {
		return tasks;
	}
	public void setTasks(Set<Task> tasks) {
		this.tasks = tasks;
	}
	@Override
	public double getShippedQuantity() {
		// TODO Auto-generated method stub
		return 0;
	}
	@Override
	public void setShippedQuantity(double shippedQuantity) {
		// TODO Auto-generated method stub
		
	}
	@Override
	public AbstractMoveDoc getAbstractMoveDoc() {
		return this.getProcessDoc();
	}
	
	/**
	 * 获取发货单明细的剩余未预分配数量
	 * @return
	 */
	public Double getUnPreAllocateQuantity() {
		return this.orderQuantity - this.preAllocatedQuantity;
	}
	
	@Override
	public double getUnallocateQuantity() {
		return this.preAllocatedQuantity-this.allocatedQuantity;
	}
	
	@Override
	public Task allocate(String bhCode,Inventory inventory, double quantity) {
		this.allocatedQuantity += quantity;
		
		Task t=addTask(TaskType.MV_PICKTICKET, 
				inventory.getLocation(),
				this.getProcessDoc().getProcessLoc(),
				inventory.getLP(), inventory.getLP(),
				inventory.getItemKeyInventory().getItemKey(), 
				inventory.getStorageDate(), 
				inventory.getSOI(),
				inventory.getStatus(),
				quantity,
				inventory.getPackageUnit());
		return t;
	}
	
    public Task addTask(String taskType, Location fromLocation, Location toLocation, Stock srcLp, 
    		Stock dstLp, ItemKey itemKey, Date storageDate, String soi, String status, 
    		double allocatedQuantity, PackageUnit packageUnit) {
		if (this.getTasks() == null) {
			this.setTasks(new HashSet<Task>());
		}
		Task t=getTask(taskType, fromLocation, toLocation, srcLp, dstLp, itemKey, storageDate, soi, status, 
				allocatedQuantity, packageUnit);
		return t;
	}
    
	private Task getTask(String taskType, Location fromLocation, Location toLocation, Stock srcLp, 
			Stock dstLp, ItemKey itemKey, Date storageDate, String soi, String status, 
			double allocatedQuantity, PackageUnit packageUnit) {
		Task task = EntityFactory.getEntity(Task.class);
		task.setCode(GlobalParamUtils.generateCodeByType("generateTask"));
		task.setType(taskType);
		task.setSrcLoc(fromLocation);
		task.setSrcLP(srcLp);
		task.setSrcLPCode(srcLp==null?null:srcLp.getLP());
		task.setDstLoc(toLocation);
		task.setDstLP(dstLp);
		task.setDstLPCode(dstLp==null?null:dstLp.getLP());
		task.setItemKey(itemKey);
		task.setStorageDate(storageDate);
		task.setSOI(soi);
		task.setInventoryStatus(status);
		task.setPackageUnit(packageUnit);
		task.setPlanQuantityMU(allocatedQuantity);
		task.setBillCode(this.getProcessDoc().getCode());
		task.setOrderDate(this.getProcessDoc().getCreateDate());//增加订单日期
		task.setProcessDocBOMDetail(this);
		this.getTasks().add(task);
		return task;
	}
    
	@Override
	public Location getAllocateDstLoc() {
		return this.getProcessDoc().getProcessLoc();
	}
	@Override
	public int hashCode() {
		return new HashCodeBuilder().append(processDoc)
		                            .append(item)
		                            .append(packageUnit)
                                    .append(newLotInfo)
                                    .toHashCode();
	}
	@Override
	public boolean equals(Object other) {
		if (!(other instanceof ProcessDocBOMDetail))
			return false;
		ProcessDocBOMDetail castOther = (ProcessDocBOMDetail) other;
		return new EqualsBuilder().append(item, castOther.getItem())
								  .append(packageUnit, castOther.getPackageUnit())
								  .append(newLotInfo,castOther.getLotInfo())
								  .isEquals();
	}
	
	/** 
	 * 获取明细对应加工作业单的code 
	 */
	public String getCode() {
		return this.getProcessDoc().getCode();
	}
	
	/** 
	 * 明细预分配
	 * @param lot 预分配批次号
	 * @param quantity 预分配数量
	 */
	public void preAllocate(String lot, Double quantity) {
		this.preAllocatedLot = lot;
		this.preAllocatedQuantity += quantity;
		if (this.preAllocatedQuantity > this.getOrderQuantity()) {
			throw new BusinessException("preAlloate.quantity.error");
		}
	}
	
	/**
	 * 明细取消预分配
	 * @param quantity
	 */
	public void unPreAllocate(Double quantity) {
		this.preAllocatedQuantity -= quantity;
		if (this.preAllocatedQuantity < 0) {
			throw new BusinessException("unPreAlloate.quantity.error");
		}
		if(this.preAllocatedQuantity==0){
			this.setPreAllocatedLot(null);
		}
	}
	
	/**
	 * 减少发货单明细的已分配数量
	 * @param quantity
	 */
	public void unallocate(double quantity) {
		this.allocatedQuantity -= quantity;
	}
	
	/**
	 * 子件拣货确认
	 * @param pickedQuantity
	 */
	public void pickConfirm(double pickedQuantity){
		this.pickedQuantity += pickedQuantity;
	}
	@Override
	public LotInfo getLotInfo() {
		return null;
	}
	
	@Override
	public void setApplyDoc(String code) {
	}
	@Override
	public void setApplyDocDetailId(Long id) {
	}
}
