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

import java.io.File;
import java.util.Date;
import java.util.List;
import java.util.Map;

import org.springframework.transaction.annotation.Transactional;

import com.dev.swms.server.model.abstractEntity.BomAccount;
import com.dev.swms.server.model.abstractEntity.PlanPickDetail;
import com.dev.swms.server.model.abstractEntity.PlanPickTicket;
import com.dev.swms.server.model.abstractEntity.ProductionPlan;
import com.dev.swms.server.model.abstractEntity.SpareParts;
import com.dev.swms.server.model.base.ItemKey;
import com.dev.swms.server.model.base.Location;
import com.dev.swms.server.model.base.WarehouseArea;
import com.dev.swms.server.model.inventory.Inventory;
import com.dev.swms.server.model.inventory.InventoryLog;
import com.dev.swms.server.model.receiving.ASN;
import com.dev.swms.server.model.shipping.BOL;
import com.dev.swms.server.model.shipping.MasterBOL;
import com.dev.swms.server.model.shipping.PickTicket;
import com.dev.swms.server.model.shipping.PickTicketDetail;
import com.dev.swms.server.model.shipping.Prewave;

import net.sf.json.JSONObject;

import com.dev.energy.server.service.BaseManager;

/**
 * @author  dev
 * 
 */
@Transactional(readOnly = true)
public interface PickTicketManager extends BaseManager {

	/**
	 * 保存拣货单－新增拣货单时自动设置所属仓库和单据状态
	 * 
	 * @param pickTicket
	 *            待保存的拣货单
	 */
	@Transactional
	void storePickTicket(PickTicket pickTicket);

	/**
	 * 激活发货单－只能激活“打开”状态的发货单
	 * 
	 * @param pickTicketIds
	 *            待激活的发货单ID清单
	 */
	@Transactional
	void activeAll(List<Long> pickTicketIds);
	@Transactional
	void appPlamAssemblys(PickTicket pt,BomAccount bomAccount,String bonded,String meg);
	@Transactional
	void activeAll(Long pickTicketId);
	
	@Transactional
	void activeAllOld(List<Long> pickTicketIds);
	@Transactional
	void checkCtPick(List<Long> pickTicketIds);
	@Transactional
	void cancelCtPick(List<Long> pickTicketIds);

	/**
	 * 取消激活发货单－只能取消激活“生效”状态的发货单
	 * 
	 * @param pickTicketIds
	 *            待取消激活的发货单ID清单
	 */
	@Transactional
	void inactiveAll(List<Long> pickTicketIds);
	@Transactional
	void inactiveAllTask(List<Long> pickTicketIds);
	@Transactional
	void inactivePlanAll(List<Long> pickTicketIds);

	/**
	 * 删除拣货单－只能删除“打开”状态的拣货单
	 * 
	 * @param pickTicketIds
	 *            待删除拣货单的ID清单
	 */
	@Transactional
	void deleteAll(List<Long> pickTicketIds);
	
	/**
	 * 删除拣货单－只能删除“打开”状态的拣货单
	 * 
	 * @param pickTicketIds
	 *            待删除拣货单的ID清单
	 */
	@Transactional
	void deleteShipDetail(List<Long> ids);
	@Transactional
	void deletePlanPickDetail(List<Long> ids);
	/**取消备货计划*/
	@Transactional
    void cancelPlanPick(List<Long> ids);
	/**
	 * 关闭拣货单－只能关闭“已发货”状态的拣货单
	 * 
	 * @param pickTicketIds
	 *            待关闭拣货单的ID清单
	 *//*
	@Transactional
	void closeAll(List<Long> pickTicketIds);*/

	/**
	 * 取消拣货单－只能取消“打开”状态的拣货单
	 * 
	 * @param pickTicketIds
	 *            待取消拣货单的ID清单
	 */
	@Transactional
	void cancelAll(List<Long> pickTicketIds);

	/**
	 * 新增拣货单明细－当PickTicketDetail对象已存在时，则直接修改拣货单明细对象
	 * 
	 * @param pickTicketId
	 *            待保存的拣货单ＩＤ
	 * @param pickTicketDetail
	 *            待增加的拣货单明细
	 */
	@Transactional
	void addPickTicketDetail(Long pickTicketId,
			PickTicketDetail pickTicketDetail);
	
	@Transactional
	void addPickTicketDetails(Long pickTicketId,List<Long> ids);

