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

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

import net.sf.json.JSONObject;

import org.springframework.transaction.annotation.Transactional;

import com.dev.swms.server.model.base.BillType;
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.Warehouse;
import com.dev.swms.server.model.base.WarehouseArea;
import com.dev.swms.server.model.count.CountRecord;
import com.dev.swms.server.model.inventory.Inventory;
import com.dev.swms.server.model.inventory.InventoryLog;
import com.dev.swms.server.model.inventory.ItemKeyInventory;
import com.dev.swms.server.model.inventory.ProcessDoc;
import com.dev.swms.server.model.inventory.ProductInventory;
import com.dev.energy.server.service.BaseManager;

/**
 * @author  dev
 */
public interface InventoryManager extends BaseManager{
	/**
	 * 根据传入的参数生成对应的ItemKeyInventory记录，如ItemKey不存在，则系统自动创建
	 * @param warehouse 仓库
	 * @param itemKey 商品属性
	 * @return
	 */
	@Transactional
	ItemKeyInventory getItemKeyInventory(Warehouse warehouse, ItemKey itemKey);
	
	@Transactional
    void importInv(File file);
	
	/**
	 * 对指定的商品进行收货入库处理
	 * @param locationId 目标存货库位ID
	 * @param itemKey 待收货商品信息
	 * @param quantity 收货数量(基本单位数量)
	 * @param packageUnitId 收货包装
     * @param LP 托盘ID
	 * @param relatedBill 相关单号
	 * @param qualityCode 质损代码
	 * @param receiveDate 收货日期
	 */
	@Transactional
	void receiving(Long locationId, ItemKey itemKey, double quantity, Long packageUnitId, Long zone_id, String barCode,double weight,double volume,
			String relatedBill, String qualityCode, Date receiveDate, BillType billType,Boolean lock,Boolean reject);
	
	/**
	 * 收货调整－用于处理错收调整业务
	 * @param locationId 调整库位ID
	 * @param itemKey 商品信息
	 * @param quantity 调整数量(基本单位数量)
	 * @param packageUnitId 商品包装ID
     * @param LP 托盘ID
	 */
	@Transactional
	void receivingAdjust(Long locationId, ItemKey itemKey, double quantity, Long packageUnitId, Long LP,String barCode,double weight,double volume,
			String status, Date storageDate, String soi, BillType billType,Boolean lock,Boolean reject);

	/**
	 * 发货调整－用于处理错发调整业务
	 * @param locationId 调整库位ID
	 * @param itemKey 商品信息
	 * @param quantity 调整数量
	 * @param packageUnitId 商品包装ID
     * @param LP 托盘ID
	 * @param relatedBill 相关单号
	 * @param description 调整原因
	 */
	@Transactional
	void shippingAdjust(Long locationId, ItemKey itemKey, double quantity, Long packageUnitId, Long LP, 
			String status, Date storageDate, String soi, String relatedBill, BillType billType, String description,Boolean lock,Boolean reject);

	/**
	 * 库存调整-修改库存
	 * @param inventoryId 待修改库存ID
	 * @param packQty 修改后数量(包装数量)
	 * @param description 调整原因
	 */
	@Transactional
	void modifyInventory(Long inventoryId, double packQty, String description);
	
	/**
	 * 库内移位－将指定的库存数量移动到指定库位
	 * @param srcInventoryId 待移位库存ID
	 * @param destLocationId 目标库位ID
	 * @param destLP 目标托盘ID
	 * @param quantity 移位数量（基本单位数量）
	 * @param packageUnitId 移位包装ID
	 */
	@Transactional
	void moveInventory(Long srcInventoryId, Long destLocationId, Long destLP, double quantity, 
			Long packageUnitId, Long taskId, Long workerId);
	/**线边投料*/
	@Transactional
	JSONObject moveInvtl(Long srcInvId,String locCode,double quantity, String oper,Long xpp_id,Long task_log_id,String locationType,String billCode) ;
	/**线边投料*/
	@Transactional
	void moveInvtlZz(List<Long> ids);
	/**线边投料*/
	@Transactional
	 void moveInvtlHc(List<Long> ids);
	/**
	 * 手工库内移位
	 * @param srcInventoryId 源库存ID
	 * @param destLocationId 目标库位ID
	 * @param fullLPMove 是否整托移位
	 * @param dstLP 目标托盘号
	 * @param packageUnitId 目标包装ID
	 * @param quantity 移位数量
	 * @param workerId 作业人员ID
	 */
	@Transactional
	void manualMove(Long srcInventoryId, Long destLocationId, double quantity, Long workerId,String reseaon);
	

	/**
     * 包装转换
     * @param srcInventoryId 原始库存ID;
     * @param destPackageUnitId 转换到包装ID;
     * @param packQuantity 转换的包装数量;
     */
    @Transactional
    void convertPackageUnit(Long srcInventoryId, Long destPackageUnitId, double packQuantity);

    /**
     * 发货确认
     * @param locationId 库位ID
     * @param itemKey 商品
     * @param quantity 发货数量
     * @param packageUnitId 商品包装ID
     * @param LP 托盘ID
	 * @param relatedBill 相关单号
     */
    @Transactional
	void ship(Long locationId, ItemKey itemKey, double quantity, Long packageUnitId, Long LP, 
			String status, Date storageDate, String soi, String relatedBill, BillType billType);
    
