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

import java.util.ArrayList;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
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.BillType;
import com.dev.swms.server.model.base.ItemKey;
import com.dev.swms.server.model.base.Structure;
import com.dev.swms.server.model.base.PackageUnit;
import com.dev.swms.server.model.base.Warehouse;
import com.dev.swms.server.model.base.Worker;
import com.dev.swms.server.model.inventory.Inventory;
import com.dev.swms.server.model.shipping.PickTicketStatus;
import com.dev.energy.server.model.Entity;
import com.dev.energy.server.web.security.UserHolder;

public class MoveObject  extends Entity{
	private static final long serialVersionUID = -4584322735023407478L;
	/** 定义单据类型 */
	public static final String MV_LOT = "MV_LOT";
	public static final String MV_TRANS = "MV_TRANS";
	
	/** 仓库 */
	private Warehouse warehouse;
	/** 货主 */
	private Structure companyA;
	/** 货主B */
	private Structure companyB;
	/** 货主 */
	private String moveType;
	/** 单据编号 */
	private String code;
	/** 单据类型 */
	private BillType billType;
	/** 创建日期 */
	private Date createDate;
	/** 移位计划状态 */
	private String status;
	/** 相关单号 */
	private String relateBillCode;
	/** 计划数量 */
	private double planQuantity;
	/** 分配数量 */
	private double allocateQuantity;
	/** 移位数量 */
	private double moveQuantity;
	/** 最后更新用户ID */
	private Long userID;
	/** 最后更新用户名 */
	private String userName;
	/** 最后更新时间 */
	private Date updateTime;
	/** 包含移位计划明细 */
	private Set<MoveObjectDetail> details = new HashSet<MoveObjectDetail>();
	/** 单据打印标志 */
	private int printCount = 0;
	/** 作业人员 */
	private Worker worker1;
	/** 作业人员 */
	private Worker worker2;
	/** 作业人员 */
	private Worker worker3;
	/** 作业人员 */
	private Worker worker4;
	

	public Worker getWorker1() {
		return worker1;
	}

	public void setWorker1(Worker worker1) {
		this.worker1 = worker1;
	}

	public Worker getWorker2() {
		return worker2;
	}

	public void setWorker2(Worker worker2) {
		this.worker2 = worker2;
	}

	public Worker getWorker3() {
		return worker3;
	}

	public void setWorker3(Worker worker3) {
		this.worker3 = worker3;
	}

	public Worker getWorker4() {
		return worker4;
	}

	public void setWorker4(Worker worker4) {
		this.worker4 = worker4;
	}


	public int getPrintCount() {
		return printCount;
	}

	public void setPrintCount(int printCount) {
		this.printCount = printCount;
	}


	public Structure getCompanyA() {
		return companyA;
	}

	public void setCompanyA(Structure companyA) {
		this.companyA = companyA;
	}

	public Structure getCompanyB() {
		return companyB;
	}

	public void setCompanyB(Structure companyB) {
		this.companyB = companyB;
	}

	public String getMoveType() {
		return moveType;
	}

	public void setMoveType(String moveType) {
		this.moveType = moveType;
	}

	public void setDetails(Set<MoveObjectDetail> details) {
		this.details = details;
	}

	public double getAllocateQuantity() {
		return allocateQuantity;
	}

	public void setAllocateQuantity(double allocateQuantity) {
		this.allocateQuantity = allocateQuantity;
	}

	public BillType getBillType() {
		return billType;
	}

	public void setBillType(BillType billType) {
		this.billType = billType;
	}


	public Set<MoveObjectDetail> getDetails() {
		return details;
	}

	public String getCode() {
		return code;
	}

	public void setCode(String code) {
		this.code = code;
	}

	public Date getCreateDate() {
		return createDate;
	}

	public void setCreateDate(Date createDate) {
		this.createDate = createDate;
	}


	public double getMoveQuantity() {
		return moveQuantity;
	}

	public void setMoveQuantity(double moveQuantity) {
		this.moveQuantity = moveQuantity;
	}

	public double getPlanQuantity() {
		return planQuantity;
	}

	public void setPlanQuantity(double planQuantity) {
		this.planQuantity = planQuantity;
	}