	/**
	 * 删除拣货单明细
	 * 
	 * @param pickTicket
	 *            待删除明细的拣货单ID
	 * @param pickTicketDetailIds
	 *            待删除的拣货单明细ID集合
	 */
	@Transactional
	void removePickTicketDetail(Long pickTicketId,
			List<Long> pickTicketDetailIds);
	
	
	@Transactional
	void removePlanPickTicketDetail(Long pickTicketId,
			List<Long> planPickTicketDetailIds);

	/**
	 * 对已分配的发货单取消分配
	 * @param pickTicketIds
	 */
	@Transactional
	void unallocate(List<Long> pickTicketIds);


	/**
	 * 生成BOL
	 * 
	 * @param BOL
	 * @param pickTicketIds 相关pickTicket
	 */
//	@Transactional
//	void createBOL(BOL BOL,List<Long> pickTicketIds);
	/**
	 * 保存BOL
	 * 
	 * @param BOL
	 * @param pickTicketIds
	 */
	@Transactional
	void storeBOL(BOL BOL);

	MasterBOL getMasterBOLbyCode(String code);

	/**
	 * 拣货确认－对指定的发货单拣货记录中未拣货的记录进行拣货
	 * 
	 * @param taskId 
	 * @param srcLocId
	 * @param srcLp
	 * @param lot
	 * @param packageUnitId
	 * @param pickedQuantity
	 * @param workerId
	 */
	@Transactional
	void pickConfirm(Long taskId, Long srcLocId, String srcLp, String lot, Long packageUnitId, double pickedQuantity,double weight, Long workerId);
	@Transactional
	void pickKamsForSys(Long taskId, double pickedQuantity, String bhr,Long workerId);
	@Transactional
	void shipConfirmKAMS(List<Long> pickIds);
	/**
	 * 拣货确认－对指定的发货单拣货记录中未拣货的记录进行拣货
	 * @param taskId
	 * @param pickedQuantity
	 * @param workerId
	 */
	@Transactional
	void pickConfirm(Long taskId, double pickedQuantity, Long workerId);
	
	/**
	 * 拣货确认－对指定的发货单进行拣货
	 * 
	 * @param pickedId
	 * @param workerId
	 */
	@Transactional
	void pickConfirm(Long pickTicketId, String bhr,Long workerId);
	
	PickTicket getPickTicketByCode(String code);
	
	/**
	 * 检查拣货单是否有待拣的拣货记录
	 * 
	 * @param pickTicketId
	 */
//	public boolean getPickedRecordsByPickTicket(Long pickTicketId);
	
//	public boolean getPickedRecordsByFromLocation(Long pickTicketId,Long locationId);
	/**
	 * 拣货退回---将选定的拣货记录取消拣货，并根据拣货记录创建上架计划
	 * @param pickTicketId 发货单ID
	 * @param pickedRecordIds 拣货记录ID集合
	 */
//	@Transactional
//	public void pickedBack(Long pickTicketId, List<Long> pickedRecordIds);
	
//	List<ItemKey> getRecordItemKeysByItemLP(Long fromLocationId, Long pickTicketId, String itemCode, String lp);
	
	/**
	 * 发货单预分配
	 * @param pickTicketIds
	 */
	@Transactional
	public void preAllocate(List<Long> pickTicketIds);

	/**
	 * 发货单预分配
	 * @param pickTicketIds
	 */
	@Transactional
	public boolean preAllocate(Long pickTicketId);

	/**
	 * 发货单明细预分配
	 * @param pickTicketId
	 * @param pickTicketDetails
	 */
	@Transactional
	void preAllocate(Long pickTicketId, Map pickTicketDetails);
	
	/**
	 * 发货单取消预分配
	 * @param pickTicketIds
	 */
	@Transactional
	public void unPreAllocate(List<Long> pickTicketIds);

	/**
	 * 发货单取消预分配
	 * @param pickTicketIds
	 */
	@Transactional
	public boolean unPreAllocate(Long pickTicketId);

	/**
	 * 发货单明细取消预分配
	 * @param pickTicketId
	 * @param pickTicketDetails
	 */
	@Transactional
	void unPreAllocate(Long pickTicketId, Map pickTicketDetails);
	
	@Transactional
	void willShip(List<Long> ids, Long dockId, Date shipDateStart, Date shipDateEnd);
	
	/**
	 * 整张发货单自动创建BOL
	 * @param pickTicketIds
	 */
	@Transactional
	void createBOL(List<Long> pickTicketIds);