    /**
     * 计算指定日期的库存进出汇总信息
     * @param date 指定汇总日期
     */
    @Transactional(readOnly = false)
    void compute(Date date,Long warehouseId);
    
    /**
     * 计算当日的库存进出汇总信息---根据库存日志表inventoryLog后台调度每日自动计算
     */
    void compute();

    /**
     * 从指定日期开始根据库存日志重算每日库存进出汇总信息
     * @param startDate 汇总起始日期
     */
    @Transactional
    void reCompute(Date startDate,Warehouse warehouse);

	/**
	 * 盘点差异调整
	 * @param countRecord
	 */
	@Transactional
	void countAdjust(CountRecord countRecord);
	
    /**
	 * 盘点盈亏调整
	 * @param InventoryIds 待修改库存ID集合
	 * @param description 调整原因
	 */
	@Transactional
	void countAdjust(List<Long> inventoryIds, String description);
	
	/**
	 * 库存锁定
	 * @param inventoryIds 选中的库存记录ID集合
	 */
	@Transactional
	void lockInventory(List<Long> inventoryIds,String lockType,String status);
	@Transactional
	void lockInventory(List<Long> inventoryIds);
	/**
	 * 库存解锁
	 * @param inventoryIds 选中的库存记录ID集合
	 */
	@Transactional
	void unlockInventory(List<Long> inventoryIds,String lockType);
	@Transactional
	void unlockInventory(List<Long> inventoryIds);
	/**
	 * 质检登记
	 * @param inventory
	 * @param quantity
	 * @param packageUnitId
	 */
	@Transactional
	void inventoryQuality(Inventory inventory, double quantity, Long packageUnitId);
	
	/**
	 * 质检通过
	 * @param inventoryIds
	 */
	@Transactional
	void qualityPass(List<Long> inventoryIds);
	
	/**
	 * 质检失败
	 * @param inventoryIds
	 */
	@Transactional
	void qualityFail(List<Long> inventoryIds);
	
	/**
	 * 质检报废
	 * @param inventory
	 * @param quantity
	 * @param packageUnitId
	 */
	@Transactional
	void qualityScrap(Inventory inventory, double quantity, Long packageUnitId);
	
	/**
	 * 库存查询接口（查询指定仓库指定批次货品的可用库存）
	 * @param items
	 * @param warehouse
	 * @return
	 */
	List<ProductInventory> getProductInventories(List<String> items, String warehouse);
	
	/**
	 * 加工消耗(直接扣减库存数量)
	 * @param srcInventoryId
	 * @param quantity
	 * @return
	 */
	@Transactional
	void processDown(Long srcInventoryId, double quantity, ProcessDoc processDoc);
	
	/**
	 * 加工收货(将新产生的BOM增加到加工库位)
	 * @param locationId
	 * @param itemKey
	 * @param quantity
	 * @param packageUnitId
	 * @param LP
	 * @param relatedBill
	 * @param qualityCode
	 * @param receiveDate
	 * @param soi
	 */
	@Transactional
	void processUp(Long locationId, ItemKey itemKey, double quantity, Long packageUnitId, 
			Long LP, String qualityCode, Date receiveDate, ProcessDoc processDoc,Boolean lock,Boolean reject);
	
	/**
	 * 库内管理批次属性调整
	 * @param inventory
	 * @param type 调整方式（按库存 or 按批次）
	 */
	@Transactional
	void storeInventoryItemKey(Inventory inventory, String type,Double quantity,Double invQuantity,Long keyID,String propC1,Date propD1,Date propD2,Date storageDate);
	
	/**
	 * 手工新增库存
	 * @param inventory
	 * @param description
	 */
	@Transactional
	void addInventory(Long itemKeyId,Inventory inventory, String lp,String description);
	
	/**
	 * 货主转换
	 * @param inventoryId
	 * @param companyBId
	 * @param transQuantity
	 */
	@Transactional
	void companyTrans(Long inventoryId,Long companyBId, double transQuantity,String moveType);
	
	/**
	 * 批量自动创建模拟库存数据
	 */
	@Transactional
	void autoCreateInventory();
	
	@Transactional
	String getMinPackageUnitByPageMap(Map map);
	
	@Transactional
	String getQuantityByPageMap(Map map);
	@Transactional
	void editInventoryStatus(List<Long> moveDocIds,String status);
	
	@Transactional
	void confirmMoveTrans(List<Long> moveObjectIds);
	
	@Transactional
	void moveToInvBatch(List<Long>  ids,Long locId);
	@Transactional
	void invLock(List<Long>  ids,boolean beLock,String status);
	
	@Transactional
	void invLpLock(List<Long>  ids,boolean beReject,String status);
	/**库存匹配*/
	@Transactional
	Inventory findInventory(ItemKey itemkey,WarehouseArea zone,Location location,String billCode,String type,Location zzkw);
	/**增加库存日志*/
	@Transactional
	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 operDesc,String bhr,String cph,Location zzkw);
}
