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

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

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.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.EntityFactory;

public class WaveDocDetail extends AbstractMoveDocDetail {
	private static final long serialVersionUID = 1L;
	/** 波次作业单 */
	private WaveDoc waveDoc;
	/** 拣货单 */
	private PickTicket pickTicket;
	/** 具体商品 */
	private Item item;
	/** 批次属性 */
	private NewLotInfo newLotInfo;
	/** 汇总数量 */
	private double quantity;
	/** 汇总数量 */
	private double planBhQty;
	/** 补货数量 */
	private double orderQuantity;
	/** 基本单位数量 */
	private double orderQtyOfMasterUnit;
	/** 预分配数量 */
	private double preAllocatedQuantity;
	/** 预分配批次 */
	private String preAllocatedLot;
	/** 已分配数量 */
	private double allocatedQuantity;
	/** 拣货数量 */
	private double pickedQuantity;
	/** 分单数量（MU数量） */
	private double billAllocatedQuantity;
	/** 包装单位 */
	private PackageUnit packageUnit;
	/** 拣货任务 */
	private Set<Task> tasks;
	/** 补货单号 */
	private String applyDoc;
	/** 补货单明细ID */
	private Long applyDocDetailId;
	/** 存货日期 */
	private Date storageDate;
	/** SOI */
	private String SOI;
	/**CA系数*/
	private Double caCoefficient=0D;
	/**库位类型，从哪里拣货*/
	private String locType;
	
	
	public double getQuantity() {
		return quantity;
	}
	public void setQuantity(double quantity) {
		this.quantity = quantity;
	}
	public String getLocType() {
		return locType;
	}
	public void setLocType(String locType) {
		this.locType = locType;
	}
	public String getPreAllocatedLot() {
		return preAllocatedLot;
	}
	public void setPreAllocatedLot(String preAllocatedLot) {
		this.preAllocatedLot = preAllocatedLot;
	}

	public double getPlanBhQty() {
		return planBhQty;
	}
	public void setPlanBhQty(double planBhQty) {
		this.planBhQty = planBhQty;
	}
	public Double getCaCoefficient() {
		return caCoefficient;
	}
	public void setCaCoefficient(Double caCoefficient) {
		this.caCoefficient = caCoefficient;
	}
	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 String getApplyDoc() {
		return applyDoc;
	}
	public void setApplyDoc(String applyDoc) {
		this.applyDoc = applyDoc;
	}
	public Long getApplyDocDetailId() {
		return applyDocDetailId;
	}
	public void setApplyDocDetailId(Long applyDocDetailId) {
		this.applyDocDetailId = applyDocDetailId;
	}
	public NewLotInfo getNewLotInfo() {
		return newLotInfo;
	}
	public void setNewLotInfo(NewLotInfo newLotInfo) {
		this.newLotInfo = newLotInfo;
	}
	public double getAllocatedQuantity() {
		return allocatedQuantity;
	}
	public void setAllocatedQuantity(double allocatedQuantity) {
		this.allocatedQuantity = allocatedQuantity;
	}
	public double getBillAllocatedQuantity() {
		return billAllocatedQuantity;
	}
	public void setBillAllocatedQuantity(double billAllocatedQuantity) {
		this.billAllocatedQuantity = billAllocatedQuantity;
	}
	public Item getItem() {
		return item;
	}
	public void setItem(Item item) {
		this.item = item;
	}
	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 PickTicket getPickTicket() {
		return pickTicket;
	}
	public void setPickTicket(PickTicket pickTicket) {
		this.pickTicket = pickTicket;
	}
	public Set<Task> getTasks() {
		return tasks;
	}
	public void setTasks(Set<Task> tasks) {
		this.tasks = tasks;
	}
	public WaveDoc getWaveDoc() {
		return waveDoc;
	}
	public void setWaveDoc(WaveDoc waveDoc) {
		this.waveDoc = waveDoc;
	}
	