	/**
	 * 根据选择信息手动创建BOL
	 */
	@Transactional
	void manualCreateBOL(Map pickedQuantity,Long pickTicketId);
	
	/**
	 * 根据ASN自动创建BOL
	 * @param asn
	 */
	@Transactional
	void createBOLByASN(ASN asn); 
	
	/**
	 * 手工添加新包装
	 */
	@Transactional
	void createNewPackage(Long BOLid, Long boxModelId, Integer packageNum,
			Map packageQtyMap, String packageNo, String description);

	/**
	 * 包箱拆分
	 * @param packageid
	 * @param splitQuantity
	 */
	@Transactional
	void splitPackage(Long  packageid,Integer splitQuantity);
	
	/**
	 * 包箱包装拆分
	 * @param packageid
	 * @param splitNumber
	 * @param packageUnitId
	 */
	@Transactional
	void splitPackageUnit(Long  packageid,Integer splitNumber,Long packageUnitId);
	
	/**
	 * 发货单整单退拣
	 * @param pickTicketId
	 */
	@Transactional
	void pickedBack(Long pickTicketId);
	
	/**
	 * 发货单批量退拣
	 */
	@Transactional
	void pickedBack(Long pickTicketId, List<Long> taskLogIds);
	
	/**
	 *发货单部分退拣
	*/
	@Transactional
	void pickedBack(Long pickTicketId, Long taskLogId,Double movedQuantity);
	
	/**
	 * 手工关闭发货单
	 * @param pickTicketIds
	 */
	@Transactional
	void closeAll(List<Long> pickTicketIds);
	
	@Transactional
	Map init_PA_INFO(Map params);

	@Transactional
	Map init_PD_INFO(Map params);
	
	@Transactional
	Map init_AL_INFO(Map params);
	
	@Transactional
	Map init_ALD_INFO(Map params);
//	按策略分配发货单
	@Transactional
	Map auto_Allocate(Map params);
//	对已分配的发货单取消分配	
	@Transactional
	Map cancell_Allocate(Map clientParams);
//	对发货单明细手工分配指定库存的数量
	@Transactional
	Map manual_Allocate(Map clientParams);
	
	/**
	 * 供前台调用，用于获取订单所属的货主是否按单包箱，以决定是否显示箱型信息
	 * @param map
	 * @return 是否按单包箱
	 */
	String getBePackagedFollowASN(Map map);
	
	//创建预波次号
	@Transactional
	void createPrewave(List<Long> ids);
	
	//添加发货单到预波次列表
	@Transactional
	void addpickticket(Long pid,List<Long> ids);
	
	//移除波次列表到发货单
	@Transactional
	void removepickticket(Long pid,List<Long> ids);
	
	//新建出库单明细时引用这个对象
	@Transactional
	void addPlanPickTicketDetail(Long pickTicketId,
			PickTicketDetail planPickTicketDetail);
	//修改出库明细
	@Transactional
	void modifyPlanPickTicketDetail(Long detailId, double qty);
	
	//整单拣货
	@Transactional
	void Wholepicking(Long masterBOLId, Long workerId,List<Long> pickTicketId);
	
	
	/**批量拣货确认*/
	@Transactional
	void multiPickConfirm(List<Long> ids);
	/**装车单-批量拣货确认*/
	@Transactional
	void multiPickConfirmForBOL(List<Long> ids);
	
	/**美务转换*/
	@Transactional
	void mwzh(List<Long> ids,Date date,int qty,String driver,String cph,String remark);
	
	
	@Transactional
	void shipconfirm(List<Long> ids,double fytps,String shipmentType,String cphorkddh,Date shipDate);//发运确认
	
	/**
	 * @author  dev
	 * 删除回单影像
	 */
	@Transactional
	void deleteSignFile(List<Long> ids);
	
//	对发货单明细手工分配指定库存的数量
	@Transactional
	void manualAllocate(Map clientParams,List<Long>  id);
	/**取消分配*/
	@Transactional
	void cancellAllocate(List<Long> ids);
	
	/**退货*/
	@Transactional
	void returnGoods(Long pickTicketId,Map map);
	
	/** 导入 **/
	@Transactional
	void importPickTicket(File file);
	/** 导入 **/
	@Transactional
	void importPickTicketKAMS(Long pickId,File file);
	@Transactional
	void importPickTicketKAMSCancle(Long pickId,File file);
	@Transactional
	void appAllocate(List<Long> pickTicketIds);
	/** 备货登记 **/
	@Transactional
	void confirmShip(Long pickId, Map qtys) ;
	/** 备货登记 **/
	@Transactional
	void confirmKAMSShip(Long pickId, Map qtys) ;
	/** 备货登记 **/
	@Transactional
	void confirmKAMSShipQT(Long pickId) ;
	/** 发运登记**/
	@Transactional
	void confirmShip(Long pickId) ;
	/** 发运登记**/
	@Transactional
	void confirmKAMSShip(Long pickId) ;
	