	public String getRelateBillCode() {
		return relateBillCode;
	}

	public void setRelateBillCode(String relateBillCode) {
		this.relateBillCode = relateBillCode;
	}

	public String getStatus() {
		return status;
	}

	public void setStatus(String status) {
		this.status = status;
	}

	public Date getUpdateTime() {
		return updateTime;
	}

	public void setUpdateTime(Date updateTime) {
		this.updateTime = updateTime;
	}

	public Long getUserID() {
		return userID;
	}

	public void setUserID(Long userID) {
		this.userID = userID;
	}

	public String getUserName() {
		return userName;
	}

	public void setUserName(String userName) {
		this.userName = userName;
	}

	public Warehouse getWarehouse() {
		return warehouse;
	}

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

	public void setUserTracking() {
		this.setUserID(UserHolder.getUser().getId());
		this.setUserName(UserHolder.getUser().getName());
		this.setUpdateTime(new Date());
	}

	public boolean cancel() {
		 if (MoveDocStatus.OPEN.equals(this.status)) {
			 this.setStatus(MoveDocStatus.CANCEL);
			 return true;
		 }
		return false;
	}

	public MoveObjectDetail getDetailByConditionForProcess(ItemKey itemKey,
			String srcLP, String soi, Date storageDate, PackageUnit packageUnit) {
		if (this.getDetails() == null || this.getDetails().size() == 0) {
			return null;
		}
		for (MoveObjectDetail detail : this.getDetails()) {
			if (detail.getItemKey().getId().equals(itemKey.getId())
					&& ((detail.getSrcLP() == null && srcLP == null) || (detail.getSrcLP() != null && detail.getSrcLP().equals(srcLP)))
					&& detail.getPackageUnit().getId().equals(packageUnit.getId())) {
				return detail;
			}
		}
		return null;
	}

	public void allocate(Double quantity) {
		this.allocateQuantity += quantity;
		if ((MoveDocStatus.OPEN.equals(this.getStatus()) 
				|| MoveDocStatus.ACTIVE.equals(this.getStatus()))
				&& this.allocateQuantity > 0) {
			this.setStatus(MoveDocStatus.ALLOCATE);
		}
	}

	public void unallocate(Double quantity) {
		this.allocateQuantity -= quantity;
		if (this.allocateQuantity == 0
				&& MoveDocStatus.ALLOCATE.equals(this.getStatus())) {
			this.setStatus(MoveDocStatus.OPEN);
		}
	}

	public void moveTo(Double moveQuantity) {
		this.moveQuantity += moveQuantity;
		if (MoveDocStatus.ACTIVE.equals(this.getStatus())
				|| MoveDocStatus.ALLOCATE.equals(this.getStatus())
				|| MoveDocStatus.MOVE.equals(this.getStatus())) {
			if (this.moveQuantity == this.planQuantity) {
				this.setStatus(MoveDocStatus.CLOSE);
			} else {
				this.setStatus(MoveDocStatus.MOVE);
			}
		}
	}

	public double getAllocatedQuantity() {
		return allocateQuantity;
	}

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

	public double getOrderQuantity() {
		return planQuantity;
	}

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

	public double getPickedQuantity() {
		return moveQuantity;
	}

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

	public double getShippedQuantity() {
		return 0;
	}

	public void setShippedQuantity(double shippedQuantity) {
		
	}


	public void removeDetail(MoveObjectDetail detail) {
		this.getDetails().remove(detail);
		this.planQuantity -= detail.getPlanQuantityOfMU();
	}

	public void add(double quantity) {
		this.planQuantity += quantity;
	}

	@Override
	public boolean equals(final Object other) {
		if (!(other instanceof MoveObject))
			return false;
		MoveObject castOther = (MoveObject) other;
		return new EqualsBuilder().append(warehouse, castOther.warehouse)
				.append(companyA, castOther.companyA)
				.append(code, castOther.code).append(billType,
						castOther.billType).isEquals();
	}

	@Override
	public int hashCode() {
		return new HashCodeBuilder().append(warehouse).append(companyA).append(
				code).append(billType).toHashCode();
	}


}