	public double getOrderQtyOfMasterUnit() {
		return orderQtyOfMasterUnit;
	}
	public void setOrderQtyOfMasterUnit(double orderQtyOfMasterUnit) {
		this.orderQtyOfMasterUnit = orderQtyOfMasterUnit;
	}
	public double getOrderQuantity() {
		return orderQuantity;
	}
	public void setOrderQuantity(double orderQuantity) {
		this.orderQuantity = orderQuantity;
	}
	@Override
	public double getPreAllocatedQuantity() {
		return this.orderQtyOfMasterUnit;
	}
	@Override
	public void setPreAllocatedQuantity(double preAllocatedQuantity) {
	}
	@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.getWaveDoc();
	}
	@Override
	public double getUnallocateQuantity() {
		return this.orderQtyOfMasterUnit-this.allocatedQuantity;
	}
	
	/**
	 * 增加发货单明细的已分配数量，并记录发货日志
	 * @param quantity
	 */
	public Task allocate(String bhCode,Inventory inventory, double quantity) {
		if (this.orderQtyOfMasterUnit<(this.allocatedQuantity+quantity)) {
			//throw new BusinessException("waveDocDetail.allocateQuantity.error");
		}
		this.allocatedQuantity += quantity;
		
		Task t=addTask(TaskType.MV_PICKTICKET, 
				inventory.getLocation(),
				this.item.getLocation(),
				inventory.getLP(), inventory.getLP(),
				inventory.getItemKeyInventory().getItemKey(), 
				inventory.getStorageDate(), 
				inventory.getSOI(),
				inventory.getStatus(),
				quantity,
				inventory.getPackageUnit());
		return t;
	}
	
	/**
	 * 减少发货单明细的已分配数量
	 * @param quantity
	 */
	public void unallocate(double quantity) {
		this.allocatedQuantity -= quantity;
		this.waveDoc.unallocate(quantity);
	}
	
    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((int)((Math.random()*9+1)*100000000)+"");//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.getWaveDoc().getCode());
		task.setOrderDate(this.getWaveDoc().getCreateDate());//增加订单日期
		task.setWaveDocDetail(this);
		this.getTasks().add(task);
		task.setCode(task.getId()+task.getCode());
		return task;
	}
    
	@Override
	public Location getAllocateDstLoc() {
		return this.item.getLocation();
		//return this.waveDoc.getPrepareGoodsLoc();
	}
	@Override
	public int hashCode() {
		// TODO Auto-generated method stub
		return 0;
	}
	@Override
	public boolean equals(Object arg0) {
		// TODO Auto-generated method stub
		return false;
	}
	
	/**
	 * 按拣货单明细生成波次作业单明细
	 * @param pickTicketDetail
	 * @param flag true:表示按单作业模式 false:表批量作业模式
	 */
	public void addPickTicketDetail(PickTicketDetail pickTicketDetail, boolean flag){
		double muQty = pickTicketDetail.getOrderQtyOfMasterUnit() - pickTicketDetail.getPickedQuantity();
		double qty = muQty/pickTicketDetail.getPackageUnit().getConvertFigure();
		if (pickTicketDetail.getPackageUnit().getPrecision() == 0) {
			qty = Math.floor(qty);
		} else {
			qty = DoubleUtils.formatByPrecision(qty, pickTicketDetail.getPackageUnit().getPrecision());
		}
		muQty = qty * pickTicketDetail.getPackageUnit().getConvertFigure();
		
		if(flag){
			this.setPickTicket(pickTicketDetail.getPickTicket());
		}
		this.setItem(pickTicketDetail.getItem());
		this.setNewLotInfo(pickTicketDetail.getNewLotInfo());
		this.setPackageUnit(pickTicketDetail.getPackageUnit());
		
		this.setOrderQuantity(this.getOrderQuantity() + qty);
		this.setOrderQtyOfMasterUnit(this.orderQtyOfMasterUnit + muQty);
		//波次作业单头
		this.waveDoc.addQuantity(this.packageUnit, qty);
	}
	
	/**
	 * 从波次作业单明细中减去拣货单明细
	 * @param pickTicketDetail
	 */
	public void deletePickTicketDetail(PickTicketDetail pickTicketDetail){
		this.setOrderQuantity(this.getOrderQuantity()-pickTicketDetail.getOrderQuantity());
		this.setOrderQtyOfMasterUnit(this.orderQtyOfMasterUnit-pickTicketDetail.getOrderQtyOfMasterUnit());
	}
	
	public void pickConfirm(double pickedQuantity){
		this.pickedQuantity += pickedQuantity;
		this.getWaveDoc().pickConfirm(pickedQuantity);
	}
	
	@Override
	public LotInfo getLotInfo() {
		return null;
	}
	
	public boolean isWaveWorkModel(){
		return waveDoc.isWaveWorkModel();
	}
	
	public void addQuantity(Double quantity,Double bhQuantity) {
		this.quantity += quantity;
		this.planBhQty += bhQuantity;
		this.orderQuantity += bhQuantity;
		this.orderQtyOfMasterUnit += bhQuantity * this.packageUnit.getConvertFigure();
		//波次作业单头
		this.waveDoc.addQuantity(this.packageUnit, bhQuantity);
	}
}