	/** 取消备货 **/
	@Transactional
	void cancelPick(Long pickId) ;
	/** 取消发货 **/
	@Transactional
	void cancelShip(Long pickId) ;
	@Transactional
	void appPlanPickTicket(List<Long> pickTicketIds);
	
	@Transactional
	void storePlanPickTicket(PlanPickTicket p);
	
	//成套生成出库单
	@Transactional
	void addpick(Map clientParams,List<Long>  id);
	
	//成套生成预备货
		@Transactional
		void addPlanPick(Map clientParams,List<Long>  id);
	
	//生成出库任务
	@Transactional
	void appPlanAssembly(List<Long> pickTicketIds,int fs1,int fs2,int fs3);
//	@Transactional
	void addpickTicketSCRJHPageer(Long id,double qty1);
	//生成拖拉机出库计划
	@Transactional
	void appPlanTLJ(List<Long> pickTicketIds);
	//获取起始机号
	@Transactional
	String getByJhMap(Map map);
	
	//耗用
	@Transactional
	void deleteProductionPlan(Long id,String tsr,double qty,String procedure);
	//完成品备货
	@Transactional
	void addpickTicketPlan_zs(Long planid,String rd,Long id,Double sum);
	@Transactional
	void addpickTicketPlan_bh(Long planid,String rd,Long id,Double sum);
	@Transactional
	void addpickTicketPlan_ctbh(Long planid,String rd,Long id,Double sum);
	@Transactional
	void copypickTicketPlan_bh(Long planid,String rd,List<Long> ids);
	@Transactional
	void appPlanPickzd(List<Long> pickTicketIds);
	//刷新手工单数量
	@Transactional
	void refPlanPick(List<Long> ids) ;
	
	@Transactional
	void addProductionp(String tsr,String str1,double qty,String procedure,String description);
	
	//生成履带机出库计划
	@Transactional
	void appPlanLDJ(List<Long> pickTicketIds);
	//接收
	@Transactional
	void pickoutConfirm(List<Long> pickTicketIds,Long zid);
	@Transactional
	void pickoutConfirm(List<Long> pickTicketIds);
	//发货确认
	@Transactional
	void confirmShipKAMS(List<Long> pickIds) ;
	
	@Transactional
	void manualAllocate(List<Long> pickIds) ;
	//KAMS审核
	@Transactional
	void activeKAMSAll(List<Long> pickTicketIds);
	//耗用
	@Transactional
	void saveProductionPlan(List<Long> pickTicketIds ,String p,Long spId);
	@Transactional
	void deleteProduction(List<Long> pickTicketIds);
	
	@Transactional
	void addInstructions(String pickTicketId,Long billTypeid,
			PlanPickDetail planPickTicketDetail);
	@Transactional
	void deletePlanAll(List<Long> pickIds);
	@Transactional
	void appzs(List<Long> pickIds);
	
	@Transactional
	void addSpareParts(SpareParts spareParts);
	
	@Transactional
	void copySpareParts(List<Long> ids);
	
	@Transactional
	void deletSpareParts(List<Long> ids);
	/***
	 * 零件耗用
	 * @param ids
	 */
	@Transactional
	void hyInv(List<Long> ids);
	/***
	 * 备货登记
	 * @param ids
	 */
	@Transactional
	void confirmPickKAMS(Long pickId, Map qtys);
	
	double getInvQtyMap(Map map);
	
	double getQuantityMap(Map map);
	
	/**
	 * 
	 * @param pickTicketDetailId 明细ID
	 * @param quantity 设变数量
	 */
	@Transactional
	void designList(long pickTicketDetailId,double quantity);
	
	boolean sheChangeColor(long pickTicketId);
	
	public Inventory findInventory(ItemKey itemkey,WarehouseArea zone,Location location,String billCode,String type);
	
	public InventoryLog addInventoryLog(String logType, int incOrDec, WarehouseArea zone,Location location,String relatedBill, 
			 ItemKey itemKey,  double occurQuantity, String LP,String operator,Long referenceLog, String description,String bhr,String cph);
}
