Browse Source

表单操作引入表达式使用

huang 2 days ago
parent
commit
c7fbd48e8d

+ 1 - 5
src/main/java/com/jsh/erp/controller/DepotHeadController.java

@@ -12,11 +12,7 @@ import com.jsh.erp.datasource.vo.DepotHeadVo4InDetail;
 import com.jsh.erp.datasource.vo.DepotHeadVo4InOutMCount;
 import com.jsh.erp.datasource.vo.DepotHeadVo4List;
 import com.jsh.erp.datasource.vo.DepotHeadVo4StatementAccount;
-import com.jsh.erp.service.DepotService;
-import com.jsh.erp.service.DepotHeadService;
-import com.jsh.erp.service.MaterialService;
-import com.jsh.erp.service.SystemConfigService;
-import com.jsh.erp.service.UserService;
+import com.jsh.erp.service.*;
 import com.jsh.erp.utils.*;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;

+ 15 - 11
src/main/java/com/jsh/erp/controller/DepotItemController.java

@@ -9,14 +9,7 @@ import com.jsh.erp.datasource.vo.DepotItemStockWarningCount;
 import com.jsh.erp.datasource.vo.DepotItemVoBatchNumberList;
 import com.jsh.erp.datasource.vo.InOutPriceVo;
 import com.jsh.erp.exception.BusinessRunTimeException;
-import com.jsh.erp.service.DepotService;
-import com.jsh.erp.service.DepotHeadService;
-import com.jsh.erp.service.DepotItemService;
-import com.jsh.erp.service.MaterialService;
-import com.jsh.erp.service.RoleService;
-import com.jsh.erp.service.SystemConfigService;
-import com.jsh.erp.service.UnitService;
-import com.jsh.erp.service.UserService;
+import com.jsh.erp.service.*;
 import com.jsh.erp.utils.*;
 import io.swagger.annotations.Api;
 import io.swagger.annotations.ApiOperation;
@@ -156,7 +149,7 @@ public class DepotItemController {
         Map<String, Object> map = new HashMap<String, Object>();
         try {
             BigDecimal stock = BigDecimal.ZERO;
-            List<MaterialVo4Unit> list = materialService.getMaterialByBarCode(barCode);
+            List<MaterialVo4Unit> list = materialService.getMaterialByBatchNumber(barCode);
             if(list!=null && list.size()>0) {
                 MaterialVo4Unit materialVo4Unit = list.get(0);
                 if(StringUtil.isNotEmpty(materialVo4Unit.getSku())){
@@ -280,6 +273,18 @@ public class DepotItemController {
                     item.put("anotherDepotName", diEx.getAnotherDepotId() == null ? "" : diEx.getAnotherDepotName());
                     item.put("mType", diEx.getMaterialType());
                     item.put("op", 1);
+                    item.put("productionDate",diEx.getProductionDate());
+                    item.put("expiryNum",diEx.getExpiryNum());
+                    item.put("supplierId",diEx.getSupplierId());
+                    item.put("batchNumber",diEx.getBatchNumber());
+                    item.put("inventory",diEx.getInventory());
+                    item.put("supplierName",diEx.getSupplierName());
+                    item.put("unitId",diEx.getUnitId());
+                    item.put("actualQuantityInStorage",diEx.getActualQuantityInStorage());
+                    item.put("warehousingVariance",diEx.getWarehousingVariance());
+                    item.put("reasonOfDifference",diEx.getReasonOfDifference());
+                    item.put("warehousingUser",diEx.getWarehousingUser());
+                    item.put("warehousingTime",diEx.getWarehousingTime());
                     dataArray.add(item);
                     //合计数据汇总
                     totalOperNumber = totalOperNumber.add(diEx.getOperNumber()==null?BigDecimal.ZERO:diEx.getOperNumber());
@@ -951,7 +956,6 @@ public class DepotItemController {
     @ApiOperation(value = "获取批次商品列表信息")
     public BaseResponseInfo getBatchNumberList(@RequestParam("name") String name,
                                                @RequestParam("depotItemId") Long depotItemId,
-                                               @RequestParam("depotId") Long depotId,
                                                @RequestParam("barCode") String barCode,
                                                @RequestParam(value = "batchNumber", required = false) String batchNumber,
                                                HttpServletRequest request) throws Exception{
@@ -965,7 +969,7 @@ public class DepotItemController {
             }
             Boolean forceFlag = systemConfigService.getForceApprovalFlag();
             Boolean inOutManageFlag = systemConfigService.getInOutManageFlag();
-            List<DepotItemVoBatchNumberList> list = depotItemService.getBatchNumberList(number, name, depotId, barCode,
+            List<DepotItemVoBatchNumberList> list = depotItemService.getBatchNumberList(number, name, null, barCode,
                     batchNumber, forceFlag, inOutManageFlag);
             map.put("rows", list);
             map.put("total", list.size());

+ 3 - 1
src/main/java/com/jsh/erp/datasource/mappers/DepotHeadMapper.java

@@ -3,9 +3,11 @@ package com.jsh.erp.datasource.mappers;
 import com.jsh.erp.datasource.entities.DepotHead;
 import com.jsh.erp.datasource.entities.DepotHeadExample;
 import java.util.List;
+
 import org.apache.ibatis.annotations.Param;
 
-public interface DepotHeadMapper {
+public interface DepotHeadMapper extends BaseMapperX<DepotHead> {
+
     long countByExample(DepotHeadExample example);
 
     int deleteByExample(DepotHeadExample example);

+ 2 - 1
src/main/java/com/jsh/erp/datasource/mappers/DepotItemMapper.java

@@ -1,11 +1,12 @@
 package com.jsh.erp.datasource.mappers;
 
+import com.jsh.erp.datasource.entities.DepotHead;
 import com.jsh.erp.datasource.entities.DepotItem;
 import com.jsh.erp.datasource.entities.DepotItemExample;
 import java.util.List;
 import org.apache.ibatis.annotations.Param;
 
-public interface DepotItemMapper {
+public interface DepotItemMapper  extends BaseMapperX<DepotItem>{
     long countByExample(DepotItemExample example);
 
     int deleteByExample(DepotItemExample example);

+ 5 - 0
src/main/java/com/jsh/erp/datasource/vo/DepotItemVoBatchNumberList.java

@@ -1,9 +1,12 @@
 package com.jsh.erp.datasource.vo;
 
 
+import lombok.Data;
+
 import java.math.BigDecimal;
 import java.util.Date;
 
+@Data
 public class DepotItemVoBatchNumberList {
 
     private String id;
@@ -18,6 +21,8 @@ public class DepotItemVoBatchNumberList {
     private String expirationDateStr;
     private BigDecimal totalNum;
 
+
+
     public String getId() {
         return id;
     }

+ 94 - 1645
src/main/java/com/jsh/erp/service/DepotHeadService.java

@@ -1,1715 +1,164 @@
 package com.jsh.erp.service;
 
-import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
-import com.jsh.erp.constants.BusinessConstants;
-import com.jsh.erp.constants.ExceptionConstants;
-import com.jsh.erp.datasource.entities.*;
-import com.jsh.erp.datasource.mappers.DepotHeadMapper;
-import com.jsh.erp.datasource.mappers.DepotHeadMapperEx;
-import com.jsh.erp.datasource.mappers.DepotItemMapperEx;
-import com.jsh.erp.datasource.vo.*;
-import com.jsh.erp.exception.BusinessRunTimeException;
-import com.jsh.erp.exception.JshException;
-import com.jsh.erp.utils.ExcelUtils;
-import com.jsh.erp.utils.PageUtils;
-import com.jsh.erp.utils.StringUtil;
-import com.jsh.erp.utils.Tools;
-import jxl.Workbook;
-import jxl.write.WritableWorkbook;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.stereotype.Service;
+import com.jsh.erp.datasource.entities.DepotHead;
+import com.jsh.erp.datasource.vo.DepotHeadVo4InDetail;
+import com.jsh.erp.datasource.vo.DepotHeadVo4InOutMCount;
+import com.jsh.erp.datasource.vo.DepotHeadVo4List;
+import com.jsh.erp.datasource.vo.DepotHeadVo4StatementAccount;
 import org.springframework.transaction.annotation.Transactional;
-import org.springframework.web.context.request.RequestContextHolder;
-import org.springframework.web.context.request.ServletRequestAttributes;
 
-import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
-import java.io.File;
 import java.math.BigDecimal;
-import java.sql.Timestamp;
-import java.util.*;
-import java.util.stream.Collectors;
+import java.util.List;
+import java.util.Map;
 
-import static com.jsh.erp.utils.Tools.getCenternTime;
-import static com.jsh.erp.utils.Tools.getNow3;
+public interface DepotHeadService {
+    DepotHead getDepotHead(long id)throws Exception;
 
-@Service
-public class DepotHeadService {
-    private Logger logger = LoggerFactory.getLogger(DepotHeadService.class);
+    List<DepotHead> getDepotHead()throws Exception;
 
-    @Resource
-    private DepotHeadMapper depotHeadMapper;
-    @Resource
-    private DepotHeadMapperEx depotHeadMapperEx;
-    @Resource
-    private UserService userService;
-    @Resource
-    private RoleService roleService;
-    @Resource
-    private DepotService depotService;
-    @Resource
-    DepotItemService depotItemService;
-    @Resource
-    private SupplierService supplierService;
-    @Resource
-    private UserBusinessService userBusinessService;
-    @Resource
-    private SystemConfigService systemConfigService;
-    @Resource
-    private SerialNumberService serialNumberService;
-    @Resource
-    private OrgaUserRelService orgaUserRelService;
-    @Resource
-    private PersonService personService;
-    @Resource
-    private AccountService accountService;
-    @Resource
-    private AccountHeadService accountHeadService;
-    @Resource
-    private AccountItemService accountItemService;
-    @Resource
-    private SequenceService sequenceService;
-    @Resource
-    DepotItemMapperEx depotItemMapperEx;
-    @Resource
-    private LogService logService;
+    List<DepotHeadVo4List> select(String type, String subType, String hasDebt, String status, String purchaseStatus, String number, String linkApply, String linkNumber,
+                                  String beginTime, String endTime, String materialParam, Long organId, Long creator, Long depotId, Long accountId, String remark) throws Exception;
 
-    public DepotHead getDepotHead(long id)throws Exception {
-        DepotHead result=null;
-        try{
-            result=depotHeadMapper.selectByPrimaryKey(id);
-        }catch(Exception e){
-            JshException.readFail(logger, e);
-        }
-        return result;
-    }
+    String[] getDepotArray(String subType) throws Exception;
 
-    public List<DepotHead> getDepotHead()throws Exception {
-        DepotHeadExample example = new DepotHeadExample();
-        example.createCriteria().andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
-        List<DepotHead> list=null;
-        try{
-            list=depotHeadMapper.selectByExample(example);
-        }catch(Exception e){
-            JshException.readFail(logger, e);
-        }
-        return list;
-    }
+    String[] getCreatorArray() throws Exception;
 
-    public List<DepotHeadVo4List> select(String type, String subType, String hasDebt, String status, String purchaseStatus, String number, String linkApply, String linkNumber,
-           String beginTime, String endTime, String materialParam, Long organId, Long creator, Long depotId, Long accountId, String remark) throws Exception {
-        List<DepotHeadVo4List> list = new ArrayList<>();
-        try{
-            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
-            Long userId = userService.getUserId(request);
-            String priceLimit = userService.getRoleTypeByUserId(userId).getPriceLimit();
-            String billCategory = getBillCategory(subType);
-            String [] depotArray = getDepotArray(subType);
-            String [] creatorArray = getCreatorArray();
-            String [] statusArray = StringUtil.isNotEmpty(status) ? status.split(",") : null;
-            String [] purchaseStatusArray = StringUtil.isNotEmpty(purchaseStatus) ? purchaseStatus.split(",") : null;
-            String [] organArray = getOrganArray(subType, purchaseStatus);
-            //以销定购,查看全部数据
-            creatorArray = StringUtil.isNotEmpty(purchaseStatus) ? null: creatorArray;
-            Map<Long,String> personMap = personService.getPersonMap();
-            Map<Long,String> accountMap = accountService.getAccountMap();
-            beginTime = Tools.parseDayToTime(beginTime,BusinessConstants.DAY_FIRST_TIME);
-            endTime = Tools.parseDayToTime(endTime,BusinessConstants.DAY_LAST_TIME);
-            PageUtils.startPage();
-            list = depotHeadMapperEx.selectByConditionDepotHead(type, subType, creatorArray, hasDebt,
-                    statusArray, purchaseStatusArray, number, linkApply, linkNumber, beginTime, endTime,
-                    materialParam, organId, organArray, creator, depotId, depotArray, accountId, remark);
-            if (null != list) {
-                List<Long> idList = new ArrayList<>();
-                List<String> numberList = new ArrayList<>();
-                for (DepotHeadVo4List dh : list) {
-                    idList.add(dh.getId());
-                    numberList.add(dh.getNumber());
-                }
-                //通过批量查询去构造map
-                Map<String,BigDecimal> finishDepositMap = getFinishDepositMapByNumberList(numberList);
-                Map<Long,Integer> financialBillNoMap = getFinancialBillNoMapByBillIdList(idList);
-                Map<String,Integer> billSizeMap = getBillSizeMapByLinkNumberList(numberList);
-                Map<Long,String> materialsListMap = findMaterialsListMapByHeaderIdList(idList);
-                Map<Long,BigDecimal> materialCountListMap = getMaterialCountListMapByHeaderIdList(idList);
-                for (DepotHeadVo4List dh : list) {
-                    if(accountMap!=null && StringUtil.isNotEmpty(dh.getAccountIdList()) && StringUtil.isNotEmpty(dh.getAccountMoneyList())) {
-                        String accountStr = accountService.getAccountStrByIdAndMoney(accountMap, dh.getAccountIdList(), dh.getAccountMoneyList());
-                        dh.setAccountName(accountStr);
-                    }
-                    if(dh.getAccountIdList() != null) {
-                        String accountidlistStr = dh.getAccountIdList().replace("[", "").replace("]", "").replaceAll("\"", "");
-                        dh.setAccountIdList(accountidlistStr);
-                    }
-                    if(dh.getAccountMoneyList() != null) {
-                        String accountmoneylistStr = dh.getAccountMoneyList().replace("[", "").replace("]", "").replaceAll("\"", "");
-                        dh.setAccountMoneyList(accountmoneylistStr);
-                    }
-                    if(dh.getChangeAmount() != null) {
-                        dh.setChangeAmount(roleService.parseBillPriceByLimit(dh.getChangeAmount().abs(), billCategory, priceLimit, request));
-                    } else {
-                        dh.setChangeAmount(BigDecimal.ZERO);
-                    }
-                    if(dh.getTotalPrice() != null) {
-                        BigDecimal lastTotalPrice = BusinessConstants.SUB_TYPE_CHECK_ENTER.equals(dh.getSubType())||
-                                BusinessConstants.SUB_TYPE_REPLAY.equals(dh.getSubType())?dh.getTotalPrice():dh.getTotalPrice().abs();
-                        dh.setTotalPrice(roleService.parseBillPriceByLimit(lastTotalPrice, billCategory, priceLimit, request));
-                    }
-                    BigDecimal discountLastMoney = dh.getDiscountLastMoney()!=null?dh.getDiscountLastMoney():BigDecimal.ZERO;
-                    dh.setDiscountLastMoney(roleService.parseBillPriceByLimit(discountLastMoney, billCategory, priceLimit, request));
-                    BigDecimal backAmount = dh.getBackAmount()!=null?dh.getBackAmount():BigDecimal.ZERO;
-                    dh.setBackAmount(roleService.parseBillPriceByLimit(backAmount, billCategory, priceLimit, request));
-                    if(dh.getDeposit() == null) {
-                        dh.setDeposit(BigDecimal.ZERO);
-                    } else {
-                        dh.setDeposit(roleService.parseBillPriceByLimit(dh.getDeposit(), billCategory, priceLimit, request));
-                    }
-                    //已经完成的欠款
-                    if(finishDepositMap!=null) {
-                        BigDecimal finishDeposit = finishDepositMap.get(dh.getNumber()) != null ? finishDepositMap.get(dh.getNumber()) : BigDecimal.ZERO;
-                        dh.setFinishDeposit(roleService.parseBillPriceByLimit(finishDeposit, billCategory, priceLimit, request));
-                    }
-                    //欠款计算
-                    BigDecimal otherMoney = dh.getOtherMoney()!=null?dh.getOtherMoney():BigDecimal.ZERO;
-                    BigDecimal deposit = dh.getDeposit()!=null?dh.getDeposit():BigDecimal.ZERO;
-                    BigDecimal changeAmount = dh.getChangeAmount()!=null?dh.getChangeAmount():BigDecimal.ZERO;
-                    BigDecimal debt = discountLastMoney.add(otherMoney).subtract((deposit.add(changeAmount)));
-                    dh.setDebt(roleService.parseBillPriceByLimit(debt, billCategory, priceLimit, request));
-                    //是否有付款单或收款单
-                    if(financialBillNoMap!=null) {
-                        Integer financialBillNoSize = financialBillNoMap.get(dh.getId());
-                        dh.setHasFinancialFlag(financialBillNoSize!=null && financialBillNoSize>0);
-                    }
-                    //是否有退款单
-                    if(billSizeMap!=null) {
-                        Integer billListSize = billSizeMap.get(dh.getNumber());
-                        dh.setHasBackFlag(billListSize!=null && billListSize>0);
-                    }
-                    if(StringUtil.isNotEmpty(dh.getSalesMan())) {
-                        dh.setSalesManStr(personService.getPersonByMapAndIds(personMap,dh.getSalesMan()));
-                    }
-                    if(dh.getOperTime() != null) {
-                        dh.setOperTimeStr(getCenternTime(dh.getOperTime()));
-                    }
-                    //商品信息简述
-                    if(materialsListMap!=null) {
-                        dh.setMaterialsList(materialsListMap.get(dh.getId()));
-                    }
-                    //商品总数量
-                    if(materialCountListMap!=null) {
-                        dh.setMaterialCount(materialCountListMap.get(dh.getId()));
-                    }
-                    //以销定购的情况(不能显示销售单据的金额和客户名称)
-                    if(StringUtil.isNotEmpty(purchaseStatus)) {
-                        dh.setOrganName("****");
-                        dh.setTotalPrice(null);
-                        dh.setDiscountLastMoney(null);
-                    }
-                }
-            }
-        } catch(Exception e){
-            JshException.readFail(logger, e);
-        }
-        return list;
-    }
+    String[] getCreatorArrayByOrg(Long organizationId) throws Exception;
 
-    /**
-     * 根据单据类型获取仓库数组
-     * @param subType
-     * @return
-     * @throws Exception
-     */
-    public String[] getDepotArray(String subType) throws Exception {
-        String [] depotArray = null;
-        if(!BusinessConstants.SUB_TYPE_PURCHASE_APPLY.equals(subType)
-                && !BusinessConstants.SUB_TYPE_PURCHASE_ORDER.equals(subType)
-                && !BusinessConstants.SUB_TYPE_SALES_ORDER.equals(subType)) {
-            String depotIds = depotService.findDepotStrByCurrentUser();
-            depotArray = StringUtil.isNotEmpty(depotIds) ? depotIds.split(",") : null;
-        }
-        return depotArray;
-    }
+    String[] getOrganArray(String subType, String purchaseStatus) throws Exception;
 
-    /**
-     * 根据角色类型获取操作员数组
-     * @return
-     * @throws Exception
-     */
-    public String[] getCreatorArray() throws Exception {
-        String creator = getCreatorByCurrentUser();
-        String [] creatorArray=null;
-        if(StringUtil.isNotEmpty(creator)){
-            creatorArray = creator.split(",");
-        }
-        return creatorArray;
-    }
+    String getCreatorByCurrentUser() throws Exception;
 
-    /**
-     * 根据角色类型获取操作员数组
-     * @param organizationId
-     * @return
-     * @throws Exception
-     */
-    public String[] getCreatorArrayByOrg(Long organizationId) throws Exception {
-        List<Long> userIdList = orgaUserRelService.getUserIdListByOrgId(organizationId);
-        if(userIdList.size()>0) {
-            List<String> userIdStrList = userIdList.stream().map(Object::toString).collect(Collectors.toList());
-            return StringUtil.listToStringArray(userIdStrList);
-        } else {
-            return "-1".split(",");
-        }
-    }
+    Map<String, BigDecimal> getFinishDepositMapByNumberList(List<String> numberList);
 
-    /**
-     * 获取机构数组
-     * @return
-     */
-    public String[] getOrganArray(String subType, String purchaseStatus) throws Exception {
-        String [] organArray = null;
-        String type = "UserCustomer";
-        Long userId = userService.getCurrentUser().getId();
-        //获取权限信息
-        String ubValue = userBusinessService.getUBValueByTypeAndKeyId(type, userId.toString());
-        List<Supplier> supplierList = supplierService.findBySelectCus();
-        if(BusinessConstants.SUB_TYPE_SALES_ORDER.equals(subType) || BusinessConstants.SUB_TYPE_SALES.equals(subType)
-                ||BusinessConstants.SUB_TYPE_SALES_RETURN.equals(subType) ) {
-            //采购订单里面选择销售订单的时候不要过滤
-            if(StringUtil.isEmpty(purchaseStatus)) {
-                if (null != supplierList && supplierList.size() > 0) {
-                    boolean customerFlag = systemConfigService.getCustomerFlag();
-                    List<String> organList = new ArrayList<>();
-                    for (Supplier supplier : supplierList) {
-                        boolean flag = ubValue.contains("[" + supplier.getId().toString() + "]");
-                        if (!customerFlag || flag) {
-                            organList.add(supplier.getId().toString());
-                        }
-                    }
-                    if(organList.size() > 0) {
-                        organArray = StringUtil.listToStringArray(organList);
-                    }
-                }
-            }
-        }
-        return organArray;
-    }
+    Map<String, Integer> getBillSizeMapByLinkNumberList(List<String> numberList) throws Exception;
 
-    /**
-     * 根据角色类型获取操作员
-     * @return
-     * @throws Exception
-     */
-    public String getCreatorByCurrentUser() throws Exception {
-        String creator = "";
-        User user = userService.getCurrentUser();
-        String roleType = userService.getRoleTypeByUserId(user.getId()).getType(); //角色类型
-        if(BusinessConstants.ROLE_TYPE_PRIVATE.equals(roleType)) {
-            creator = user.getId().toString();
-        } else if(BusinessConstants.ROLE_TYPE_THIS_ORG.equals(roleType)) {
-            creator = orgaUserRelService.getUserIdListByUserId(user.getId());
-        }
-        return creator;
-    }
-
-    public Map<String, BigDecimal> getFinishDepositMapByNumberList(List<String> numberList) {
-        Map<String,BigDecimal> finishDepositMap = new HashMap<>();
-        if(numberList.size()>0) {
-            List<FinishDepositVo> list = depotHeadMapperEx.getFinishDepositByNumberList(numberList);
-            if(list!=null && list.size()>0) {
-                for (FinishDepositVo finishDepositVo : list) {
-                    if(finishDepositVo!=null) {
-                        finishDepositMap.put(finishDepositVo.getNumber(), finishDepositVo.getFinishDeposit());
-                    }
-                }
-            }
-        }
-        return finishDepositMap;
-    }
-
-    public Map<String, Integer> getBillSizeMapByLinkNumberList(List<String> numberList) throws Exception {
-        Map<String, Integer> billListMap = new HashMap<>();
-        if(numberList.size()>0) {
-            List<DepotHead> list = getBillListByLinkNumberList(numberList);
-            if(list!=null && list.size()>0) {
-                for (DepotHead depotHead : list) {
-                    if(depotHead!=null) {
-                        billListMap.put(depotHead.getLinkNumber(), list.size());
-                    }
-                }
-            }
-        }
-        return billListMap;
-    }
-
-    public Map<Long,Integer> getFinancialBillNoMapByBillIdList(List<Long> idList) {
-        Map<Long, Integer> billListMap = new HashMap<>();
-        if(idList.size()>0) {
-            List<AccountItem> list = accountHeadService.getFinancialBillNoByBillIdList(idList);
-            if(list!=null && list.size()>0) {
-                for (AccountItem accountItem : list) {
-                    if(accountItem!=null) {
-                        billListMap.put(accountItem.getBillId(), list.size());
-                    }
-                }
-            }
-        }
-        return billListMap;
-    }
+    Map<Long,Integer> getFinancialBillNoMapByBillIdList(List<Long> idList);
 
     @Transactional(value = "transactionManager", rollbackFor = Exception.class)
-    public int insertDepotHead(JSONObject obj, HttpServletRequest request)throws Exception {
-        DepotHead depotHead = JSONObject.parseObject(obj.toJSONString(), DepotHead.class);
-        depotHead.setCreateTime(new Timestamp(System.currentTimeMillis()));
-        depotHead.setStatus(BusinessConstants.BILLS_STATUS_UN_AUDIT);
-        int result=0;
-        try{
-            result=depotHeadMapper.insert(depotHead);
-            logService.insertLog("单据", BusinessConstants.LOG_OPERATION_TYPE_ADD, request);
-        }catch(Exception e){
-            JshException.writeFail(logger, e);
-        }
-        return result;
-    }
+    int insertDepotHead(JSONObject obj, HttpServletRequest request)throws Exception;
 
     @Transactional(value = "transactionManager", rollbackFor = Exception.class)
-    public int updateDepotHead(JSONObject obj, HttpServletRequest request) throws Exception{
-        DepotHead depotHead = JSONObject.parseObject(obj.toJSONString(), DepotHead.class);
-        DepotHead dh=null;
-        try{
-            dh = depotHeadMapper.selectByPrimaryKey(depotHead.getId());
-        }catch(Exception e){
-            JshException.readFail(logger, e);
-        }
-        depotHead.setStatus(dh.getStatus());
-        depotHead.setCreateTime(dh.getCreateTime());
-        int result=0;
-        try{
-            result = depotHeadMapper.updateByPrimaryKey(depotHead);
-            logService.insertLog("单据",
-                    new StringBuffer(BusinessConstants.LOG_OPERATION_TYPE_EDIT).append(depotHead.getId()).toString(), request);
-        }catch(Exception e){
-            JshException.writeFail(logger, e);
-        }
-        return result;
-    }
+    int updateDepotHead(JSONObject obj, HttpServletRequest request) throws Exception;
 
     @Transactional(value = "transactionManager", rollbackFor = Exception.class)
-    public int deleteDepotHead(Long id, HttpServletRequest request)throws Exception {
-        return batchDeleteBillByIds(id.toString());
-    }
+    int deleteDepotHead(Long id, HttpServletRequest request)throws Exception;
 
     @Transactional(value = "transactionManager", rollbackFor = Exception.class)
-    public int batchDeleteDepotHead(String ids, HttpServletRequest request)throws Exception {
-        return batchDeleteBillByIds(ids);
-    }
+    int batchDeleteDepotHead(String ids, HttpServletRequest request)throws Exception;
 
     @Transactional(value = "transactionManager", rollbackFor = Exception.class)
-    public int batchDeleteBillByIds(String ids)throws Exception {
-        StringBuffer sb = new StringBuffer();
-        sb.append(BusinessConstants.LOG_OPERATION_TYPE_DELETE);
-        List<DepotHead> dhList = getDepotHeadListByIds(ids);
-        for(DepotHead depotHead: dhList){
-            //只有未审核的单据才能被删除
-            if(!"0".equals(depotHead.getStatus())) {
-                throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_UN_AUDIT_DELETE_FAILED_CODE,
-                        String.format(ExceptionConstants.DEPOT_HEAD_UN_AUDIT_DELETE_FAILED_MSG));
-            }
-        }
-        for(DepotHead depotHead: dhList){
-            sb.append("[").append(depotHead.getNumber()).append("]");
-            User userInfo = userService.getCurrentUser();
-            //删除入库单据,先校验序列号是否出库,如果未出库则同时删除序列号,如果已出库则不能删除单据
-            if (BusinessConstants.DEPOTHEAD_TYPE_IN.equals(depotHead.getType())) {
-                List<DepotItem> depotItemList = depotItemMapperEx.findDepotItemListBydepotheadId(depotHead.getId(), BusinessConstants.ENABLE_SERIAL_NUMBER_ENABLED);
-                if (depotItemList != null && depotItemList.size() > 0) {
-                    //单据明细里面存在序列号商品
-                    int serialNumberSellCount = depotHeadMapperEx.getSerialNumberBySell(depotHead.getNumber());
-                    if (serialNumberSellCount > 0) {
-                        //已出库则不能删除单据
-                        throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_SERIAL_IS_SELL_CODE,
-                                String.format(ExceptionConstants.DEPOT_HEAD_SERIAL_IS_SELL_MSG, depotHead.getNumber()));
-                    } else {
-                        //删除序列号
-                        SerialNumberExample example = new SerialNumberExample();
-                        example.createCriteria().andInBillNoEqualTo(depotHead.getNumber());
-                        serialNumberService.deleteByExample(example);
-                    }
-                }
-            }
-            //删除出库数据回收序列号
-            if (BusinessConstants.DEPOTHEAD_TYPE_OUT.equals(depotHead.getType())
-                    && !BusinessConstants.SUB_TYPE_TRANSFER.equals(depotHead.getSubType())) {
-                //查询单据子表列表
-                List<DepotItem> depotItemList = depotItemMapperEx.findDepotItemListBydepotheadId(depotHead.getId(), BusinessConstants.ENABLE_SERIAL_NUMBER_ENABLED);
-                /**回收序列号*/
-                if (depotItemList != null && depotItemList.size() > 0) {
-                    for (DepotItem depotItem : depotItemList) {
-                        //BasicNumber=OperNumber*ratio
-                        serialNumberService.cancelSerialNumber(depotItem.getMaterialId(), depotHead.getNumber(), (depotItem.getBasicNumber() == null ? 0 : depotItem.getBasicNumber()).intValue(), userInfo);
-                    }
-                }
-            }
-            List<DepotItem> list = depotItemService.getListByHeaderId(depotHead.getId());
-            //删除单据子表数据
-            depotItemMapperEx.batchDeleteDepotItemByDepotHeadIds(new Long[]{depotHead.getId()});
-            //删除单据主表信息
-            batchDeleteDepotHeadByIds(depotHead.getId().toString());
-            //将关联的单据置为审核状态-针对采购入库、销售出库、盘点复盘、其它入库、其它出库
-            if(StringUtil.isNotEmpty(depotHead.getLinkNumber())){
-                if((BusinessConstants.DEPOTHEAD_TYPE_IN.equals(depotHead.getType()) &&
-                        BusinessConstants.SUB_TYPE_PURCHASE.equals(depotHead.getSubType()))
-                        || (BusinessConstants.DEPOTHEAD_TYPE_OUT.equals(depotHead.getType()) &&
-                        BusinessConstants.SUB_TYPE_SALES.equals(depotHead.getSubType()))
-                        || (BusinessConstants.DEPOTHEAD_TYPE_OTHER.equals(depotHead.getType()) &&
-                        BusinessConstants.SUB_TYPE_REPLAY.equals(depotHead.getSubType()))
-                        || (BusinessConstants.DEPOTHEAD_TYPE_IN.equals(depotHead.getType()) &&
-                        BusinessConstants.SUB_TYPE_OTHER.equals(depotHead.getSubType()))
-                        || (BusinessConstants.DEPOTHEAD_TYPE_OUT.equals(depotHead.getType()) &&
-                        BusinessConstants.SUB_TYPE_OTHER.equals(depotHead.getSubType()))) {
-                    String status = BusinessConstants.BILLS_STATUS_AUDIT;
-                    //查询除当前单据之外的关联单据列表
-                    List<DepotHead> exceptCurrentList = getListByLinkNumberExceptCurrent(depotHead.getLinkNumber(), depotHead.getNumber(), depotHead.getType());
-                    if(exceptCurrentList!=null && exceptCurrentList.size()>0) {
-                        status = BusinessConstants.BILLS_STATUS_SKIPING;
-                    }
-                    DepotHead dh = new DepotHead();
-                    dh.setStatus(status);
-                    DepotHeadExample example = new DepotHeadExample();
-                    example.createCriteria().andNumberEqualTo(depotHead.getLinkNumber());
-                    depotHeadMapper.updateByExampleSelective(dh, example);
-                }
-            }
-            //将关联的单据置为审核状态-针对请购单转采购订单的情况
-            if(StringUtil.isNotEmpty(depotHead.getLinkApply())){
-                if(BusinessConstants.DEPOTHEAD_TYPE_OTHER.equals(depotHead.getType()) &&
-                        BusinessConstants.SUB_TYPE_PURCHASE_ORDER.equals(depotHead.getSubType())) {
-                    String status = BusinessConstants.BILLS_STATUS_AUDIT;
-                    //查询除当前单据之外的关联单据列表
-                    List<DepotHead> exceptCurrentList = getListByLinkApplyExceptCurrent(depotHead.getLinkApply(), depotHead.getNumber(), depotHead.getType());
-                    if(exceptCurrentList!=null && exceptCurrentList.size()>0) {
-                        status = BusinessConstants.BILLS_STATUS_SKIPING;
-                    }
-                    DepotHead dh = new DepotHead();
-                    dh.setStatus(status);
-                    DepotHeadExample example = new DepotHeadExample();
-                    example.createCriteria().andNumberEqualTo(depotHead.getLinkApply());
-                    depotHeadMapper.updateByExampleSelective(dh, example);
-                }
-            }
-            //将关联的销售订单单据置为未采购状态-针对销售订单转采购订单的情况
-            if(StringUtil.isNotEmpty(depotHead.getLinkNumber())){
-                if(BusinessConstants.DEPOTHEAD_TYPE_OTHER.equals(depotHead.getType()) &&
-                        BusinessConstants.SUB_TYPE_PURCHASE_ORDER.equals(depotHead.getSubType())) {
-                    DepotHead dh = new DepotHead();
-                    //获取分批操作后单据的商品和商品数量(汇总)
-                    List<DepotItemVo4MaterialAndSum> batchList = depotItemMapperEx.getBatchBillDetailMaterialSum(depotHead.getLinkNumber(), "normal", depotHead.getType());
-                    if(batchList.size()>0) {
-                        dh.setPurchaseStatus(BusinessConstants.PURCHASE_STATUS_SKIPING);
-                    } else {
-                        dh.setPurchaseStatus(BusinessConstants.PURCHASE_STATUS_UN_AUDIT);
-                    }
-                    DepotHeadExample example = new DepotHeadExample();
-                    example.createCriteria().andNumberEqualTo(depotHead.getLinkNumber());
-                    depotHeadMapper.updateByExampleSelective(dh, example);
-                }
-            }
-            //对于零售出库单据,更新会员的预收款信息
-            if (BusinessConstants.DEPOTHEAD_TYPE_OUT.equals(depotHead.getType())
-                    && BusinessConstants.SUB_TYPE_RETAIL.equals(depotHead.getSubType())){
-                if(BusinessConstants.PAY_TYPE_PREPAID.equals(depotHead.getPayType())) {
-                    if (depotHead.getOrganId() != null) {
-                        //更新会员预付款
-                        supplierService.updateAdvanceIn(depotHead.getOrganId());
-                    }
-                }
-            }
-            for (DepotItem depotItem : list) {
-                //更新当前库存
-                depotItemService.updateCurrentStock(depotItem);
-                //更新当前成本价
-                depotItemService.updateCurrentUnitPrice(depotItem);
-            }
-        }
-        //路径列表
-        List<String> pathList = new ArrayList<>();
-        for(DepotHead depotHead: dhList){
-            if(StringUtil.isNotEmpty(depotHead.getFileName())) {
-                pathList.add(depotHead.getFileName());
-            }
-        }
-        //逻辑删除文件
-        systemConfigService.deleteFileByPathList(pathList);
-        logService.insertLog("单据", sb.toString(),
-                ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest());
-        return 1;
-    }
+    int batchDeleteBillByIds(String ids)throws Exception;
 
-    /**
-     * 删除单据主表信息
-     * @param ids
-     * @return
-     * @throws Exception
-     */
     @Transactional(value = "transactionManager", rollbackFor = Exception.class)
-    public int batchDeleteDepotHeadByIds(String ids)throws Exception {
-        User userInfo=userService.getCurrentUser();
-        String [] idArray=ids.split(",");
-        int result=0;
-        try{
-            result = depotHeadMapperEx.batchDeleteDepotHeadByIds(new Date(),userInfo==null?null:userInfo.getId(),idArray);
-        }catch(Exception e){
-            JshException.writeFail(logger, e);
-        }
-        return result;
-    }
+    int batchDeleteDepotHeadByIds(String ids)throws Exception;
 
-    public List<DepotHead> getDepotHeadListByIds(String ids)throws Exception {
-        List<Long> idList = StringUtil.strToLongList(ids);
-        List<DepotHead> list = new ArrayList<>();
-        try{
-            DepotHeadExample example = new DepotHeadExample();
-            example.createCriteria().andIdIn(idList);
-            list = depotHeadMapper.selectByExample(example);
-        }catch(Exception e){
-            JshException.readFail(logger, e);
-        }
-        return list;
-    }
+    List<DepotHead> getDepotHeadListByIds(String ids)throws Exception;
 
-    /**
-     * 校验单据编号是否存在
-     * @param id
-     * @param number
-     * @return
-     * @throws Exception
-     */
-    public int checkIsBillNumberExist(Long id, String number)throws Exception {
-        DepotHeadExample example = new DepotHeadExample();
-        example.createCriteria().andIdNotEqualTo(id).andNumberEqualTo(number).andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
-        List<DepotHead> list = null;
-        try{
-            list = depotHeadMapper.selectByExample(example);
-        }catch(Exception e){
-            JshException.readFail(logger, e);
-        }
-        return list==null?0:list.size();
-    }
+    int checkIsBillNumberExist(Long id, String number)throws Exception;
 
     @Transactional(value = "transactionManager", rollbackFor = Exception.class)
-    public int batchSetStatus(String status, String depotHeadIDs)throws Exception {
-        int result = 0;
-        List<Long> dhIds = new ArrayList<>();
-        List<Long> ids = StringUtil.strToLongList(depotHeadIDs);
-        for(Long id: ids) {
-            DepotHead depotHead = getDepotHead(id);
-            if("0".equals(status)){
-                //进行反审核操作
-                if("1".equals(depotHead.getStatus()) && "0".equals(depotHead.getPurchaseStatus())) {
-                    dhIds.add(id);
-                } else if("2".equals(depotHead.getPurchaseStatus())) {
-                    throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_PURCHASE_STATUS_TWO_CODE,
-                            String.format(ExceptionConstants.DEPOT_HEAD_PURCHASE_STATUS_TWO_MSG));
-                } else if("3".equals(depotHead.getPurchaseStatus())) {
-                    throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_PURCHASE_STATUS_THREE_CODE,
-                            String.format(ExceptionConstants.DEPOT_HEAD_PURCHASE_STATUS_THREE_MSG));
-                } else {
-                    throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_AUDIT_TO_UN_AUDIT_FAILED_CODE,
-                            String.format(ExceptionConstants.DEPOT_HEAD_AUDIT_TO_UN_AUDIT_FAILED_MSG));
-                }
-            } else if("1".equals(status)){
-                //进行审核操作
-                if("0".equals(depotHead.getStatus())) {
-                    dhIds.add(id);
-                } else {
-                    throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_UN_AUDIT_TO_AUDIT_FAILED_CODE,
-                            String.format(ExceptionConstants.DEPOT_HEAD_UN_AUDIT_TO_AUDIT_FAILED_MSG));
-                }
-            }
-        }
-        if(dhIds.size()>0) {
-            DepotHead depotHead = new DepotHead();
-            depotHead.setStatus(status);
-            DepotHeadExample example = new DepotHeadExample();
-            example.createCriteria().andIdIn(dhIds);
-            result = depotHeadMapper.updateByExampleSelective(depotHead, example);
-            //更新当前库存
-            if(systemConfigService.getForceApprovalFlag()) {
-                for(Long dhId: dhIds) {
-                    List<DepotItem> list = depotItemService.getListByHeaderId(dhId);
-                    for (DepotItem depotItem : list) {
-                        depotItemService.updateCurrentStock(depotItem);
-                    }
-                }
-            }
-        }
-        return result;
-    }
+    int batchSetStatus(String status, String depotHeadIDs)throws Exception;
 
-    public Map<Long,String> findMaterialsListMapByHeaderIdList(List<Long> idList)throws Exception {
-        Map<Long,String> materialsListMap = new HashMap<>();
-        if(idList.size()>0) {
-            List<MaterialsListVo> list = depotHeadMapperEx.findMaterialsListMapByHeaderIdList(idList);
-            for (MaterialsListVo materialsListVo : list) {
-                String materialsList = materialsListVo.getMaterialsList();
-                if(StringUtil.isNotEmpty(materialsList)) {
-                    materialsList = materialsList.replace(",",",");
-                }
-                materialsListMap.put(materialsListVo.getHeaderId(), materialsList);
-            }
-        }
-        return materialsListMap;
-    }
+    Map<Long,String> findMaterialsListMapByHeaderIdList(List<Long> idList)throws Exception;
 
-    public Map<Long,BigDecimal> getMaterialCountListMapByHeaderIdList(List<Long> idList)throws Exception {
-        Map<Long,BigDecimal> materialCountListMap = new HashMap<>();
-        if(idList.size()>0) {
-            List<MaterialCountVo> list = depotHeadMapperEx.getMaterialCountListByHeaderIdList(idList);
-            for(MaterialCountVo materialCountVo : list){
-                materialCountListMap.put(materialCountVo.getHeaderId(), materialCountVo.getMaterialCount());
-            }
-        }
-        return materialCountListMap;
-    }
+    Map<Long,BigDecimal> getMaterialCountListMapByHeaderIdList(List<Long> idList)throws Exception;
 
-    public List<DepotHeadVo4InDetail> findInOutDetail(String beginTime, String endTime, String type, String[] creatorArray,
-                                                      String[] organArray, List<Long> categoryList, Boolean forceFlag, Boolean inOutManageFlag,
-                                                      String materialParam, List<Long> depotList, Integer oId, String number,
-                                                      Long creator, String remark, String column, String order, Integer offset, Integer rows) throws Exception{
-        List<DepotHeadVo4InDetail> list = null;
-        try{
-            list =depotHeadMapperEx.findInOutDetail(beginTime, endTime, type, creatorArray, organArray, categoryList, forceFlag, inOutManageFlag,
-                    materialParam, depotList, oId, number, creator, remark, column, order, offset, rows);
-        }catch(Exception e){
-            JshException.readFail(logger, e);
-        }
-        return list;
-    }
+    List<DepotHeadVo4InDetail> findInOutDetail(String beginTime, String endTime, String type, String[] creatorArray,
+                                               String[] organArray, List<Long> categoryList, Boolean forceFlag, Boolean inOutManageFlag,
+                                               String materialParam, List<Long> depotList, Integer oId, String number,
+                                               Long creator, String remark, String column, String order, Integer offset, Integer rows) throws Exception;
 
-    public int findInOutDetailCount(String beginTime, String endTime, String type, String[] creatorArray,
-                                    String[] organArray, List<Long> categoryList, Boolean forceFlag, Boolean inOutManageFlag, String materialParam, List<Long> depotList, Integer oId, String number,
-                                    Long creator, String remark) throws Exception{
-        int result = 0;
-        try{
-            result =depotHeadMapperEx.findInOutDetailCount(beginTime, endTime, type, creatorArray, organArray, categoryList, forceFlag, inOutManageFlag,
-                    materialParam, depotList, oId, number, creator, remark);
-        }catch(Exception e){
-            JshException.readFail(logger, e);
-        }
-        return result;
-    }
+    int findInOutDetailCount(String beginTime, String endTime, String type, String[] creatorArray,
+                             String[] organArray, List<Long> categoryList, Boolean forceFlag, Boolean inOutManageFlag, String materialParam, List<Long> depotList, Integer oId, String number,
+                             Long creator, String remark) throws Exception;
 
-    public DepotHeadVo4InDetail findInOutDetailStatistic(String beginTime, String endTime, String type, String [] creatorArray,
-                                                      String [] organArray, List<Long> categoryList, Boolean forceFlag, Boolean inOutManageFlag,
-                                                      String materialParam, List<Long> depotList, Integer oId, String number,
-                                                      Long creator, String remark) throws Exception{
-        DepotHeadVo4InDetail item = new DepotHeadVo4InDetail();
-        try{
-            List<DepotHeadVo4InDetail> list =depotHeadMapperEx.findInOutDetailStatistic(beginTime, endTime, type, creatorArray, organArray, categoryList, forceFlag, inOutManageFlag,
-                    materialParam, depotList, oId, number, creator, remark);
-            if(list.size()>0) {
-                item.setOperNumber(list.get(0).getOperNumber());
-                item.setAllPrice(list.get(0).getAllPrice());
-            }
-        }catch(Exception e){
-            JshException.readFail(logger, e);
-        }
-        return item;
-    }
+    DepotHeadVo4InDetail findInOutDetailStatistic(String beginTime, String endTime, String type, String[] creatorArray,
+                                                  String[] organArray, List<Long> categoryList, Boolean forceFlag, Boolean inOutManageFlag,
+                                                  String materialParam, List<Long> depotList, Integer oId, String number,
+                                                  Long creator, String remark) throws Exception;
 
-    public List<DepotHeadVo4InOutMCount> findInOutMaterialCount(String beginTime, String endTime, String type, List<Long> categoryList,
-                                                                Boolean forceFlag, Boolean inOutManageFlag, String materialParam,
-                                                                List<Long> depotList, Long organizationId, Integer oId, String column, String order,
-                                                                Integer offset, Integer rows)throws Exception {
-        List<DepotHeadVo4InOutMCount> list = null;
-        try{
-            String [] creatorArray = getCreatorArray();
-            if(creatorArray == null && organizationId != null) {
-                creatorArray = getCreatorArrayByOrg(organizationId);
-            }
-            String subType = "出库".equals(type)? "销售" : "";
-            String [] organArray = getOrganArray(subType, "");
-            list =depotHeadMapperEx.findInOutMaterialCount(beginTime, endTime, type, categoryList, forceFlag, inOutManageFlag, materialParam, depotList, oId,
-                    creatorArray, organArray, column, order, offset, rows);
-        }catch(Exception e){
-            JshException.readFail(logger, e);
-        }
-        return list;
-    }
+    List<DepotHeadVo4InOutMCount> findInOutMaterialCount(String beginTime, String endTime, String type, List<Long> categoryList,
+                                                         Boolean forceFlag, Boolean inOutManageFlag, String materialParam,
+                                                         List<Long> depotList, Long organizationId, Integer oId, String column, String order,
+                                                         Integer offset, Integer rows)throws Exception;
 
-    public int findInOutMaterialCountTotal(String beginTime, String endTime, String type, List<Long> categoryList,
-                                           Boolean forceFlag, Boolean inOutManageFlag, String materialParam,
-                                           List<Long> depotList, Long organizationId, Integer oId)throws Exception {
-        int result = 0;
-        try{
-            String [] creatorArray = getCreatorArray();
-            if(creatorArray == null && organizationId != null) {
-                creatorArray = getCreatorArrayByOrg(organizationId);
-            }
-            String subType = "出库".equals(type)? "销售" : "";
-            String [] organArray = getOrganArray(subType, "");
-            result =depotHeadMapperEx.findInOutMaterialCountTotal(beginTime, endTime, type, categoryList, forceFlag, inOutManageFlag, materialParam, depotList, oId,
-                    creatorArray, organArray);
-        }catch(Exception e){
-            JshException.readFail(logger, e);
-        }
-        return result;
-    }
+    int findInOutMaterialCountTotal(String beginTime, String endTime, String type, List<Long> categoryList,
+                                    Boolean forceFlag, Boolean inOutManageFlag, String materialParam,
+                                    List<Long> depotList, Long organizationId, Integer oId)throws Exception;
 
-    public DepotHeadVo4InOutMCount findInOutMaterialCountStatistic(String beginTime, String endTime, String type, List<Long> categoryList,
-                                                                Boolean forceFlag, Boolean inOutManageFlag, String materialParam,
-                                                                List<Long> depotList, Long organizationId, Integer oId) throws Exception {
-        DepotHeadVo4InOutMCount item = new DepotHeadVo4InOutMCount();
-        try{
-            String [] creatorArray = getCreatorArray();
-            if(creatorArray == null && organizationId != null) {
-                creatorArray = getCreatorArrayByOrg(organizationId);
-            }
-            String subType = "出库".equals(type)? "销售" : "";
-            String [] organArray = getOrganArray(subType, "");
-            List<DepotHeadVo4InOutMCount> list = depotHeadMapperEx.findInOutMaterialCountStatistic(beginTime, endTime, type, categoryList,
-                    forceFlag, inOutManageFlag, materialParam, depotList, oId, creatorArray, organArray);
-            if(list.size()>0) {
-                item.setNumSum(list.get(0).getNumSum());
-                item.setPriceSum(list.get(0).getPriceSum());
-            }
-        }catch(Exception e){
-            JshException.readFail(logger, e);
-        }
-        return item;
-    }
+    DepotHeadVo4InOutMCount findInOutMaterialCountStatistic(String beginTime, String endTime, String type, List<Long> categoryList,
+                                                            Boolean forceFlag, Boolean inOutManageFlag, String materialParam,
+                                                            List<Long> depotList, Long organizationId, Integer oId) throws Exception;
 
-    public List<DepotHeadVo4InDetail> findAllocationDetail(String beginTime, String endTime, String subType, String number,
-                            String [] creatorArray, List<Long> categoryList, Boolean forceFlag, String materialParam, List<Long> depotList, List<Long> depotFList,
-                            String remark, String column, String order, Integer offset, Integer rows) throws Exception{
-        List<DepotHeadVo4InDetail> list = null;
-        try{
-            list =depotHeadMapperEx.findAllocationDetail(beginTime, endTime, subType, number, creatorArray, categoryList, forceFlag,
-                    materialParam, depotList, depotFList, remark, column, order, offset, rows);
-        }catch(Exception e){
-            JshException.readFail(logger, e);
-        }
-        return list;
-    }
+    List<DepotHeadVo4InDetail> findAllocationDetail(String beginTime, String endTime, String subType, String number,
+                                                    String[] creatorArray, List<Long> categoryList, Boolean forceFlag, String materialParam, List<Long> depotList, List<Long> depotFList,
+                                                    String remark, String column, String order, Integer offset, Integer rows) throws Exception;
 
-    public int findAllocationDetailCount(String beginTime, String endTime, String subType, String number,
-                            String [] creatorArray, List<Long> categoryList, Boolean forceFlag, String materialParam, List<Long> depotList,  List<Long> depotFList,
-                            String remark) throws Exception{
-        int result = 0;
-        try{
-            result =depotHeadMapperEx.findAllocationDetailCount(beginTime, endTime, subType, number, creatorArray, categoryList, forceFlag,
-                    materialParam, depotList, depotFList, remark);
-        }catch(Exception e){
-            JshException.readFail(logger, e);
-        }
-        return result;
-    }
+    int findAllocationDetailCount(String beginTime, String endTime, String subType, String number,
+                                  String[] creatorArray, List<Long> categoryList, Boolean forceFlag, String materialParam, List<Long> depotList, List<Long> depotFList,
+                                  String remark) throws Exception;
 
-    public DepotHeadVo4InDetail findAllocationStatistic(String beginTime, String endTime, String subType, String number,
-                                                        String [] creatorArray, List<Long> categoryList, Boolean forceFlag, String materialParam, List<Long> depotList, List<Long> depotFList,
-                                                        String remark) throws Exception{
-        DepotHeadVo4InDetail item = new DepotHeadVo4InDetail();
-        try{
-            List<DepotHeadVo4InDetail> list =depotHeadMapperEx.findAllocationStatistic(beginTime, endTime, subType, number, creatorArray, categoryList, forceFlag,
-                    materialParam, depotList, depotFList, remark);
-            if(list.size()>0) {
-                item.setOperNumber(list.get(0).getOperNumber());
-                item.setAllPrice(list.get(0).getAllPrice());
-            }
-        }catch(Exception e){
-            JshException.readFail(logger, e);
-        }
-        return item;
-    }
+    DepotHeadVo4InDetail findAllocationStatistic(String beginTime, String endTime, String subType, String number,
+                                                 String[] creatorArray, List<Long> categoryList, Boolean forceFlag, String materialParam, List<Long> depotList, List<Long> depotFList,
+                                                 String remark) throws Exception;
 
-    public List<DepotHeadVo4StatementAccount> getStatementAccount(String beginTime, String endTime, Integer organId, String [] organArray,
-                                                                  Integer hasDebt, String supplierType, String type, String subType, String typeBack,
-                                                                  String subTypeBack, String billType, Integer offset, Integer rows) {
-        List<DepotHeadVo4StatementAccount> list = null;
-        try{
-            list = depotHeadMapperEx.getStatementAccount(beginTime, endTime, organId, organArray, hasDebt, supplierType, type, subType,typeBack, subTypeBack, billType, offset, rows);
-        } catch(Exception e){
-            JshException.readFail(logger, e);
-        }
-        return list;
-    }
+    List<DepotHeadVo4StatementAccount> getStatementAccount(String beginTime, String endTime, Integer organId, String[] organArray,
+                                                           Integer hasDebt, String supplierType, String type, String subType, String typeBack,
+                                                           String subTypeBack, String billType, Integer offset, Integer rows);
 
-    public int getStatementAccountCount(String beginTime, String endTime, Integer organId, String [] organArray,
-                                        Integer hasDebt, String supplierType, String type, String subType, String typeBack, String subTypeBack, String billType) {
-        int result = 0;
-        try{
-            result = depotHeadMapperEx.getStatementAccountCount(beginTime, endTime, organId, organArray, hasDebt, supplierType, type, subType,typeBack, subTypeBack, billType);
-        } catch(Exception e){
-            JshException.readFail(logger, e);
-        }
-        return result;
-    }
+    int getStatementAccountCount(String beginTime, String endTime, Integer organId, String[] organArray,
+                                 Integer hasDebt, String supplierType, String type, String subType, String typeBack, String subTypeBack, String billType);
 
-    public List<DepotHeadVo4StatementAccount> getStatementAccountTotalPay(String beginTime, String endTime, Integer organId, String [] organArray,
-                                                                          Integer hasDebt, String supplierType, String type, String subType,
-                                                                          String typeBack, String subTypeBack, String billType) {
-        List<DepotHeadVo4StatementAccount> list = null;
-        try{
-            list = depotHeadMapperEx.getStatementAccountTotalPay(beginTime, endTime, organId, organArray, hasDebt, supplierType, type, subType,typeBack, subTypeBack, billType);
-        } catch(Exception e){
-            JshException.readFail(logger, e);
-        }
-        return list;
-    }
+    List<DepotHeadVo4StatementAccount> getStatementAccountTotalPay(String beginTime, String endTime, Integer organId, String[] organArray,
+                                                                   Integer hasDebt, String supplierType, String type, String subType,
+                                                                   String typeBack, String subTypeBack, String billType);
 
-    public List<DepotHeadVo4List> getDetailByNumber(String number, HttpServletRequest request)throws Exception {
-        List<DepotHeadVo4List> resList = new ArrayList<>();
-        try{
-            Long userId = userService.getUserId(request);
-            String priceLimit = userService.getRoleTypeByUserId(userId).getPriceLimit();
-            Map<Long,String> personMap = personService.getPersonMap();
-            Map<Long,String> accountMap = accountService.getAccountMap();
-            List<DepotHeadVo4List> list = depotHeadMapperEx.getDetailByNumber(number);
-            if (null != list) {
-                List<Long> idList = new ArrayList<>();
-                List<String> numberList = new ArrayList<>();
-                for (DepotHeadVo4List dh : list) {
-                    idList.add(dh.getId());
-                    numberList.add(dh.getNumber());
-                }
-                //通过批量查询去构造map
-                Map<Long,Integer> financialBillNoMap = getFinancialBillNoMapByBillIdList(idList);
-                Map<String,Integer> billSizeMap = getBillSizeMapByLinkNumberList(numberList);
-                Map<Long,String> materialsListMap = findMaterialsListMapByHeaderIdList(idList);
-                DepotHeadVo4List dh = list.get(0);
-                String billCategory = getBillCategory(dh.getSubType());
-                if(accountMap!=null && StringUtil.isNotEmpty(dh.getAccountIdList()) && StringUtil.isNotEmpty(dh.getAccountMoneyList())) {
-                    String accountStr = accountService.getAccountStrByIdAndMoney(accountMap, dh.getAccountIdList(), dh.getAccountMoneyList());
-                    dh.setAccountName(accountStr);
-                }
-                if(dh.getAccountIdList() != null) {
-                    String accountidlistStr = dh.getAccountIdList().replace("[", "").replace("]", "").replaceAll("\"", "");
-                    dh.setAccountIdList(accountidlistStr);
-                }
-                if(dh.getAccountMoneyList() != null) {
-                    String accountmoneylistStr = dh.getAccountMoneyList().replace("[", "").replace("]", "").replaceAll("\"", "");
-                    dh.setAccountMoneyList(accountmoneylistStr);
-                }
-                if(dh.getChangeAmount() != null) {
-                    dh.setChangeAmount(roleService.parseBillPriceByLimit(dh.getChangeAmount().abs(), billCategory, priceLimit, request));
-                } else {
-                    dh.setChangeAmount(BigDecimal.ZERO);
-                }
-                if(dh.getTotalPrice() != null) {
-                    dh.setTotalPrice(roleService.parseBillPriceByLimit(dh.getTotalPrice().abs(), billCategory, priceLimit, request));
-                }
-                BigDecimal discountLastMoney = dh.getDiscountLastMoney()!=null?dh.getDiscountLastMoney():BigDecimal.ZERO;
-                dh.setDiscountLastMoney(roleService.parseBillPriceByLimit(discountLastMoney, billCategory, priceLimit, request));
-                BigDecimal backAmount = dh.getBackAmount()!=null?dh.getBackAmount():BigDecimal.ZERO;
-                dh.setBackAmount(roleService.parseBillPriceByLimit(backAmount, billCategory, priceLimit, request));
-                if(dh.getDeposit() == null) {
-                    dh.setDeposit(BigDecimal.ZERO);
-                } else {
-                    dh.setDeposit(roleService.parseBillPriceByLimit(dh.getDeposit(), billCategory, priceLimit, request));
-                }
-                //欠款计算
-                BigDecimal otherMoney = dh.getOtherMoney()!=null?dh.getOtherMoney():BigDecimal.ZERO;
-                BigDecimal deposit = dh.getDeposit()!=null?dh.getDeposit():BigDecimal.ZERO;
-                BigDecimal changeAmount = dh.getChangeAmount()!=null?dh.getChangeAmount():BigDecimal.ZERO;
-                BigDecimal debt = discountLastMoney.add(otherMoney).subtract((deposit.add(changeAmount)));
-                dh.setDebt(roleService.parseBillPriceByLimit(debt, billCategory, priceLimit, request));
-                //是否有付款单或收款单
-                if(financialBillNoMap!=null) {
-                    Integer financialBillNoSize = financialBillNoMap.get(dh.getId());
-                    dh.setHasFinancialFlag(financialBillNoSize!=null && financialBillNoSize>0);
-                }
-                //是否有退款单
-                if(billSizeMap!=null) {
-                    Integer billListSize = billSizeMap.get(dh.getNumber());
-                    dh.setHasBackFlag(billListSize!=null && billListSize>0);
-                }
-                if(StringUtil.isNotEmpty(dh.getSalesMan())) {
-                    dh.setSalesManStr(personService.getPersonByMapAndIds(personMap,dh.getSalesMan()));
-                }
-                if(dh.getOperTime() != null) {
-                    dh.setOperTimeStr(getCenternTime(dh.getOperTime()));
-                }
-                //商品信息简述
-                if(materialsListMap!=null) {
-                    dh.setMaterialsList(materialsListMap.get(dh.getId()));
-                }
-                dh.setCreatorName(userService.getUser(dh.getCreator()).getUsername());
-                resList.add(dh);
-            }
-        }catch(Exception e){
-            JshException.readFail(logger, e);
-        }
-        return resList;
-    }
+    List<DepotHeadVo4List> getDetailByNumber(String number, HttpServletRequest request)throws Exception;
 
-    /**
-     * 查询除当前单据之外的关联单据列表
-     * @param linkNumber
-     * @param number
-     * @return
-     * @throws Exception
-     */
-    public List<DepotHead> getListByLinkNumberExceptCurrent(String linkNumber, String number, String type)throws Exception {
-        DepotHeadExample example = new DepotHeadExample();
-        example.createCriteria().andLinkNumberEqualTo(linkNumber).andNumberNotEqualTo(number).andTypeEqualTo(type)
-                .andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
-        return depotHeadMapper.selectByExample(example);
-    }
+    List<DepotHead> getListByLinkNumberExceptCurrent(String linkNumber, String number, String type)throws Exception;
 
-    /**
-     * 查询除当前单据之外的关联单据列表
-     * @param linkApply
-     * @param number
-     * @return
-     * @throws Exception
-     */
-    public List<DepotHead> getListByLinkApplyExceptCurrent(String linkApply, String number, String type)throws Exception {
-        DepotHeadExample example = new DepotHeadExample();
-        example.createCriteria().andLinkApplyEqualTo(linkApply).andNumberNotEqualTo(number).andTypeEqualTo(type)
-                .andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
-        return depotHeadMapper.selectByExample(example);
-    }
+    List<DepotHead> getListByLinkApplyExceptCurrent(String linkApply, String number, String type)throws Exception;
 
-    /**
-     * 根据原单号查询关联的单据列表(批量)
-     * @param linkNumberList
-     * @return
-     * @throws Exception
-     */
-    public List<DepotHead> getBillListByLinkNumberList(List<String> linkNumberList)throws Exception {
-        if(linkNumberList!=null && linkNumberList.size()>0) {
-            DepotHeadExample example = new DepotHeadExample();
-            example.createCriteria().andLinkNumberIn(linkNumberList).andSubTypeLike("退货").andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
-            return depotHeadMapper.selectByExample(example);
-        } else {
-            return new ArrayList<>();
-        }
-    }
+    List<DepotHead> getBillListByLinkNumberList(List<String> linkNumberList)throws Exception;
 
-    /**
-     * 根据原单号查询关联的单据列表
-     * @param linkNumber
-     * @return
-     * @throws Exception
-     */
-    public List<DepotHead> getBillListByLinkNumber(String linkNumber)throws Exception {
-        DepotHeadExample example = new DepotHeadExample();
-        example.createCriteria().andLinkNumberEqualTo(linkNumber).andSubTypeLike("退货").andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
-        return depotHeadMapper.selectByExample(example);
-    }
+    List<DepotHead> getBillListByLinkNumber(String linkNumber)throws Exception;
 
-    /**
-     * 新增单据主表及单据子表信息
-     * @param beanJson
-     * @param rows
-     * @param request
-     * @throws Exception
-     */
     @Transactional(value = "transactionManager", rollbackFor = Exception.class)
-    public void addDepotHeadAndDetail(String beanJson, String rows,
-                                      HttpServletRequest request) throws Exception {
-        /**处理单据主表数据*/
-        DepotHead depotHead = JSONObject.parseObject(beanJson, DepotHead.class);
-        //校验单号是否重复
-        if(checkIsBillNumberExist(0L, depotHead.getNumber())>0) {
-            throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_BILL_NUMBER_EXIST_CODE,
-                    String.format(ExceptionConstants.DEPOT_HEAD_BILL_NUMBER_EXIST_MSG));
-        }
-        //校验是否同时录入关联请购单号和关联订单号
-        if(StringUtil.isNotEmpty(depotHead.getLinkNumber()) && StringUtil.isNotEmpty(depotHead.getLinkApply())) {
-            throw new BusinessRunTimeException(ExceptionConstants.DEPOT_ITEM_EXIST_REPEAT_NO_FAILED_CODE,
-                    String.format(ExceptionConstants.DEPOT_ITEM_EXIST_REPEAT_NO_FAILED_MSG));
-        }
-        String subType = depotHead.getSubType();
-        //结算账户校验
-        if("采购".equals(subType) || "采购退货".equals(subType) || "销售".equals(subType) || "销售退货".equals(subType)) {
-            if (StringUtil.isEmpty(depotHead.getAccountIdList()) && depotHead.getAccountId() == null) {
-                throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_ACCOUNT_FAILED_CODE,
-                        String.format(ExceptionConstants.DEPOT_HEAD_ACCOUNT_FAILED_MSG));
-            }
-        }
-        //判断用户是否已经登录过,登录过不再处理
-        User userInfo=userService.getCurrentUser();
-        depotHead.setCreator(userInfo==null?null:userInfo.getId());
-        depotHead.setCreateTime(new Timestamp(System.currentTimeMillis()));
-        if(StringUtil.isEmpty(depotHead.getStatus())) {
-            depotHead.setStatus(BusinessConstants.BILLS_STATUS_UN_AUDIT);
-        }
-        depotHead.setPurchaseStatus(BusinessConstants.BILLS_STATUS_UN_AUDIT);
-        depotHead.setPayType(depotHead.getPayType()==null?"现付":depotHead.getPayType());
-        if(StringUtil.isNotEmpty(depotHead.getAccountIdList())){
-            depotHead.setAccountIdList(depotHead.getAccountIdList().replace("[", "").replace("]", "").replaceAll("\"", ""));
-        }
-        if(StringUtil.isNotEmpty(depotHead.getAccountMoneyList())) {
-            //校验多账户的结算金额
-            String accountMoneyList = depotHead.getAccountMoneyList().replace("[", "").replace("]", "").replaceAll("\"", "");
-            BigDecimal sum = StringUtil.getArrSum(accountMoneyList.split(","));
-            BigDecimal manyAccountSum = sum.abs();
-            if(manyAccountSum.compareTo(depotHead.getChangeAmount().abs())!=0) {
-                throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_MANY_ACCOUNT_FAILED_CODE,
-                        String.format(ExceptionConstants.DEPOT_HEAD_MANY_ACCOUNT_FAILED_MSG));
-            }
-            depotHead.setAccountMoneyList(accountMoneyList);
-        }
-        //校验累计扣除订金是否超出订单中的金额
-        if(depotHead.getDeposit()!=null && StringUtil.isNotEmpty(depotHead.getLinkNumber())) {
-            BigDecimal finishDeposit = depotHeadMapperEx.getFinishDepositByNumberExceptCurrent(depotHead.getLinkNumber(), depotHead.getNumber());
-            //订单中的订金金额
-            BigDecimal changeAmount = getDepotHead(depotHead.getLinkNumber()).getChangeAmount();
-            if(changeAmount!=null) {
-                BigDecimal preDeposit = changeAmount.abs();
-                if(depotHead.getDeposit().add(finishDeposit).compareTo(preDeposit)>0) {
-                    throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_DEPOSIT_OVER_PRE_CODE,
-                            String.format(ExceptionConstants.DEPOT_HEAD_DEPOSIT_OVER_PRE_MSG));
-                }
-            }
-        }
-        //校验附件的数量
-        if(StringUtil.isNotEmpty(depotHead.getFileName())) {
-            String[] fileArr = depotHead.getFileName().split(",");
-            if(fileArr.length>4) {
-                throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_FILE_NUM_LIMIT_CODE,
-                        String.format(ExceptionConstants.DEPOT_HEAD_FILE_NUM_LIMIT_MSG, 4));
-            }
-        }
-        depotHeadMapper.insertSelective(depotHead);
-        /**入库和出库处理预付款信息*/
-        if(BusinessConstants.PAY_TYPE_PREPAID.equals(depotHead.getPayType())){
-            if(depotHead.getOrganId()!=null) {
-                BigDecimal currentAdvanceIn = supplierService.getSupplier(depotHead.getOrganId()).getAdvanceIn();
-                if(currentAdvanceIn.compareTo(depotHead.getTotalPrice())>=0) {
-                    //更新会员的预付款
-                    supplierService.updateAdvanceIn(depotHead.getOrganId());
-                } else {
-                    throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_MEMBER_PAY_LACK_CODE,
-                            String.format(ExceptionConstants.DEPOT_HEAD_MEMBER_PAY_LACK_MSG));
-                }
-            }
-        }
-        //根据单据编号查询单据id
-        DepotHeadExample dhExample = new DepotHeadExample();
-        dhExample.createCriteria().andNumberEqualTo(depotHead.getNumber()).andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
-        List<DepotHead> list = depotHeadMapper.selectByExample(dhExample);
-        if(list!=null) {
-            Long headId = list.get(0).getId();
-            /**入库和出库处理单据子表信息*/
-            depotItemService.saveDetials(rows,headId, "add",request);
-        }
-        logService.insertLog("单据",
-                new StringBuffer(BusinessConstants.LOG_OPERATION_TYPE_ADD).append(depotHead.getNumber()).toString(),
-                ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest());
-    }
+    void addDepotHeadAndDetail(String beanJson, String rows,
+                               HttpServletRequest request) throws Exception;
 
-    /**
-     * 更新单据主表及单据子表信息
-     * @param beanJson
-     * @param rows
-     * @param request
-     * @throws Exception
-     */
     @Transactional(value = "transactionManager", rollbackFor = Exception.class)
-    public void updateDepotHeadAndDetail(String beanJson, String rows,HttpServletRequest request)throws Exception {
-        /**更新单据主表信息*/
-        DepotHead depotHead = JSONObject.parseObject(beanJson, DepotHead.class);
-        //校验单号是否重复
-        if(checkIsBillNumberExist(depotHead.getId(), depotHead.getNumber())>0) {
-            throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_BILL_NUMBER_EXIST_CODE,
-                    String.format(ExceptionConstants.DEPOT_HEAD_BILL_NUMBER_EXIST_MSG));
-        }
-        //校验是否同时录入关联请购单号和关联订单号
-        if(StringUtil.isNotEmpty(depotHead.getLinkNumber()) && StringUtil.isNotEmpty(depotHead.getLinkApply())) {
-            throw new BusinessRunTimeException(ExceptionConstants.DEPOT_ITEM_EXIST_REPEAT_NO_FAILED_CODE,
-                    String.format(ExceptionConstants.DEPOT_ITEM_EXIST_REPEAT_NO_FAILED_MSG));
-        }
-        //校验单据状态,如果不是未审核则提示
-        if(!"0".equals(getDepotHead(depotHead.getId()).getStatus())) {
-            throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_BILL_CANNOT_EDIT_CODE,
-                    String.format(ExceptionConstants.DEPOT_HEAD_BILL_CANNOT_EDIT_MSG));
-        }
-        //获取之前的会员id
-        Long preOrganId = getDepotHead(depotHead.getId()).getOrganId();
-        String subType = depotHead.getSubType();
-        //结算账户校验
-        if("采购".equals(subType) || "采购退货".equals(subType) || "销售".equals(subType) || "销售退货".equals(subType)) {
-            if (StringUtil.isEmpty(depotHead.getAccountIdList()) && depotHead.getAccountId() == null) {
-                throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_ACCOUNT_FAILED_CODE,
-                        String.format(ExceptionConstants.DEPOT_HEAD_ACCOUNT_FAILED_MSG));
-            }
-        }
-        if(StringUtil.isNotEmpty(depotHead.getAccountIdList())){
-            depotHead.setAccountIdList(depotHead.getAccountIdList().replace("[", "").replace("]", "").replaceAll("\"", ""));
-        }
-        if(StringUtil.isNotEmpty(depotHead.getAccountMoneyList())) {
-            //校验多账户的结算金额
-            String accountMoneyList = depotHead.getAccountMoneyList().replace("[", "").replace("]", "").replaceAll("\"", "");
-            BigDecimal sum = StringUtil.getArrSum(accountMoneyList.split(","));
-            BigDecimal manyAccountSum = sum.abs();
-            if(manyAccountSum.compareTo(depotHead.getChangeAmount().abs())!=0) {
-                throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_MANY_ACCOUNT_FAILED_CODE,
-                        String.format(ExceptionConstants.DEPOT_HEAD_MANY_ACCOUNT_FAILED_MSG));
-            }
-            depotHead.setAccountMoneyList(accountMoneyList);
-        }
-        //校验累计扣除订金是否超出订单中的金额
-        if(depotHead.getDeposit()!=null && StringUtil.isNotEmpty(depotHead.getLinkNumber())) {
-            BigDecimal finishDeposit = depotHeadMapperEx.getFinishDepositByNumberExceptCurrent(depotHead.getLinkNumber(), depotHead.getNumber());
-            //订单中的订金金额
-            BigDecimal changeAmount = getDepotHead(depotHead.getLinkNumber()).getChangeAmount();
-            if(changeAmount!=null) {
-                BigDecimal preDeposit = changeAmount.abs();
-                if(depotHead.getDeposit().add(finishDeposit).compareTo(preDeposit)>0) {
-                    throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_DEPOSIT_OVER_PRE_CODE,
-                            String.format(ExceptionConstants.DEPOT_HEAD_DEPOSIT_OVER_PRE_MSG));
-                }
-            }
-        }
-        //校验附件的数量
-        if(StringUtil.isNotEmpty(depotHead.getFileName())) {
-            String[] fileArr = depotHead.getFileName().split(",");
-            if(fileArr.length>4) {
-                throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_FILE_NUM_LIMIT_CODE,
-                        String.format(ExceptionConstants.DEPOT_HEAD_FILE_NUM_LIMIT_MSG, 4));
-            }
-        }
-        depotHeadMapper.updateByPrimaryKeySelective(depotHead);
-        //如果存在多账户结算需要将原账户的id置空
-        if(StringUtil.isNotEmpty(depotHead.getAccountIdList())) {
-            depotHeadMapperEx.setAccountIdToNull(depotHead.getId());
-        }
-        /**入库和出库处理预付款信息*/
-        if(BusinessConstants.PAY_TYPE_PREPAID.equals(depotHead.getPayType())){
-            if(depotHead.getOrganId()!=null){
-                BigDecimal currentAdvanceIn = supplierService.getSupplier(depotHead.getOrganId()).getAdvanceIn();
-                if(currentAdvanceIn.compareTo(depotHead.getTotalPrice())>=0) {
-                    //更新会员的预付款
-                    supplierService.updateAdvanceIn(depotHead.getOrganId());
-                    if(null != preOrganId && !preOrganId.equals(depotHead.getOrganId())) {
-                        //更新之前会员的预付款
-                        supplierService.updateAdvanceIn(preOrganId);
-                    }
-                } else {
-                    throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_MEMBER_PAY_LACK_CODE,
-                            String.format(ExceptionConstants.DEPOT_HEAD_MEMBER_PAY_LACK_MSG));
-                }
-            }
-        }
-        /**入库和出库处理单据子表信息*/
-        depotItemService.saveDetials(rows,depotHead.getId(), "update",request);
-        logService.insertLog("单据",
-                new StringBuffer(BusinessConstants.LOG_OPERATION_TYPE_EDIT).append(depotHead.getNumber()).toString(),
-                ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest());
-    }
-
-    public Map<String, Object> getBuyAndSaleStatistics(String today, String monthFirstDay, String yesterdayBegin, String yesterdayEnd,
-                                                       String yearBegin, String yearEnd, HttpServletRequest request) throws Exception {
-        Long userId = userService.getUserId(request);
-        String priceLimit = userService.getRoleTypeByUserId(userId).getPriceLimit();
-        Boolean forceFlag = systemConfigService.getForceApprovalFlag();
-        String[] creatorArray = getCreatorArray();
-        List<InOutPriceVo> inOutPriceVoList = depotHeadMapperEx.getBuyAndSaleStatisticsList(yearBegin, yearEnd, creatorArray, forceFlag);
-
-        String[] periods = {"today", "month", "yesterday", "year"};
-        String[] types = {"Buy", "BuyBack", "Sale", "SaleBack", "RetailSale", "RetailSaleBack"};
-
-        Map<String, BigDecimal> statistics = new HashMap<>();
-
-        // 初始化 statistics Map
-        for (String period : periods) {
-            for (String type : types) {
-                statistics.put(period + type, BigDecimal.ZERO);
-            }
-        }
-
-        Date todayDate = Tools.strToDate(today);
-        Date monthFirstDate = Tools.strToDate(monthFirstDay);
-        Date yesterdayStartDate = Tools.strToDate(yesterdayBegin);
-        Date yesterdayEndDate = Tools.strToDate(yesterdayEnd);
-        Date yearStartDate = Tools.strToDate(yearBegin);
-        Date yearEndDate = Tools.strToDate(yearEnd);
-
-        for (InOutPriceVo item : inOutPriceVoList) {
-            Date operTime = item.getOperTime();
-            BigDecimal discountLastMoney = item.getDiscountLastMoney();
-            BigDecimal totalPriceAbs = item.getTotalPrice().abs();
-
-            if (isWithinRange(operTime, todayDate, Tools.strToDate(getNow3()))) {
-                updateStatistics(statistics, item, "today", discountLastMoney, totalPriceAbs);
-            }
-
-            if (isWithinRange(operTime, monthFirstDate, Tools.strToDate(getNow3()))) {
-                updateStatistics(statistics, item, "month", discountLastMoney, totalPriceAbs);
-            }
-
-            if (isWithinRange(operTime, yesterdayStartDate, yesterdayEndDate)) {
-                updateStatistics(statistics, item, "yesterday", discountLastMoney, totalPriceAbs);
-            }
-
-            if (isWithinRange(operTime, yearStartDate, yearEndDate)) {
-                updateStatistics(statistics, item, "year", discountLastMoney, totalPriceAbs);
-            }
-        }
-
-        Map<String, Object> result = new HashMap<>();
-        for (String period : periods) {
-            result.put(period + "Buy", roleService.parseHomePriceByLimit(statistics.get(period + "Buy").subtract(statistics.get(period + "BuyBack")), "buy", priceLimit, "***", request));
-            result.put(period + "Sale", roleService.parseHomePriceByLimit(statistics.get(period + "Sale").subtract(statistics.get(period + "SaleBack")), "sale", priceLimit, "***", request));
-            result.put(period + "RetailSale", roleService.parseHomePriceByLimit(statistics.get(period + "RetailSale").subtract(statistics.get(period + "RetailSaleBack")), "retail", priceLimit, "***", request));
-        }
-
-        return result;
-    }
-
-    private boolean isWithinRange(Date operTime, Date startDate, Date endDate) {
-        return operTime.compareTo(startDate) >= 0 && operTime.compareTo(endDate) <= 0;
-    }
-
-    private void updateStatistics(Map<String, BigDecimal> statistics, InOutPriceVo item, String period, BigDecimal discountLastMoney, BigDecimal totalPriceAbs) {
-        switch (item.getType()) {
-            case "入库":
-                switch (item.getSubType()) {
-                    case "采购":
-                        statistics.put(period + "Buy", statistics.get(period + "Buy").add(discountLastMoney));
-                        break;
-                    case "销售退货":
-                        statistics.put(period + "SaleBack", statistics.get(period + "SaleBack").add(discountLastMoney));
-                        break;
-                    case "零售退货":
-                        statistics.put(period + "RetailSaleBack", statistics.get(period + "RetailSaleBack").add(totalPriceAbs));
-                        break;
-                }
-                break;
-            case "出库":
-                switch (item.getSubType()) {
-                    case "采购退货":
-                        statistics.put(period + "BuyBack", statistics.get(period + "BuyBack").add(discountLastMoney));
-                        break;
-                    case "销售":
-                        statistics.put(period + "Sale", statistics.get(period + "Sale").add(discountLastMoney));
-                        break;
-                    case "零售":
-                        statistics.put(period + "RetailSale", statistics.get(period + "RetailSale").add(totalPriceAbs));
-                        break;
-                }
-                break;
-        }
-    }
-
-
-    public DepotHead getDepotHead(String number)throws Exception {
-        DepotHead depotHead = new DepotHead();
-        try{
-            DepotHeadExample example = new DepotHeadExample();
-            example.createCriteria().andNumberEqualTo(number).andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
-            List<DepotHead> list = depotHeadMapper.selectByExample(example);
-            if(null!=list && list.size()>0) {
-                depotHead = list.get(0);
-            }
-        }catch(Exception e){
-            JshException.readFail(logger, e);
-        }
-        return depotHead;
-    }
+    void updateDepotHeadAndDetail(String beanJson, String rows, HttpServletRequest request)throws Exception;
 
-    public List<DepotHeadVo4List> debtList(Long organId, String materialParam, String number, String beginTime, String endTime,
-                                           String status, Integer offset, Integer rows) {
-        List<DepotHeadVo4List> resList = new ArrayList<>();
-        try{
-            String depotIds = depotService.findDepotStrByCurrentUser();
-            String [] depotArray=depotIds.split(",");
-            String [] creatorArray = getCreatorArray();
-            beginTime = Tools.parseDayToTime(beginTime,BusinessConstants.DAY_FIRST_TIME);
-            endTime = Tools.parseDayToTime(endTime,BusinessConstants.DAY_LAST_TIME);
-            List<DepotHeadVo4List> list=depotHeadMapperEx.debtList(organId, creatorArray, status, number,
-                    beginTime, endTime, materialParam, depotArray, offset, rows);
-            if (null != list) {
-                resList = parseDebtBillList(list);
-            }
-        }catch(Exception e){
-            JshException.readFail(logger, e);
-        }
-        return resList;
-    }
+    Map<String, Object> getBuyAndSaleStatistics(String today, String monthFirstDay, String yesterdayBegin, String yesterdayEnd,
+                                                String yearBegin, String yearEnd, HttpServletRequest request) throws Exception;
 
-    public int debtListCount(Long organId, String materialParam, String number, String beginTime, String endTime,
-                             String status) {
-        int total = 0;
-        try {
-            String depotIds = depotService.findDepotStrByCurrentUser();
-            String[] depotArray = depotIds.split(",");
-            String[] creatorArray = getCreatorArray();
-            beginTime = Tools.parseDayToTime(beginTime, BusinessConstants.DAY_FIRST_TIME);
-            endTime = Tools.parseDayToTime(endTime, BusinessConstants.DAY_LAST_TIME);
-            total = depotHeadMapperEx.debtListCount(organId, creatorArray, status, number,
-                    beginTime, endTime, materialParam, depotArray);
-        } catch(Exception e){
-            JshException.readFail(logger, e);
-        }
-        return total;
-    }
+    DepotHead getDepotHead(String number)throws Exception;
 
-    public void debtExport(Long organId, String materialParam, String number, String type, String subType,
-                           String beginTime, String endTime, String status, String mpList,
-                           HttpServletRequest request, HttpServletResponse response) {
-        try {
-            Long userId = userService.getUserId(request);
-            String priceLimit = userService.getRoleTypeByUserId(userId).getPriceLimit();
-            String billCategory = getBillCategory(subType);
-            String depotIds = depotService.findDepotStrByCurrentUser();
-            String[] depotArray = depotIds.split(",");
-            String[] creatorArray = getCreatorArray();
-            status = StringUtil.isNotEmpty(status) ? status : null;
-            beginTime = Tools.parseDayToTime(beginTime, BusinessConstants.DAY_FIRST_TIME);
-            endTime = Tools.parseDayToTime(endTime, BusinessConstants.DAY_LAST_TIME);
-            List<DepotHeadVo4List> dhList = new ArrayList<>();
-            List<DepotHeadVo4List> list = depotHeadMapperEx.debtList(organId, creatorArray, status, number,
-                    beginTime, endTime, materialParam, depotArray, null, null);
-            if (null != list) {
-                dhList = parseDebtBillList(list);
-            }
-            //生成Excel文件
-            String fileName = "单据信息";
-            File file = new File("/opt/"+ fileName);
-            WritableWorkbook wtwb = Workbook.createWorkbook(file);
-            String oneTip = "";
-            String sheetOneStr = "";
-            if("采购".equals(subType)) {
-                oneTip = "供应商对账列表";
-                sheetOneStr = "供应商,单据编号,关联单据,商品信息,单据日期,操作员,单据金额,本单欠款,已付欠款,待付欠款,备注";
-            } else if("出库".equals(type) && "销售".equals(subType)) {
-                oneTip = "客户对账列表";
-                sheetOneStr = "客户,单据编号,关联单据,商品信息,单据日期,操作员,单据金额,本单欠款,已收欠款,待收欠款,备注";
-            }
-            if(StringUtil.isNotEmpty(beginTime) && StringUtil.isNotEmpty(endTime)) {
-                oneTip = oneTip + "(" + beginTime + "至" + endTime + ")";
-            }
-            List<String> sheetOneList = StringUtil.strToStringList(sheetOneStr);
-            String[] sheetOneArr = StringUtil.listToStringArray(sheetOneList);
-            List<Long> idList = new ArrayList<>();
-            List<String[]> billList = new ArrayList<>();
-            Map<Long, BillListCacheVo> billListCacheVoMap = new HashMap<>();
-            for (DepotHeadVo4List dh : dhList) {
-                idList.add(dh.getId());
-                BillListCacheVo billListCacheVo = new BillListCacheVo();
-                billListCacheVo.setNumber(dh.getNumber());
-                billListCacheVo.setOrganName(dh.getOrganName());
-                billListCacheVo.setOperTimeStr(getCenternTime(dh.getOperTime()));
-                billListCacheVoMap.put(dh.getId(), billListCacheVo);
-                String[] objs = new String[sheetOneArr.length];
-                objs[0] = dh.getOrganName();
-                objs[1] = dh.getNumber();
-                objs[2] = dh.getLinkNumber();
-                objs[3] = dh.getMaterialsList();
-                objs[4] = dh.getOperTimeStr();
-                objs[5] = dh.getUserName();
-                BigDecimal discountLastMoney = dh.getDiscountLastMoney() == null ? BigDecimal.ZERO : dh.getDiscountLastMoney();
-                BigDecimal otherMoney = dh.getOtherMoney() == null ? BigDecimal.ZERO : dh.getOtherMoney();
-                BigDecimal deposit = dh.getDeposit() == null ? BigDecimal.ZERO : dh.getDeposit();
-                objs[6] = parseDecimalToStr(discountLastMoney.add(otherMoney).subtract(deposit), 2);
-                objs[7] = parseDecimalToStr(dh.getNeedDebt(), 2);
-                objs[8] = parseDecimalToStr(dh.getFinishDebt(), 2);
-                objs[9] = parseDecimalToStr(dh.getDebt(), 2);
-                objs[10] = dh.getRemark();
-                billList.add(objs);
-            }
-            ExcelUtils.exportObjectsManySheet(wtwb, oneTip, sheetOneArr, "单据列表", 0, billList);
-            //导出明细数据
-            if(idList.size()>0) {
-                List<DepotItemVo4WithInfoEx> dataList = depotItemMapperEx.getBillDetailListByIds(idList);
-                String[] mpArr = mpList.split(",");
-                String twoTip = "";
-                String sheetTwoStr = "";
-                if ("采购".equals(subType)) {
-                    twoTip = "供应商单据明细";
-                    sheetTwoStr = "供应商,单据编号,单据日期,仓库名称,条码,名称,规格,型号,颜色,品牌,制造商,扩展信息,单位,序列号,批号,有效期,多属性,数量,单价,金额,税率(%),税额,价税合计,重量,备注";
-                } else if ("销售".equals(subType)) {
-                    twoTip = "客户单据明细";
-                    sheetTwoStr = "客户,单据编号,单据日期,仓库名称,条码,名称,规格,型号,颜色,品牌,制造商,扩展信息,单位,序列号,批号,有效期,多属性,数量,单价,金额,税率(%),税额,价税合计,重量,备注";
-                }
-                if (StringUtil.isNotEmpty(beginTime) && StringUtil.isNotEmpty(endTime)) {
-                    twoTip = twoTip + "(" + beginTime + "至" + endTime + ")";
-                }
-                List<String> sheetTwoList = StringUtil.strToStringList(sheetTwoStr);
-                String[] sheetTwoArr = StringUtil.listToStringArray(sheetTwoList);
-                List<String[]> billDetail = new ArrayList<>();
-                for (DepotItemVo4WithInfoEx diEx : dataList) {
-                    String[] objs = new String[sheetTwoArr.length];
-                    BillListCacheVo billListCacheVo = billListCacheVoMap.get(diEx.getHeaderId());
-                    objs[0] = billListCacheVo != null ? billListCacheVo.getOrganName() : "";
-                    objs[1] = billListCacheVo != null ? billListCacheVo.getNumber() : "";
-                    objs[2] = billListCacheVo != null ? billListCacheVo.getOperTimeStr() : "";
-                    objs[3] = diEx.getDepotId() == null ? "" : diEx.getDepotName();
-                    objs[4] = diEx.getBarCode();
-                    objs[5] = diEx.getMName();
-                    objs[6] = diEx.getMStandard();
-                    objs[7] = diEx.getMModel();
-                    objs[8] = diEx.getMColor();
-                    objs[9] = diEx.getBrand();
-                    objs[10] = diEx.getMMfrs();
-                    objs[11] = depotItemService.getOtherInfo(mpArr, diEx);
-                    objs[12] = diEx.getMaterialUnit();
-                    objs[13] = diEx.getSnList();
-                    objs[14] = diEx.getBatchNumber();
-                    objs[15] = Tools.parseDateToStr(diEx.getExpirationDate());
-                    objs[16] = diEx.getSku();
-                    objs[17] = parseDecimalToStr(diEx.getOperNumber(), 2);
-                    objs[18] = parseDecimalToStr(roleService.parseBillPriceByLimit(diEx.getUnitPrice(), billCategory, priceLimit, request), 2);
-                    objs[19] = parseDecimalToStr(roleService.parseBillPriceByLimit(diEx.getAllPrice(), billCategory, priceLimit, request), 2);
-                    objs[20] = parseDecimalToStr(roleService.parseBillPriceByLimit(diEx.getTaxRate(), billCategory, priceLimit, request), 2);
-                    objs[21] = parseDecimalToStr(roleService.parseBillPriceByLimit(diEx.getTaxMoney(), billCategory, priceLimit, request), 2);
-                    objs[22] = parseDecimalToStr(roleService.parseBillPriceByLimit(diEx.getTaxLastMoney(), billCategory, priceLimit, request), 2);
-                    BigDecimal allWeight = diEx.getBasicNumber() == null || diEx.getWeight() == null ? BigDecimal.ZERO : diEx.getBasicNumber().multiply(diEx.getWeight());
-                    objs[23] = parseDecimalToStr(allWeight, 2);
-                    objs[24] = diEx.getRemark();
-                    billDetail.add(objs);
-                }
-                ExcelUtils.exportObjectsManySheet(wtwb, twoTip, sheetTwoArr, "单据明细", 1, billDetail);
-            }
-            wtwb.write();
-            wtwb.close();
-            ExcelUtils.downloadExcel(file, file.getName(), response);
-        } catch(Exception e){
-            JshException.readFail(logger, e);
-        }
-    }
+    List<DepotHeadVo4List> debtList(Long organId, String materialParam, String number, String beginTime, String endTime,
+                                    String status, Integer offset, Integer rows);
 
-    public List<DepotHeadVo4List> parseDebtBillList(List<DepotHeadVo4List> list) throws Exception {
-        List<Long> idList = new ArrayList<>();
-        List<DepotHeadVo4List> dhList = new ArrayList<>();
-        for (DepotHeadVo4List dh : list) {
-            idList.add(dh.getId());
-        }
-        //通过批量查询去构造map
-        Map<Long,String> materialsListMap = findMaterialsListMapByHeaderIdList(idList);
-        for (DepotHeadVo4List dh : list) {
-            if(dh.getChangeAmount() != null) {
-                dh.setChangeAmount(dh.getChangeAmount().abs());
-            }
-            if(dh.getTotalPrice() != null) {
-                dh.setTotalPrice(dh.getTotalPrice().abs());
-            }
-            if(dh.getDeposit() == null) {
-                dh.setDeposit(BigDecimal.ZERO);
-            }
-            if(dh.getOperTime() != null) {
-                dh.setOperTimeStr(getCenternTime(dh.getOperTime()));
-            }
-            BigDecimal discountLastMoney = dh.getDiscountLastMoney()!=null?dh.getDiscountLastMoney():BigDecimal.ZERO;
-            BigDecimal otherMoney = dh.getOtherMoney()!=null?dh.getOtherMoney():BigDecimal.ZERO;
-            BigDecimal deposit = dh.getDeposit()!=null?dh.getDeposit():BigDecimal.ZERO;
-            BigDecimal changeAmount = dh.getChangeAmount()!=null?dh.getChangeAmount().abs():BigDecimal.ZERO;
-            //本单欠款(如果退货则为负数)
-            dh.setNeedDebt(discountLastMoney.add(otherMoney).subtract(deposit.add(changeAmount)));
-            if(BusinessConstants.SUB_TYPE_PURCHASE_RETURN.equals(dh.getSubType()) || BusinessConstants.SUB_TYPE_SALES_RETURN.equals(dh.getSubType())) {
-                dh.setNeedDebt(BigDecimal.ZERO.subtract(dh.getNeedDebt()));
-            }
-            BigDecimal needDebt = dh.getNeedDebt()!=null?dh.getNeedDebt():BigDecimal.ZERO;
-            BigDecimal finishDebt = accountItemService.getEachAmountByBillId(dh.getId());
-            finishDebt = finishDebt!=null?finishDebt:BigDecimal.ZERO;
-            //已收欠款
-            dh.setFinishDebt(finishDebt);
-            //待收欠款
-            dh.setDebt(needDebt.subtract(finishDebt));
-            //商品信息简述
-            if(materialsListMap!=null) {
-                dh.setMaterialsList(materialsListMap.get(dh.getId()));
-            }
-            dhList.add(dh);
-        }
-        return dhList;
-    }
+    int debtListCount(Long organId, String materialParam, String number, String beginTime, String endTime,
+                      String status);
 
-    public String getBillCategory(String subType) {
-        if(subType.equals("零售") || subType.equals("零售退货")) {
-            return "retail";
-        } else if(subType.equals("销售订单") || subType.equals("销售") || subType.equals("销售退货")) {
-            return "sale";
-        } else {
-            return "buy";
-        }
-    }
+    void debtExport(Long organId, String materialParam, String number, String type, String subType,
+                    String beginTime, String endTime, String status, String mpList,
+                    HttpServletRequest request, HttpServletResponse response);
 
-    /**
-     * 格式化金额样式
-     * @param decimal
-     * @param num
-     * @return
-     */
-    private String parseDecimalToStr(BigDecimal decimal, Integer num) {
-        return decimal == null ? "" : decimal.setScale(num, BigDecimal.ROUND_HALF_UP).toString();
-    }
+    List<DepotHeadVo4List> parseDebtBillList(List<DepotHeadVo4List> list) throws Exception;
 
-    private String parseStatusToStr(String status, String type) {
-        if(StringUtil.isNotEmpty(status)) {
-            if("purchase".equals(type)) {
-                switch (status) {
-                    case "2":
-                        return "完成采购";
-                    case "3":
-                        return "部分采购";
-                }
-            } else if("sale".equals(type)) {
-                switch (status) {
-                    case "2":
-                        return "完成销售";
-                    case "3":
-                        return "部分销售";
-                }
-            }
-            switch (status) {
-                case "0":
-                    return "未审核";
-                case "1":
-                    return "已审核";
-                case "9":
-                    return "审核中";
-            }
-        }
-        return "";
-    }
+    String getBillCategory(String subType);
 
-    public List<DepotHeadVo4List> waitBillList(String number, String materialParam, String type, String subType,
-                                               String beginTime, String endTime, String status, int offset, int rows) {
-        List<DepotHeadVo4List> resList = new ArrayList<>();
-        try{
-            String [] depotArray = getDepotArray("其它");
-            //给仓管可以看全部的单据(此时可以通过分配仓库去控制权限)
-            String [] creatorArray = null;
-            String [] subTypeArray = StringUtil.isNotEmpty(subType) ? subType.split(",") : null;
-            String [] statusArray = StringUtil.isNotEmpty(status) ? status.split(",") : null;
-            Map<Long,String> accountMap = accountService.getAccountMap();
-            beginTime = Tools.parseDayToTime(beginTime,BusinessConstants.DAY_FIRST_TIME);
-            endTime = Tools.parseDayToTime(endTime,BusinessConstants.DAY_LAST_TIME);
-            List<DepotHeadVo4List> list = depotHeadMapperEx.waitBillList(type, subTypeArray, creatorArray, statusArray, number, beginTime, endTime,
-                    materialParam, depotArray, offset, rows);
-            if (null != list) {
-                List<Long> idList = new ArrayList<>();
-                for (DepotHeadVo4List dh : list) {
-                    idList.add(dh.getId());
-                }
-                //通过批量查询去构造map
-                Map<Long,String> materialsListMap = findMaterialsListMapByHeaderIdList(idList);
-                Map<Long,BigDecimal> materialCountListMap = getMaterialCountListMapByHeaderIdList(idList);
-                for (DepotHeadVo4List dh : list) {
-                    if(accountMap!=null && StringUtil.isNotEmpty(dh.getAccountIdList()) && StringUtil.isNotEmpty(dh.getAccountMoneyList())) {
-                        String accountStr = accountService.getAccountStrByIdAndMoney(accountMap, dh.getAccountIdList(), dh.getAccountMoneyList());
-                        dh.setAccountName(accountStr);
-                    }
-                    if(dh.getOperTime() != null) {
-                        dh.setOperTimeStr(getCenternTime(dh.getOperTime()));
-                    }
-                    //商品信息简述
-                    if(materialsListMap!=null) {
-                        dh.setMaterialsList(materialsListMap.get(dh.getId()));
-                    }
-                    //商品总数量
-                    if(materialCountListMap!=null) {
-                        dh.setMaterialCount(materialCountListMap.get(dh.getId()));
-                    }
-                    resList.add(dh);
-                }
-            }
-        }catch(Exception e){
-            JshException.readFail(logger, e);
-        }
-        return resList;
-    }
+    List<DepotHeadVo4List> waitBillList(String number, String materialParam, String type, String subType,
+                                        String beginTime, String endTime, String status, int offset, int rows);
 
-    public Long waitBillCount(String number, String materialParam, String type, String subType,
-                             String beginTime, String endTime, String status) {
-        Long result=null;
-        try{
-            String [] depotArray = getDepotArray("其它");
-            //给仓管可以看全部的单据(此时可以通过分配仓库去控制权限)
-            String [] creatorArray = null;
-            String [] subTypeArray = StringUtil.isNotEmpty(subType) ? subType.split(",") : null;
-            String [] statusArray = StringUtil.isNotEmpty(status) ? status.split(",") : null;
-            beginTime = Tools.parseDayToTime(beginTime,BusinessConstants.DAY_FIRST_TIME);
-            endTime = Tools.parseDayToTime(endTime,BusinessConstants.DAY_LAST_TIME);
-            result=depotHeadMapperEx.waitBillCount(type, subTypeArray, creatorArray, statusArray, number, beginTime, endTime,
-                    materialParam, depotArray);
-        }catch(Exception e){
-            JshException.readFail(logger, e);
-        }
-        return result;
-    }
+    Long waitBillCount(String number, String materialParam, String type, String subType,
+                       String beginTime, String endTime, String status);
 
     @Transactional(value = "transactionManager", rollbackFor = Exception.class)
-    public void batchAddDepotHeadAndDetail(String ids, HttpServletRequest request) throws Exception {
-        List<DepotHead> dhList = getDepotHeadListByIds(ids);
-        StringBuilder sb = new StringBuilder();
-        User userInfo=userService.getCurrentUser();
-        for(DepotHead depotHead : dhList) {
-            String prefixNo = BusinessConstants.DEPOTHEAD_TYPE_IN.equals(depotHead.getType())?"QTRK":"QTCK";
-            //关联单据单号
-            String oldNumber = depotHead.getNumber();
-            //校验单据最新状态不能进行批量操作
-            if("0".equals(depotHead.getStatus()) || "2".equals(depotHead.getStatus()) || "9".equals(depotHead.getStatus())) {
-                throw new BusinessRunTimeException(ExceptionConstants.DEPOT_ITEM_EXIST_NEW_STATUS_FAILED_CODE,
-                        String.format(ExceptionConstants.DEPOT_ITEM_EXIST_NEW_STATUS_FAILED_MSG, oldNumber, depotHead.getType()));
-            }
-            //校验是否是部分入库或者部分出库
-            if("3".equals(depotHead.getStatus())) {
-                throw new BusinessRunTimeException(ExceptionConstants.DEPOT_ITEM_EXIST_PARTIALLY_STATUS_FAILED_CODE,
-                        String.format(ExceptionConstants.DEPOT_ITEM_EXIST_PARTIALLY_STATUS_FAILED_MSG, oldNumber, depotHead.getType()));
-            }
-            depotHead.setLinkNumber(oldNumber);
-            //给单号重新赋值
-            String number = prefixNo + sequenceService.buildOnlyNumber();
-            depotHead.setNumber(number);
-            depotHead.setDefaultNumber(number);
-            depotHead.setOperTime(new Date());
-            depotHead.setSubType(BusinessConstants.SUB_TYPE_OTHER);
-            depotHead.setChangeAmount(BigDecimal.ZERO);
-            depotHead.setTotalPrice(BigDecimal.ZERO);
-            depotHead.setDiscountLastMoney(BigDecimal.ZERO);
-            depotHead.setCreator(userInfo==null?null:userInfo.getId());
-            depotHead.setOrganId(null);
-            depotHead.setAccountId(null);
-            depotHead.setAccountIdList(null);
-            depotHead.setAccountMoneyList(null);
-            depotHead.setFileName(null);
-            depotHead.setSalesMan(null);
-            depotHead.setStatus("0");
-            depotHead.setTenantId(null);
-            //查询明细
-            List<DepotItemVo4WithInfoEx> itemList = depotItemService.getDetailList(depotHead.getId());
-            depotHead.setId(null);
-            JSONArray rowArr = new JSONArray();
-            for(DepotItemVo4WithInfoEx item: itemList) {
-                if("1".equals(item.getEnableSerialNumber())) {
-                    throw new BusinessRunTimeException(ExceptionConstants.DEPOT_ITEM_EXIST_SERIAL_NUMBER_FAILED_CODE,
-                            String.format(ExceptionConstants.DEPOT_ITEM_EXIST_SERIAL_NUMBER_FAILED_MSG, oldNumber));
-                }
-                if("1".equals(item.getEnableBatchNumber())) {
-                    throw new BusinessRunTimeException(ExceptionConstants.DEPOT_ITEM_EXIST_BATCH_NUMBER_FAILED_CODE,
-                            String.format(ExceptionConstants.DEPOT_ITEM_EXIST_BATCH_NUMBER_FAILED_MSG, oldNumber));
-                }
-                item.setUnitPrice(BigDecimal.ZERO);
-                item.setAllPrice(BigDecimal.ZERO);
-                item.setLinkId(item.getId());
-                item.setTenantId(null);
-                String itemStr = JSONObject.toJSONString(item);
-                JSONObject itemObj = JSONObject.parseObject(itemStr);
-                itemObj.put("unit", itemObj.getString("materialUnit"));
-                rowArr.add(itemObj.toJSONString());
-            }
-            String rows = rowArr.toJSONString();
-            //新增其它入库单或其它出库单
-            sb.append("[").append(depotHead.getNumber()).append("]");
-            depotHeadMapper.insertSelective(depotHead);
-            //根据单据编号查询单据id
-            DepotHeadExample dhExample = new DepotHeadExample();
-            dhExample.createCriteria().andNumberEqualTo(depotHead.getNumber()).andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
-            List<DepotHead> list = depotHeadMapper.selectByExample(dhExample);
-            if(list!=null) {
-                Long headId = list.get(0).getId();
-                /**入库和出库处理单据子表信息*/
-                depotItemService.saveDetials(rows, headId, "add", request);
-            }
-        }
-        logService.insertLog("单据",
-                new StringBuffer(BusinessConstants.LOG_OPERATION_TYPE_BATCH_ADD).append(sb).toString(),
-                ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest());
-    }
+    void batchAddDepotHeadAndDetail(String ids, HttpServletRequest request) throws Exception;
 }

+ 62 - 1351
src/main/java/com/jsh/erp/service/DepotItemService.java

@@ -2,1432 +2,143 @@ package com.jsh.erp.service;
 
 import com.alibaba.fastjson.JSONArray;
 import com.alibaba.fastjson.JSONObject;
-import com.jsh.erp.constants.BusinessConstants;
-import com.jsh.erp.constants.ExceptionConstants;
 import com.jsh.erp.datasource.entities.*;
-import com.jsh.erp.datasource.mappers.*;
 import com.jsh.erp.datasource.vo.DepotItemStockWarningCount;
-import com.jsh.erp.datasource.vo.DepotItemVo4Stock;
 import com.jsh.erp.datasource.vo.DepotItemVoBatchNumberList;
 import com.jsh.erp.datasource.vo.InOutPriceVo;
-import com.jsh.erp.exception.BusinessRunTimeException;
-import com.jsh.erp.exception.JshException;
-import com.jsh.erp.utils.StringUtil;
-import com.jsh.erp.utils.Tools;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.stereotype.Service;
 import org.springframework.transaction.annotation.Transactional;
 
-import javax.annotation.Resource;
 import javax.servlet.http.HttpServletRequest;
 import java.math.BigDecimal;
-import java.util.*;
+import java.util.List;
+import java.util.Map;
 
-@Service
-public class DepotItemService {
-    private Logger logger = LoggerFactory.getLogger(DepotItemService.class);
+public interface DepotItemService {
+    DepotItem getDepotItem(long id)throws Exception;
 
-    private final static String TYPE = "入库";
-    private final static String SUM_TYPE = "number";
-    private final static String IN = "in";
-    private final static String OUT = "out";
+    List<DepotItem> getDepotItem()throws Exception;
 
-    @Resource
-    private DepotItemMapper depotItemMapper;
-    @Resource
-    private DepotItemMapperEx depotItemMapperEx;
-    @Resource
-    private MaterialService materialService;
-    @Resource
-    private MaterialExtendService materialExtendService;
-    @Resource
-    private SerialNumberMapperEx serialNumberMapperEx;
-    @Resource
-    private DepotHeadService depotHeadService;
-    @Resource
-    private DepotHeadMapper depotHeadMapper;
-    @Resource
-    private SerialNumberService serialNumberService;
-    @Resource
-    private UserService userService;
-    @Resource
-    private SystemConfigService systemConfigService;
-    @Resource
-    private DepotService depotService;
-    @Resource
-    private UnitService unitService;
-    @Resource
-    private MaterialCurrentStockMapper materialCurrentStockMapper;
-    @Resource
-    private MaterialCurrentStockMapperEx materialCurrentStockMapperEx;
-    @Resource
-    private LogService logService;
+    List<DepotItem> select(String name, Integer type, String remark, int offset, int rows)throws Exception;
 
-    public DepotItem getDepotItem(long id)throws Exception {
-        DepotItem result=null;
-        try{
-            result=depotItemMapper.selectByPrimaryKey(id);
-        }catch(Exception e){
-            JshException.readFail(logger, e);
-        }
-        return result;
-    }
-
-    public List<DepotItem> getDepotItem()throws Exception {
-        DepotItemExample example = new DepotItemExample();
-        example.createCriteria().andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
-        List<DepotItem> list=null;
-        try{
-            list=depotItemMapper.selectByExample(example);
-        }catch(Exception e){
-            JshException.readFail(logger, e);
-        }
-        return list;
-    }
-
-    public List<DepotItem> select(String name, Integer type, String remark, int offset, int rows)throws Exception {
-        List<DepotItem> list=null;
-        try{
-            list=depotItemMapperEx.selectByConditionDepotItem(name, type, remark, offset, rows);
-        }catch(Exception e){
-            JshException.readFail(logger, e);
-        }
-        return list;
-    }
-
-    public Long countDepotItem(String name, Integer type, String remark) throws Exception{
-        Long result =null;
-        try{
-            result=depotItemMapperEx.countsByDepotItem(name, type, remark);
-        }catch(Exception e){
-            JshException.readFail(logger, e);
-        }
-        return result;
-    }
+    Long countDepotItem(String name, Integer type, String remark) throws Exception;
 
     @Transactional(value = "transactionManager", rollbackFor = Exception.class)
-    public int insertDepotItem(JSONObject obj, HttpServletRequest request)throws Exception {
-        DepotItem depotItem = JSONObject.parseObject(obj.toJSONString(), DepotItem.class);
-        int result =0;
-        try{
-            result=depotItemMapper.insertSelective(depotItem);
-        }catch(Exception e){
-            JshException.readFail(logger, e);
-        }
-        return result;
-    }
+    int insertDepotItem(JSONObject obj, HttpServletRequest request)throws Exception;
 
     @Transactional(value = "transactionManager", rollbackFor = Exception.class)
-    public int updateDepotItem(JSONObject obj, HttpServletRequest request)throws Exception {
-        DepotItem depotItem = JSONObject.parseObject(obj.toJSONString(), DepotItem.class);
-        int result =0;
-        try{
-            result=depotItemMapper.updateByPrimaryKeySelective(depotItem);
-        }catch(Exception e){
-            JshException.readFail(logger, e);
-        }
-        return result;
-    }
+    int updateDepotItem(JSONObject obj, HttpServletRequest request)throws Exception;
 
     @Transactional(value = "transactionManager", rollbackFor = Exception.class)
-    public int deleteDepotItem(Long id, HttpServletRequest request)throws Exception {
-        int result =0;
-        try{
-            result=depotItemMapper.deleteByPrimaryKey(id);
-        }catch(Exception e){
-            JshException.writeFail(logger, e);
-        }
-        return result;
-    }
+    int deleteDepotItem(Long id, HttpServletRequest request)throws Exception;
 
     @Transactional(value = "transactionManager", rollbackFor = Exception.class)
-    public int batchDeleteDepotItem(String ids, HttpServletRequest request)throws Exception {
-        List<Long> idList = StringUtil.strToLongList(ids);
-        DepotItemExample example = new DepotItemExample();
-        example.createCriteria().andIdIn(idList);
-        int result =0;
-        try{
-            result=depotItemMapper.deleteByExample(example);
-        }catch(Exception e){
-            JshException.writeFail(logger, e);
-        }
-        return result;
-    }
+    int batchDeleteDepotItem(String ids, HttpServletRequest request)throws Exception;
 
-    public int checkIsNameExist(Long id, String name)throws Exception {
-        DepotItemExample example = new DepotItemExample();
-        example.createCriteria().andIdNotEqualTo(id).andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
-        List<DepotItem> list =null;
-        try{
-            list=depotItemMapper.selectByExample(example);
-        }catch(Exception e){
-            JshException.readFail(logger, e);
-        }
-        return list==null?0:list.size();
-    }
+    int checkIsNameExist(Long id, String name)throws Exception;
 
-    public List<DepotItemVo4DetailByTypeAndMId> findDetailByDepotIdsAndMaterialIdList(String depotIds, Boolean forceFlag, Boolean inOutManageFlag, String sku, String batchNumber,
-                                                                                      String number, String beginTime, String endTime, Long mId, Integer offset, Integer rows)throws Exception {
-        Long depotId = null;
-        if(StringUtil.isNotEmpty(depotIds)) {
-            depotId = Long.parseLong(depotIds);
-        }
-        List<Long> depotList = depotService.parseDepotList(depotId);
-        Long[] depotIdArray = StringUtil.listToLongArray(depotList);
-        List<DepotItemVo4DetailByTypeAndMId> list =null;
-        try{
-            list = depotItemMapperEx.findDetailByDepotIdsAndMaterialIdList(depotIdArray, forceFlag, inOutManageFlag, sku, batchNumber, number, beginTime, endTime, mId, offset, rows);
-        }catch(Exception e){
-            JshException.readFail(logger, e);
-        }
-        return list;
-    }
+    List<DepotItemVo4DetailByTypeAndMId> findDetailByDepotIdsAndMaterialIdList(String depotIds, Boolean forceFlag, Boolean inOutManageFlag, String sku, String batchNumber,
+                                                                               String number, String beginTime, String endTime, Long mId, Integer offset, Integer rows)throws Exception;
 
-    public Long findDetailByDepotIdsAndMaterialIdCount(String depotIds, Boolean forceFlag, Boolean inOutManageFlag, String sku, String batchNumber,
-                                                       String number, String beginTime, String endTime, Long mId)throws Exception {
-        Long depotId = null;
-        if(StringUtil.isNotEmpty(depotIds)) {
-            depotId = Long.parseLong(depotIds);
-        }
-        List<Long> depotList = depotService.parseDepotList(depotId);
-        Long[] depotIdArray = StringUtil.listToLongArray(depotList);
-        Long result =null;
-        try{
-            result = depotItemMapperEx.findDetailByDepotIdsAndMaterialIdCount(depotIdArray, forceFlag, inOutManageFlag, sku, batchNumber, number, beginTime, endTime, mId);
-        }catch(Exception e){
-            JshException.readFail(logger, e);
-        }
-        return result;
-    }
+    Long findDetailByDepotIdsAndMaterialIdCount(String depotIds, Boolean forceFlag, Boolean inOutManageFlag, String sku, String batchNumber,
+                                                String number, String beginTime, String endTime, Long mId)throws Exception;
 
     @Transactional(value = "transactionManager", rollbackFor = Exception.class)
-    public int insertDepotItemWithObj(DepotItem depotItem)throws Exception {
-        int result =0;
-        try{
-            result = depotItemMapper.insertSelective(depotItem);
-        }catch(Exception e){
-            JshException.writeFail(logger, e);
-        }
-        return result;
-    }
+    int insertDepotItemWithObj(DepotItem depotItem)throws Exception;
 
     @Transactional(value = "transactionManager", rollbackFor = Exception.class)
-    public int updateDepotItemWithObj(DepotItem depotItem)throws Exception {
-        int result =0;
-        try{
-            result = depotItemMapper.updateByPrimaryKeySelective(depotItem);
-        }catch(Exception e){
-            JshException.writeFail(logger, e);
-        }
-        return result;
-    }
+    int updateDepotItemWithObj(DepotItem depotItem)throws Exception;
 
-    public List<DepotItem> getListByHeaderId(Long headerId)throws Exception {
-        List<DepotItem> list =null;
-        try{
-            DepotItemExample example = new DepotItemExample();
-            example.createCriteria().andHeaderIdEqualTo(headerId).andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
-            list = depotItemMapper.selectByExample(example);
-        }catch(Exception e){
-            JshException.readFail(logger, e);
-        }
-        return list;
-    }
+    List<DepotItem> getListByHeaderId(Long headerId)throws Exception;
 
-    /**
-     * 查询当前单据中指定商品的明细信息
-     * @param headerId
-     * @param meId
-     * @return
-     * @throws Exception
-     */
-    public DepotItem getItemByHeaderIdAndMaterial(Long headerId, Long meId)throws Exception {
-        DepotItem depotItem = new DepotItem();
-        try{
-            DepotItemExample example = new DepotItemExample();
-            example.createCriteria().andHeaderIdEqualTo(headerId).andMaterialExtendIdEqualTo(meId).andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
-            List<DepotItem> list = depotItemMapper.selectByExample(example);
-            if(list!=null && list.size()>0) {
-                depotItem = list.get(0);
-            }
-        }catch(Exception e){
-            JshException.readFail(logger, e);
-        }
-        return depotItem;
-    }
+    DepotItem getItemByHeaderIdAndMaterial(Long headerId, Long meId)throws Exception;
 
-    /**
-     * 查询被关联订单中指定商品的明细信息
-     * @param linkStr
-     * @param meId
-     * @return
-     * @throws Exception
-     */
-    public DepotItem getPreItemByHeaderIdAndMaterial(String linkStr, Long meId, Long linkId)throws Exception {
-        DepotItem depotItem = new DepotItem();
-        try{
-            DepotHead depotHead = depotHeadService.getDepotHead(linkStr);
-            if(null!=depotHead && null!=depotHead.getId()) {
-                DepotItemExample example = new DepotItemExample();
-                example.createCriteria().andHeaderIdEqualTo(depotHead.getId()).andMaterialExtendIdEqualTo(meId).andIdEqualTo(linkId).andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
-                List<DepotItem> list = depotItemMapper.selectByExample(example);
-                if(list!=null && list.size()>0) {
-                    depotItem = list.get(0);
-                }
-            }
-        }catch(Exception e){
-            JshException.readFail(logger, e);
-        }
-        return depotItem;
-    }
+    DepotItem getPreItemByHeaderIdAndMaterial(String linkStr, Long meId, Long linkId)throws Exception;
 
-    public List<DepotItemVo4WithInfoEx> getDetailList(Long headerId)throws Exception {
-        List<DepotItemVo4WithInfoEx> list =null;
-        try{
-            list = depotItemMapperEx.getDetailList(headerId);
-        }catch(Exception e){
-            JshException.readFail(logger, e);
-        }
-        return list;
-    }
+    List<DepotItemVo4WithInfoEx> getDetailList(Long headerId)throws Exception;
 
-    public List<DepotItemVo4WithInfoEx> getInOutStock(String materialParam, List<Long> categoryIdList, String endTime, Integer offset, Integer rows)throws Exception {
-        List<DepotItemVo4WithInfoEx> list =null;
-        try{
-            list = depotItemMapperEx.getInOutStock(materialParam, categoryIdList, endTime, offset, rows);
-        }catch(Exception e){
-            JshException.readFail(logger, e);
-        }
-        return list;
-    }
+    List<DepotItemVo4WithInfoEx> getInOutStock(String materialParam, List<Long> categoryIdList, String endTime, Integer offset, Integer rows)throws Exception;
 
-    public int getInOutStockCount(String materialParam, List<Long> categoryIdList, String endTime)throws Exception {
-        int result=0;
-        try{
-            result = depotItemMapperEx.getInOutStockCount(materialParam, categoryIdList, endTime);
-        }catch(Exception e){
-            JshException.readFail(logger, e);
-        }
-        return result;
-    }
+    int getInOutStockCount(String materialParam, List<Long> categoryIdList, String endTime)throws Exception;
 
-    public List<DepotItemVo4WithInfoEx> getListWithBuyOrSale(String materialParam, String billType,
-                                                             String beginTime, String endTime, String[] creatorArray, Long organId, String[] organArray, List<Long> categoryList, List<Long> depotList, Boolean forceFlag, Integer offset, Integer rows)throws Exception {
-        List<DepotItemVo4WithInfoEx> list =null;
-        try{
-            list = depotItemMapperEx.getListWithBuyOrSale(materialParam, billType, beginTime, endTime, creatorArray, organId, organArray, categoryList, depotList, forceFlag, offset, rows);
-        }catch(Exception e){
-            JshException.readFail(logger, e);
-        }
-        return list;
-    }
+    List<DepotItemVo4WithInfoEx> getListWithBuyOrSale(String materialParam, String billType,
+                                                      String beginTime, String endTime, String[] creatorArray, Long organId, String[] organArray, List<Long> categoryList, List<Long> depotList, Boolean forceFlag, Integer offset, Integer rows)throws Exception;
 
-    public int getListWithBuyOrSaleCount(String materialParam, String billType,
-                                         String beginTime, String endTime, String[] creatorArray, Long organId, String[] organArray, List<Long> categoryList, List<Long> depotList, Boolean forceFlag)throws Exception {
-        int result=0;
-        try{
-            result = depotItemMapperEx.getListWithBuyOrSaleCount(materialParam, billType, beginTime, endTime, creatorArray, organId, organArray, categoryList, depotList, forceFlag);
-        }catch(Exception e){
-            JshException.readFail(logger, e);
-        }
-        return result;
-    }
+    int getListWithBuyOrSaleCount(String materialParam, String billType,
+                                  String beginTime, String endTime, String[] creatorArray, Long organId, String[] organArray, List<Long> categoryList, List<Long> depotList, Boolean forceFlag)throws Exception;
 
-    public BigDecimal buyOrSale(String type, String subType, Long MId, String beginTime, String endTime,
-                                String[] creatorArray, Long organId, String [] organArray, List<Long> depotList, Boolean forceFlag, String sumType) throws Exception{
-        BigDecimal result= BigDecimal.ZERO;
-        try{
-            if (SUM_TYPE.equals(sumType)) {
-                result= depotItemMapperEx.buyOrSaleNumber(type, subType, MId, beginTime, endTime, creatorArray, organId, organArray, depotList, forceFlag, sumType);
-            } else {
-                result= depotItemMapperEx.buyOrSalePrice(type, subType, MId, beginTime, endTime, creatorArray, organId, organArray, depotList, forceFlag, sumType);
-            }
-        }catch(Exception e){
-            JshException.readFail(logger, e);
-        }
-        return result;
-    }
+    BigDecimal buyOrSale(String type, String subType, Long MId, String beginTime, String endTime,
+                         String[] creatorArray, Long organId, String[] organArray, List<Long> depotList, Boolean forceFlag, String sumType) throws Exception;
 
-    public BigDecimal buyOrSalePriceTotal(String type, String subType, String materialParam, String beginTime, String endTime,
-                                String[] creatorArray, Long organId, String [] organArray, List<Long> categoryList, List<Long> depotList, Boolean forceFlag) throws Exception{
-        BigDecimal result= BigDecimal.ZERO;
-        try{
-            result= depotItemMapperEx.buyOrSalePriceTotal(type, subType, materialParam, beginTime, endTime, creatorArray, organId, organArray, categoryList, depotList, forceFlag);
-        }catch(Exception e){
-            JshException.readFail(logger, e);
-        }
-        return result;
+    BigDecimal buyOrSalePriceTotal(String type, String subType, String materialParam, String beginTime, String endTime,
+                                   String[] creatorArray, Long organId, String[] organArray, List<Long> categoryList, List<Long> depotList, Boolean forceFlag) throws Exception;
 
-    }
-
-    /**
-     * 统计采购、销售、零售的总金额列表
-     * @param beginTime
-     * @param endTime
-     * @return
-     * @throws Exception
-     */
-    public List<InOutPriceVo> inOrOutPriceList(String beginTime, String endTime) throws Exception{
-        List<InOutPriceVo> result = new ArrayList<>();
-        try{
-            String [] creatorArray = depotHeadService.getCreatorArray();
-            Boolean forceFlag = systemConfigService.getForceApprovalFlag();
-            result = depotItemMapperEx.inOrOutPriceList(beginTime, endTime, creatorArray, forceFlag);
-        }catch(Exception e){
-            JshException.readFail(logger, e);
-        }
-        return result;
-    }
+    List<InOutPriceVo> inOrOutPriceList(String beginTime, String endTime) throws Exception;
 
     @Transactional(value = "transactionManager", rollbackFor = Exception.class)
-    public void saveDetials(String rows, Long headerId, String actionType, HttpServletRequest request) throws Exception{
-        //查询单据主表信息
-        DepotHead depotHead =depotHeadMapper.selectByPrimaryKey(headerId);
-        //删除序列号和回收序列号
-        deleteOrCancelSerialNumber(actionType, depotHead, headerId);
-        //删除单据的明细
-        deleteDepotItemHeadId(headerId);
-        JSONArray rowArr = JSONArray.parseArray(rows);
-        if (null != rowArr && rowArr.size()>0) {
-            //针对组装单、拆卸单校验是否存在组合件和普通子件
-            checkAssembleWithMaterialType(rowArr, depotHead.getSubType());
-            for (int i = 0; i < rowArr.size(); i++) {
-                DepotItem depotItem = new DepotItem();
-                JSONObject rowObj = JSONObject.parseObject(rowArr.getString(i));
-                depotItem.setHeaderId(headerId);
-                String barCode = rowObj.getString("barCode");
-                MaterialExtend materialExtend = materialExtendService.getInfoByBarCode(barCode);
-                if(materialExtend == null) {
-                    throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_BARCODE_IS_NOT_EXIST_CODE,
-                            String.format(ExceptionConstants.MATERIAL_BARCODE_IS_NOT_EXIST_MSG, barCode));
-                }
-                depotItem.setMaterialId(materialExtend.getMaterialId());
-                depotItem.setMaterialExtendId(materialExtend.getId());
-                depotItem.setMaterialUnit(rowObj.getString("unit"));
-                Material material= materialService.getMaterial(depotItem.getMaterialId());
-                if (BusinessConstants.ENABLE_SERIAL_NUMBER_ENABLED.equals(material.getEnableSerialNumber()) ||
-                        BusinessConstants.ENABLE_BATCH_NUMBER_ENABLED.equals(material.getEnableBatchNumber())) {
-                    //组装拆卸单不能选择批号或序列号商品
-                    if(BusinessConstants.SUB_TYPE_ASSEMBLE.equals(depotHead.getSubType()) ||
-                            BusinessConstants.SUB_TYPE_DISASSEMBLE.equals(depotHead.getSubType())) {
-                        throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_ASSEMBLE_SELECT_ERROR_CODE,
-                                String.format(ExceptionConstants.MATERIAL_ASSEMBLE_SELECT_ERROR_MSG, barCode));
-                    }
-                    //调拨单不能选择批号或序列号商品(该场景走出库和入库单)
-                    if(BusinessConstants.SUB_TYPE_TRANSFER.equals(depotHead.getSubType())) {
-                        throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_TRANSFER_SELECT_ERROR_CODE,
-                                String.format(ExceptionConstants.MATERIAL_TRANSFER_SELECT_ERROR_MSG, barCode));
-                    }
-                    //盘点业务不能选择批号或序列号商品(该场景走出库和入库单)
-                    if(BusinessConstants.SUB_TYPE_CHECK_ENTER.equals(depotHead.getSubType())
-                       ||BusinessConstants.SUB_TYPE_REPLAY.equals(depotHead.getSubType())) {
-                        throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_STOCK_CHECK_ERROR_CODE,
-                                String.format(ExceptionConstants.MATERIAL_STOCK_CHECK_ERROR_MSG, barCode));
-                    }
-                }
-                if (StringUtil.isExist(rowObj.get("snList"))) {
-                    depotItem.setSnList(rowObj.getString("snList"));
-                    if(StringUtil.isExist(rowObj.get("depotId"))) {
-                        String [] snArray = depotItem.getSnList().split(",");
-                        int operNum = rowObj.getInteger("operNumber");
-                        if(snArray.length == operNum) {
-                            Long depotId = rowObj.getLong("depotId");
-                            BigDecimal inPrice = BigDecimal.ZERO;
-                            if (StringUtil.isExist(rowObj.get("unitPrice"))) {
-                                inPrice = rowObj.getBigDecimal("unitPrice");
-                            }
-                            serialNumberService.addSerialNumberByBill(depotHead.getType(), depotHead.getSubType(),
-                                    depotHead.getNumber(), materialExtend.getMaterialId(), depotId, inPrice, depotItem.getSnList());
-                        } else {
-                            throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_SN_NUMBERE_FAILED_CODE,
-                                    String.format(ExceptionConstants.DEPOT_HEAD_SN_NUMBERE_FAILED_MSG, barCode));
-                        }
-                    }
-                } else {
-                    //入库或出库
-                    if (BusinessConstants.DEPOTHEAD_TYPE_IN.equals(depotHead.getType()) ||
-                            BusinessConstants.DEPOTHEAD_TYPE_OUT.equals(depotHead.getType())) {
-                        //序列号不能为空
-                        if (BusinessConstants.ENABLE_SERIAL_NUMBER_ENABLED.equals(material.getEnableSerialNumber())) {
-                            //如果开启出入库管理,并且类型等于采购、采购退货、销售、销售退货,则跳过
-                            if(systemConfigService.getInOutManageFlag() &&
-                                    (BusinessConstants.SUB_TYPE_PURCHASE.equals(depotHead.getSubType())
-                                            ||BusinessConstants.SUB_TYPE_PURCHASE_RETURN.equals(depotHead.getSubType())
-                                            ||BusinessConstants.SUB_TYPE_SALES.equals(depotHead.getSubType())
-                                            ||BusinessConstants.SUB_TYPE_SALES_RETURN.equals(depotHead.getSubType()))) {
-                                //跳过
-                            } else {
-                                throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_SERIAL_NUMBERE_EMPTY_CODE,
-                                        String.format(ExceptionConstants.MATERIAL_SERIAL_NUMBERE_EMPTY_MSG, barCode));
-                            }
-                        }
-                    }
-                }
-                if (StringUtil.isExist(rowObj.get("batchNumber"))) {
-                    depotItem.setBatchNumber(rowObj.getString("batchNumber"));
-                } else {
-                    //入库或出库
-                    if(BusinessConstants.DEPOTHEAD_TYPE_IN.equals(depotHead.getType()) ||
-                            BusinessConstants.DEPOTHEAD_TYPE_OUT.equals(depotHead.getType())) {
-                        //批号不能为空
-                        if (BusinessConstants.ENABLE_BATCH_NUMBER_ENABLED.equals(material.getEnableBatchNumber())) {
-                            //如果开启出入库管理,并且类型等于采购、采购退货、销售、销售退货,则跳过
-                            if(systemConfigService.getInOutManageFlag() &&
-                                    (BusinessConstants.SUB_TYPE_PURCHASE.equals(depotHead.getSubType())
-                                            ||BusinessConstants.SUB_TYPE_PURCHASE_RETURN.equals(depotHead.getSubType())
-                                            ||BusinessConstants.SUB_TYPE_SALES.equals(depotHead.getSubType())
-                                            ||BusinessConstants.SUB_TYPE_SALES_RETURN.equals(depotHead.getSubType()))) {
-                                //跳过
-                            } else {
-                                throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_BATCH_NUMBERE_EMPTY_CODE,
-                                        String.format(ExceptionConstants.DEPOT_HEAD_BATCH_NUMBERE_EMPTY_MSG, barCode));
-                            }
-                        }
-                    }
-                }
-                if (StringUtil.isExist(rowObj.get("expirationDate"))) {
-                    depotItem.setExpirationDate(rowObj.getDate("expirationDate"));
-                }
-                if (StringUtil.isExist(rowObj.get("sku"))) {
-                    depotItem.setSku(rowObj.getString("sku"));
-                }
-                if (StringUtil.isExist(rowObj.get("linkId"))) {
-                    depotItem.setLinkId(rowObj.getLong("linkId"));
-                }
-                //以下进行单位换算
-                Unit unitInfo = materialService.findUnit(materialExtend.getMaterialId()); //查询多单位信息
-                if (StringUtil.isExist(rowObj.get("operNumber"))) {
-                    depotItem.setOperNumber(rowObj.getBigDecimal("operNumber"));
-                    String unit = rowObj.get("unit").toString();
-                    BigDecimal oNumber = rowObj.getBigDecimal("operNumber");
-                    if (StringUtil.isNotEmpty(unitInfo.getName())) {
-                        String basicUnit = unitInfo.getBasicUnit(); //基本单位
-                        if (unit.equals(basicUnit)) { //如果等于基本单位
-                            depotItem.setBasicNumber(oNumber); //数量一致
-                        } else if (unit.equals(unitInfo.getOtherUnit())) { //如果等于副单位
-                            depotItem.setBasicNumber(oNumber.multiply(unitInfo.getRatio())); //数量乘以比例
-                        } else if (unit.equals(unitInfo.getOtherUnitTwo())) { //如果等于副单位2
-                            depotItem.setBasicNumber(oNumber.multiply(unitInfo.getRatioTwo())); //数量乘以比例
-                        } else if (unit.equals(unitInfo.getOtherUnitThree())) { //如果等于副单位3
-                            depotItem.setBasicNumber(oNumber.multiply(unitInfo.getRatioThree())); //数量乘以比例
-                        } else {
-                            depotItem.setBasicNumber(oNumber); //数量一致
-                        }
-                    } else {
-                        depotItem.setBasicNumber(oNumber); //其他情况
-                    }
-                }
-                //如果数量+已完成数量>原订单数量,给出预警(判断前提是存在关联订单|关联请购单)
-                String linkStr = StringUtil.isNotEmpty(depotHead.getLinkNumber())? depotHead.getLinkNumber(): depotHead.getLinkApply();
-                if (StringUtil.isNotEmpty(linkStr) && StringUtil.isExist(rowObj.get("preNumber")) && StringUtil.isExist(rowObj.get("finishNumber"))) {
-                    if("add".equals(actionType)) {
-                        //在新增模式进行状态赋值
-                        BigDecimal preNumber = rowObj.getBigDecimal("preNumber");
-                        BigDecimal finishNumber = rowObj.getBigDecimal("finishNumber");
-                        if(depotItem.getOperNumber().add(finishNumber).compareTo(preNumber)>0) {
-                            if(!systemConfigService.getOverLinkBillFlag()) {
-                                throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_NUMBER_NEED_EDIT_FAILED_CODE,
-                                        String.format(ExceptionConstants.DEPOT_HEAD_NUMBER_NEED_EDIT_FAILED_MSG, barCode));
-                            }
-                        }
-                    } else if("update".equals(actionType)) {
-                        //当前单据的类型
-                        String currentSubType = depotHead.getSubType();
-                        //在更新模式进行状态赋值
-                        String unit = rowObj.get("unit").toString();
-                        Long preHeaderId = depotHeadService.getDepotHead(linkStr).getId();
-                        if(null!=preHeaderId) {
-                            //前一个单据的数量
-                            BigDecimal preNumber = getPreItemByHeaderIdAndMaterial(linkStr, depotItem.getMaterialExtendId(), depotItem.getLinkId()).getOperNumber();
-                            //除去此单据之外的已入库|已出库
-                            BigDecimal realFinishNumber = getRealFinishNumber(currentSubType, depotItem.getMaterialExtendId(), depotItem.getLinkId(), preHeaderId, headerId, unitInfo, unit);
-                            if(preNumber!=null) {
-                                if (depotItem.getOperNumber().add(realFinishNumber).compareTo(preNumber) > 0) {
-                                    if (!systemConfigService.getOverLinkBillFlag()) {
-                                        throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_NUMBER_NEED_EDIT_FAILED_CODE,
-                                                String.format(ExceptionConstants.DEPOT_HEAD_NUMBER_NEED_EDIT_FAILED_MSG, barCode));
-                                    }
-                                }
-                            } else {
-                                throw new BusinessRunTimeException(ExceptionConstants.DEPOT_ITEM_PRE_BILL_IS_CHANGE_CODE,
-                                        ExceptionConstants.DEPOT_ITEM_PRE_BILL_IS_CHANGE_MSG);
-                            }
-                        }
-                    }
-                }
-                if (StringUtil.isExist(rowObj.get("unitPrice"))) {
-                    BigDecimal unitPrice = rowObj.getBigDecimal("unitPrice");
-                    depotItem.setUnitPrice(unitPrice);
-                    if(materialExtend.getLowDecimal()!=null) {
-                        //零售或销售单价低于最低售价,进行提示
-                        if("零售".equals(depotHead.getSubType()) || "销售".equals(depotHead.getSubType())) {
-                            if (unitPrice.compareTo(materialExtend.getLowDecimal()) < 0) {
-                                throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_UNIT_PRICE_LOW_CODE,
-                                        String.format(ExceptionConstants.DEPOT_HEAD_UNIT_PRICE_LOW_MSG, barCode));
-                            }
-                        }
-                    }
-                }
-                //如果是销售出库、销售退货、零售出库、零售退货则给采购单价字段赋值(如果是批次商品,则要根据批号去找之前的入库价)
-                if(BusinessConstants.SUB_TYPE_SALES.equals(depotHead.getSubType()) ||
-                    BusinessConstants.SUB_TYPE_SALES_RETURN.equals(depotHead.getSubType()) ||
-                    BusinessConstants.SUB_TYPE_RETAIL.equals(depotHead.getSubType()) ||
-                    BusinessConstants.SUB_TYPE_RETAIL_RETURN.equals(depotHead.getSubType())) {
-                    boolean moveAvgPriceFlag = systemConfigService.getMoveAvgPriceFlag();
-                    BigDecimal currentUnitPrice = materialCurrentStockMapperEx.getCurrentUnitPriceByMId(materialExtend.getMaterialId());
-                    currentUnitPrice = unitService.parseUnitPriceByUnit(currentUnitPrice, unitInfo, depotItem.getMaterialUnit());
-                    BigDecimal unitPrice = moveAvgPriceFlag? currentUnitPrice: materialExtend.getPurchaseDecimal();
-                    depotItem.setPurchaseUnitPrice(unitPrice);
-                    if(StringUtil.isNotEmpty(depotItem.getBatchNumber())) {
-                        depotItem.setPurchaseUnitPrice(getDepotItemByBatchNumber(depotItem.getMaterialExtendId(),depotItem.getBatchNumber()).getUnitPrice());
-                    }
-                }
-                if (StringUtil.isExist(rowObj.get("taxUnitPrice"))) {
-                    depotItem.setTaxUnitPrice(rowObj.getBigDecimal("taxUnitPrice"));
-                }
-                if (StringUtil.isExist(rowObj.get("allPrice"))) {
-                    depotItem.setAllPrice(rowObj.getBigDecimal("allPrice"));
-                }
-                if (StringUtil.isExist(rowObj.get("depotId"))) {
-                    depotItem.setDepotId(rowObj.getLong("depotId"));
-                } else {
-                    if(!BusinessConstants.SUB_TYPE_PURCHASE_APPLY.equals(depotHead.getSubType())
-                            && !BusinessConstants.SUB_TYPE_PURCHASE_ORDER.equals(depotHead.getSubType())
-                            && !BusinessConstants.SUB_TYPE_SALES_ORDER.equals(depotHead.getSubType())) {
-                        throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_DEPOT_FAILED_CODE,
-                                String.format(ExceptionConstants.DEPOT_HEAD_DEPOT_FAILED_MSG));
-                    }
-                }
-                if(BusinessConstants.SUB_TYPE_TRANSFER.equals(depotHead.getSubType())) {
-                    if (StringUtil.isExist(rowObj.get("anotherDepotId"))) {
-                        if(rowObj.getLong("anotherDepotId").equals(rowObj.getLong("depotId"))) {
-                            throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_ANOTHER_DEPOT_EQUAL_FAILED_CODE,
-                                    String.format(ExceptionConstants.DEPOT_HEAD_ANOTHER_DEPOT_EQUAL_FAILED_MSG));
-                        } else {
-                            depotItem.setAnotherDepotId(rowObj.getLong("anotherDepotId"));
-                        }
-                    } else {
-                        throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_ANOTHER_DEPOT_FAILED_CODE,
-                                String.format(ExceptionConstants.DEPOT_HEAD_ANOTHER_DEPOT_FAILED_MSG));
-                    }
-                }
-                if (StringUtil.isExist(rowObj.get("taxRate"))) {
-                    depotItem.setTaxRate(rowObj.getBigDecimal("taxRate"));
-                }
-                if (StringUtil.isExist(rowObj.get("taxMoney"))) {
-                    depotItem.setTaxMoney(rowObj.getBigDecimal("taxMoney"));
-                }
-                if (StringUtil.isExist(rowObj.get("taxLastMoney"))) {
-                    depotItem.setTaxLastMoney(rowObj.getBigDecimal("taxLastMoney"));
-                }
-                if (StringUtil.isExist(rowObj.get("mType"))) {
-                    depotItem.setMaterialType(rowObj.getString("mType"));
-                }
-                if (StringUtil.isExist(rowObj.get("remark"))) {
-                    depotItem.setRemark(rowObj.getString("remark"));
-                }
-                //出库时判断库存是否充足
-                if(BusinessConstants.DEPOTHEAD_TYPE_OUT.equals(depotHead.getType())){
-                    String stockMsg = material.getName() + "-" + barCode;
-                    BigDecimal stock = getCurrentStockByParam(depotItem.getDepotId(),depotItem.getMaterialId());
-                    if(StringUtil.isNotEmpty(depotItem.getSku())) {
-                        //对于sku商品要换个方式计算库存
-                        stock = getSkuStockByParam(depotItem.getDepotId(),depotItem.getMaterialExtendId(),null,null);
-                    }
-                    if(StringUtil.isNotEmpty(depotItem.getBatchNumber())) {
-                        //对于批次商品要换个方式计算库存
-                        stock = getOneBatchNumberStock(depotItem.getDepotId(), barCode, depotItem.getBatchNumber());
-                        stockMsg += "-批号" + depotItem.getBatchNumber();
-                    }
-                    BigDecimal thisRealNumber = depotItem.getBasicNumber()==null?BigDecimal.ZERO:depotItem.getBasicNumber();
-                    if(StringUtil.isNotEmpty(depotItem.getBatchNumber())) {
-                        //对于批次商品,直接使用当前填写的数量
-                        thisRealNumber = depotItem.getOperNumber()==null?BigDecimal.ZERO:depotItem.getOperNumber();
-                    }
-                    if(!systemConfigService.getMinusStockFlag() && stock.compareTo(thisRealNumber)<0){
-                        throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_STOCK_NOT_ENOUGH_CODE,
-                                String.format(ExceptionConstants.MATERIAL_STOCK_NOT_ENOUGH_MSG, stockMsg));
-                    }
-                    //出库时处理序列号
-                    if(!BusinessConstants.SUB_TYPE_TRANSFER.equals(depotHead.getSubType())) {
-                        //判断商品是否开启序列号,开启的售出序列号,未开启的跳过
-                        if(BusinessConstants.ENABLE_SERIAL_NUMBER_ENABLED.equals(material.getEnableSerialNumber())) {
-                            //如果开启出入库管理,并且类型等于采购、采购退货、销售、销售退货,则跳过
-                            if(systemConfigService.getInOutManageFlag() &&
-                                    (BusinessConstants.SUB_TYPE_PURCHASE.equals(depotHead.getSubType())
-                                            ||BusinessConstants.SUB_TYPE_PURCHASE_RETURN.equals(depotHead.getSubType())
-                                            ||BusinessConstants.SUB_TYPE_SALES.equals(depotHead.getSubType())
-                                            ||BusinessConstants.SUB_TYPE_SALES_RETURN.equals(depotHead.getSubType()))) {
-                                //跳过
-                            } else {
-                                //售出序列号,获得当前操作人
-                                User userInfo = userService.getCurrentUser();
-                                serialNumberService.checkAndUpdateSerialNumber(depotItem, depotHead.getNumber(), userInfo, StringUtil.toNull(depotItem.getSnList()));
-                            }
-                        }
-                    }
-                }
-                this.insertDepotItemWithObj(depotItem);
-                //更新当前库存
-                updateCurrentStock(depotItem);
-                //更新当前成本价
-                updateCurrentUnitPrice(depotItem);
-                //更新商品的价格
-                updateMaterialExtendPrice(materialExtend.getId(), depotHead.getSubType(), depotHead.getBillType(), rowObj);
-            }
-            //如果关联单据号非空则更新订单的状态,单据类型:采购入库单、销售出库单、盘点复盘单、其它入库单、其它出库单
-            if(BusinessConstants.SUB_TYPE_PURCHASE.equals(depotHead.getSubType())
-                    || BusinessConstants.SUB_TYPE_SALES.equals(depotHead.getSubType())
-                    || BusinessConstants.SUB_TYPE_REPLAY.equals(depotHead.getSubType())
-                    || BusinessConstants.SUB_TYPE_OTHER.equals(depotHead.getSubType())) {
-                if(StringUtil.isNotEmpty(depotHead.getLinkNumber())) {
-                    //单据状态:是否全部完成 2-全部完成 3-部分完成(针对订单的分批出入库)
-                    String billStatus = getBillStatusByParam(depotHead, depotHead.getLinkNumber(), "normal");
-                    changeBillStatus(depotHead.getLinkNumber(), billStatus);
-                }
-            }
-            //当前单据类型为采购订单的逻辑
-            if(BusinessConstants.SUB_TYPE_PURCHASE_ORDER.equals(depotHead.getSubType())) {
-                //如果关联单据号非空则更新订单的状态,此处针对销售订单转采购订单的场景
-                if(StringUtil.isNotEmpty(depotHead.getLinkNumber())) {
-                    String billStatus = getBillStatusByParam(depotHead, depotHead.getLinkNumber(), "normal");
-                    changeBillPurchaseStatus(depotHead.getLinkNumber(), billStatus);
-                }
-                //如果关联单据号非空则更新订单的状态,此处针对请购单转采购订单的场景
-                if(StringUtil.isNotEmpty(depotHead.getLinkApply())) {
-                    String billStatus = getBillStatusByParam(depotHead, depotHead.getLinkApply(), "apply");
-                    changeBillStatus(depotHead.getLinkApply(), billStatus);
-                }
-            }
-        } else {
-            throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_ROW_FAILED_CODE,
-                    String.format(ExceptionConstants.DEPOT_HEAD_ROW_FAILED_MSG));
-        }
-    }
-    /**
-     * 判断单据的状态
-     * 通过数组对比:原单据的商品和商品数量(汇总) 与 分批操作后单据的商品和商品数量(汇总)
-     * @param depotHead
-     * @param linkStr
-     * @return
-     */
+    void saveDetials(String rows, Long headerId, String actionType, HttpServletRequest request) throws Exception;
+
     @Transactional(value = "transactionManager", rollbackFor = Exception.class)
-    public String getBillStatusByParam(DepotHead depotHead, String linkStr, String linkType) {
-        String res = BusinessConstants.BILLS_STATUS_SKIPED;
-        //获取原单据的商品和商品数量(汇总)
-        List<DepotItemVo4MaterialAndSum> linkList = depotItemMapperEx.getLinkBillDetailMaterialSum(linkStr);
-        //获取分批操作后单据的商品和商品数量(汇总)
-        List<DepotItemVo4MaterialAndSum> batchList = depotItemMapperEx.getBatchBillDetailMaterialSum(linkStr, linkType, depotHead.getType());
-        //将分批操作后的单据的商品和商品数据构造成Map
-        Map<Long, BigDecimal> materialSumMap = new HashMap<>();
-        for(DepotItemVo4MaterialAndSum materialAndSum : batchList) {
-            materialSumMap.put(materialAndSum.getMaterialExtendId(), materialAndSum.getOperNumber());
-        }
-        for(DepotItemVo4MaterialAndSum materialAndSum : linkList) {
-            //过滤掉原单里面有数量为0的商品
-            if(materialAndSum.getOperNumber().compareTo(BigDecimal.ZERO) != 0) {
-                BigDecimal materialSum = materialSumMap.get(materialAndSum.getMaterialExtendId());
-                if (materialSum != null) {
-                    if (materialSum.compareTo(materialAndSum.getOperNumber()) < 0) {
-                        res = BusinessConstants.BILLS_STATUS_SKIPING;
-                    }
-                } else {
-                    res = BusinessConstants.BILLS_STATUS_SKIPING;
-                }
-            }
-        }
-        return res;
-    }
+    String getBillStatusByParam(DepotHead depotHead, String linkStr, String linkType);
 
-    /**
-     * 更新单据状态
-     * @param linkStr
-     * @param billStatus
-     */
     @Transactional(value = "transactionManager", rollbackFor = Exception.class)
-    public void changeBillStatus(String linkStr, String billStatus) {
-        DepotHead depotHeadOrders = new DepotHead();
-        depotHeadOrders.setStatus(billStatus);
-        DepotHeadExample example = new DepotHeadExample();
-        List<String> linkNoList = StringUtil.strToStringList(linkStr);
-        example.createCriteria().andNumberIn(linkNoList);
-        try{
-            depotHeadMapper.updateByExampleSelective(depotHeadOrders, example);
-        }catch(Exception e){
-            logger.error("异常码[{}],异常提示[{}],异常[{}]",
-                    ExceptionConstants.DATA_WRITE_FAIL_CODE,ExceptionConstants.DATA_WRITE_FAIL_MSG,e);
-            throw new BusinessRunTimeException(ExceptionConstants.DATA_WRITE_FAIL_CODE,
-                    ExceptionConstants.DATA_WRITE_FAIL_MSG);
-        }
-    }
+    void changeBillStatus(String linkStr, String billStatus);
 
-    /**
-     * 更新单据状态,此处针对销售订单转采购订单的场景
-     * @param linkStr
-     * @param billStatus
-     */
     @Transactional(value = "transactionManager", rollbackFor = Exception.class)
-    public void changeBillPurchaseStatus(String linkStr, String billStatus) {
-        DepotHead depotHeadOrders = new DepotHead();
-        depotHeadOrders.setPurchaseStatus(billStatus);
-        DepotHeadExample example = new DepotHeadExample();
-        List<String> linkNoList = StringUtil.strToStringList(linkStr);
-        example.createCriteria().andNumberIn(linkNoList);
-        try{
-            depotHeadMapper.updateByExampleSelective(depotHeadOrders, example);
-        }catch(Exception e){
-            logger.error("异常码[{}],异常提示[{}],异常[{}]",
-                    ExceptionConstants.DATA_WRITE_FAIL_CODE,ExceptionConstants.DATA_WRITE_FAIL_MSG,e);
-            throw new BusinessRunTimeException(ExceptionConstants.DATA_WRITE_FAIL_CODE,
-                    ExceptionConstants.DATA_WRITE_FAIL_MSG);
-        }
-    }
+    void changeBillPurchaseStatus(String linkStr, String billStatus);
 
-    /**
-     * 根据批号查询单据明细信息
-     * @param materialExtendId
-     * @param batchNumber
-     * @return
-     */
-    public DepotItem getDepotItemByBatchNumber(Long materialExtendId, String batchNumber) {
-        List<DepotItem> depotItemList = depotItemMapperEx.getDepotItemByBatchNumber(materialExtendId, batchNumber);
-        if(null != depotItemList && depotItemList.size() > 0){
-            return depotItemList.get(0);
-        } else {
-            return new DepotItem();
-        }
-    }
+    DepotItem getDepotItemByBatchNumber(Long materialExtendId, String batchNumber);
 
     @Transactional(value = "transactionManager", rollbackFor = Exception.class)
-    public void deleteDepotItemHeadId(Long headerId)throws Exception {
-        try{
-            //1、查询删除前的单据明细
-            List<DepotItem> depotItemList = getListByHeaderId(headerId);
-            //2、删除单据明细
-            DepotItemExample example = new DepotItemExample();
-            example.createCriteria().andHeaderIdEqualTo(headerId);
-            depotItemMapper.deleteByExample(example);
-            //3、计算删除之后单据明细中商品的库存
-            for(DepotItem depotItem : depotItemList){
-                updateCurrentStock(depotItem);
-            }
-        }catch(Exception e){
-            JshException.writeFail(logger, e);
-        }
-    }
+    void deleteDepotItemHeadId(Long headerId)throws Exception;
 
-    /**
-     * 删除序列号和回收序列号
-     * @param actionType
-     * @throws Exception
-     */
     @Transactional(value = "transactionManager", rollbackFor = Exception.class)
-    public void deleteOrCancelSerialNumber(String actionType, DepotHead depotHead, Long headerId) throws Exception {
-        if(actionType.equals("update")) {
-            User userInfo = userService.getCurrentUser();
-            if(BusinessConstants.DEPOTHEAD_TYPE_IN.equals(depotHead.getType())){
-                //入库逻辑
-                String number = depotHead.getNumber();
-                SerialNumberExample example = new SerialNumberExample();
-                example.createCriteria().andInBillNoEqualTo(number);
-                serialNumberService.deleteByExample(example);
-            } else if(BusinessConstants.DEPOTHEAD_TYPE_OUT.equals(depotHead.getType())){
-                //出库逻辑
-                DepotItemExample example = new DepotItemExample();
-                example.createCriteria().andHeaderIdEqualTo(headerId).andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
-                List<DepotItem> depotItemList = depotItemMapper.selectByExample(example);
-                if(null != depotItemList && depotItemList.size() > 0){
-                    for (DepotItem depotItem : depotItemList){
-                        if(StringUtil.isNotEmpty(depotItem.getSnList())){
-                            serialNumberService.cancelSerialNumber(depotItem.getMaterialId(), depotHead.getNumber(), (depotItem.getBasicNumber() == null ? 0 : depotItem.getBasicNumber()).intValue(), userInfo);
-                        }
-                    }
-                }
-            }
-        }
-    }
+    void deleteOrCancelSerialNumber(String actionType, DepotHead depotHead, Long headerId) throws Exception;
 
-    /**
-     * 针对组装单、拆卸单校验是否存在组合件和普通子件
-     * @param rowArr
-     * @param subType
-     */
-    public void checkAssembleWithMaterialType(JSONArray rowArr, String subType) {
-        if(BusinessConstants.SUB_TYPE_ASSEMBLE.equals(subType) ||
-                BusinessConstants.SUB_TYPE_DISASSEMBLE.equals(subType)) {
-            if(rowArr.size() > 1) {
-                JSONObject firstRowObj = JSONObject.parseObject(rowArr.getString(0));
-                JSONObject secondRowObj = JSONObject.parseObject(rowArr.getString(1));
-                String firstMaterialType = firstRowObj.getString("mType");
-                String secondMaterialType = secondRowObj.getString("mType");
-                if(!"组合件".equals(firstMaterialType) || !"普通子件".equals(secondMaterialType)) {
-                    throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_CHECK_ASSEMBLE_EMPTY_CODE,
-                            String.format(ExceptionConstants.DEPOT_HEAD_CHECK_ASSEMBLE_EMPTY_MSG));
-                }
-            } else {
-                throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_CHECK_ASSEMBLE_EMPTY_CODE,
-                        String.format(ExceptionConstants.DEPOT_HEAD_CHECK_ASSEMBLE_EMPTY_MSG));
-            }
-        }
-    }
+    void checkAssembleWithMaterialType(JSONArray rowArr, String subType);
 
-    /**
-     * 更新商品的价格
-     * @param meId
-     * @param subType
-     * @param rowObj
-     */
     @Transactional(value = "transactionManager", rollbackFor = Exception.class)
-    public void updateMaterialExtendPrice(Long meId, String subType, String billType, JSONObject rowObj) throws Exception {
-        if(systemConfigService.getUpdateUnitPriceFlag()) {
-            if (StringUtil.isExist(rowObj.get("unitPrice"))) {
-                BigDecimal unitPrice = rowObj.getBigDecimal("unitPrice");
-                MaterialExtend materialExtend = new MaterialExtend();
-                materialExtend.setId(meId);
-                if(BusinessConstants.SUB_TYPE_PURCHASE.equals(subType)) {
-                    materialExtend.setPurchaseDecimal(unitPrice);
-                }
-                if(BusinessConstants.SUB_TYPE_SALES.equals(subType)) {
-                    materialExtend.setWholesaleDecimal(unitPrice);
-                }
-                if(BusinessConstants.SUB_TYPE_RETAIL.equals(subType)) {
-                    materialExtend.setCommodityDecimal(unitPrice);
-                }
-                //其它入库-生产入库的情况更新采购单价
-                if(BusinessConstants.SUB_TYPE_OTHER.equals(subType)) {
-                    if(BusinessConstants.BILL_TYPE_PRODUCE_IN.equals(billType)) {
-                        materialExtend.setPurchaseDecimal(unitPrice);
-                    }
-                }
-                materialExtendService.updateMaterialExtend(materialExtend);
-            }
-        }
-    }
+    void updateMaterialExtendPrice(Long meId, String subType, String billType, JSONObject rowObj) throws Exception;
 
     @Transactional(value = "transactionManager", rollbackFor = Exception.class)
-    public List<DepotItemStockWarningCount> findStockWarningCount(Integer offset, Integer rows, String materialParam, List<Long> depotList, List<Long> categoryList) {
-        List<DepotItemStockWarningCount> list = null;
-        try{
-            list =depotItemMapperEx.findStockWarningCount(offset, rows, materialParam, depotList, categoryList);
-        }catch(Exception e){
-            JshException.readFail(logger, e);
-        }
-        return list;
-    }
+    List<DepotItemStockWarningCount> findStockWarningCount(Integer offset, Integer rows, String materialParam, List<Long> depotList, List<Long> categoryList);
 
     @Transactional(value = "transactionManager", rollbackFor = Exception.class)
-    public int findStockWarningCountTotal(String materialParam, List<Long> depotList, List<Long> categoryList) {
-        int result = 0;
-        try{
-            result =depotItemMapperEx.findStockWarningCountTotal(materialParam, depotList, categoryList);
-        }catch(Exception e){
-            JshException.readFail(logger, e);
-        }
-        return result;
-    }
+    int findStockWarningCountTotal(String materialParam, List<Long> depotList, List<Long> categoryList);
 
-    /**
-     * 库存统计-sku
-     * @param depotId
-     * @param meId
-     * @param beginTime
-     * @param endTime
-     * @return
-     */
-    public BigDecimal getSkuStockByParam(Long depotId, Long meId, String beginTime, String endTime) throws Exception {
-        Boolean forceFlag = systemConfigService.getForceApprovalFlag();
-        Boolean inOutManageFlag = systemConfigService.getInOutManageFlag();
-        List<Long> depotList = depotService.parseDepotList(depotId);
-        //盘点复盘后数量的变动
-        BigDecimal stockCheckSum = depotItemMapperEx.getSkuStockCheckSumByDepotList(depotList, meId, forceFlag, beginTime, endTime);
-        DepotItemVo4Stock stockObj = depotItemMapperEx.getSkuStockByParamWithDepotList(depotList, meId, forceFlag, inOutManageFlag, beginTime, endTime);
-        BigDecimal stockSum = BigDecimal.ZERO;
-        if(stockObj!=null) {
-            BigDecimal inTotal = stockObj.getInTotal();
-            BigDecimal transfInTotal = stockObj.getTransfInTotal();
-            BigDecimal assemInTotal = stockObj.getAssemInTotal();
-            BigDecimal disAssemInTotal = stockObj.getDisAssemInTotal();
-            BigDecimal outTotal = stockObj.getOutTotal();
-            BigDecimal transfOutTotal = stockObj.getTransfOutTotal();
-            BigDecimal assemOutTotal = stockObj.getAssemOutTotal();
-            BigDecimal disAssemOutTotal = stockObj.getDisAssemOutTotal();
-            stockSum = inTotal.add(transfInTotal).add(assemInTotal).add(disAssemInTotal)
-                    .subtract(outTotal).subtract(transfOutTotal).subtract(assemOutTotal).subtract(disAssemOutTotal);
-        }
-        return stockCheckSum.add(stockSum);
-    }
+    BigDecimal getSkuStockByParam(Long depotId, Long meId, String beginTime, String endTime) throws Exception;
 
-    /**
-     * 库存统计-单仓库
-     * @param depotId
-     * @param mId
-     * @param beginTime
-     * @param endTime
-     * @return
-     */
-    public BigDecimal getStockByParam(Long depotId, Long mId, String beginTime, String endTime) throws Exception {
-        List<Long> depotList = depotService.parseDepotList(depotId);
-        return getStockByParamWithDepotList(depotList, mId, beginTime, endTime);
-    }
+    BigDecimal getStockByParam(Long depotId, Long mId, String beginTime, String endTime) throws Exception;
 
-    /**
-     * 库存统计-多仓库
-     * @param depotList
-     * @param mId
-     * @param beginTime
-     * @param endTime
-     * @return
-     */
-    public BigDecimal getStockByParamWithDepotList(List<Long> depotList, Long mId, String beginTime, String endTime) throws Exception {
-        Boolean forceFlag = systemConfigService.getForceApprovalFlag();
-        Boolean inOutManageFlag = systemConfigService.getInOutManageFlag();
-        //初始库存
-        BigDecimal initStock = materialService.getInitStockByMidAndDepotList(depotList, mId);
-        //盘点复盘后数量的变动
-        BigDecimal stockCheckSum = depotItemMapperEx.getStockCheckSumByDepotList(depotList, mId, forceFlag, beginTime, endTime);
-        DepotItemVo4Stock stockObj = depotItemMapperEx.getStockByParamWithDepotList(depotList, mId, forceFlag, inOutManageFlag, beginTime, endTime);
-        BigDecimal stockSum = BigDecimal.ZERO;
-        if(stockObj!=null) {
-            BigDecimal inTotal = stockObj.getInTotal();
-            BigDecimal transfInTotal = stockObj.getTransfInTotal();
-            BigDecimal assemInTotal = stockObj.getAssemInTotal();
-            BigDecimal disAssemInTotal = stockObj.getDisAssemInTotal();
-            BigDecimal outTotal = stockObj.getOutTotal();
-            BigDecimal transfOutTotal = stockObj.getTransfOutTotal();
-            BigDecimal assemOutTotal = stockObj.getAssemOutTotal();
-            BigDecimal disAssemOutTotal = stockObj.getDisAssemOutTotal();
-            stockSum = inTotal.add(transfInTotal).add(assemInTotal).add(disAssemInTotal)
-                    .subtract(outTotal).subtract(transfOutTotal).subtract(assemOutTotal).subtract(disAssemOutTotal);
-        }
-        return initStock.add(stockCheckSum).add(stockSum);
-    }
+    BigDecimal getStockByParamWithDepotList(List<Long> depotList, Long mId, String beginTime, String endTime) throws Exception;
 
-    /**
-     * 统计时间段内的入库和出库数量-多仓库
-     * @param depotList
-     * @param mId
-     * @param beginTime
-     * @param endTime
-     * @return
-     */
-    public Map<String, BigDecimal> getIntervalMapByParamWithDepotList(List<Long> depotList, Long mId, String beginTime, String endTime) throws Exception {
-        Boolean forceFlag = systemConfigService.getForceApprovalFlag();
-        Boolean inOutManageFlag = systemConfigService.getInOutManageFlag();
-        Map<String,BigDecimal> intervalMap = new HashMap<>();
-        BigDecimal inSum = BigDecimal.ZERO;
-        BigDecimal outSum = BigDecimal.ZERO;
-        //盘点复盘后数量的变动
-        BigDecimal stockCheckSum = depotItemMapperEx.getStockCheckSumByDepotList(depotList, mId, forceFlag, beginTime, endTime);
-        DepotItemVo4Stock stockObj = depotItemMapperEx.getStockByParamWithDepotList(depotList, mId, forceFlag, inOutManageFlag, beginTime, endTime);
-        if(stockObj!=null) {
-            BigDecimal inTotal = stockObj.getInTotal();
-            BigDecimal transfInTotal = stockObj.getTransfInTotal();
-            BigDecimal assemInTotal = stockObj.getAssemInTotal();
-            BigDecimal disAssemInTotal = stockObj.getDisAssemInTotal();
-            inSum = inTotal.add(transfInTotal).add(assemInTotal).add(disAssemInTotal);
-            BigDecimal outTotal = stockObj.getOutTotal();
-            BigDecimal transfOutTotal = stockObj.getTransfOutTotal();
-            BigDecimal assemOutTotal = stockObj.getAssemOutTotal();
-            BigDecimal disAssemOutTotal = stockObj.getDisAssemOutTotal();
-            outSum = outTotal.add(transfOutTotal).add(assemOutTotal).add(disAssemOutTotal);
-        }
-        if(stockCheckSum.compareTo(BigDecimal.ZERO)>0) {
-            inSum = inSum.add(stockCheckSum);
-        } else {
-            //盘点复盘数量为负数代表出库
-            outSum = outSum.subtract(stockCheckSum);
-        }
-        intervalMap.put("inSum", inSum);
-        intervalMap.put("outSum", outSum);
-        return intervalMap;
-    }
+    Map<String, BigDecimal> getIntervalMapByParamWithDepotList(List<Long> depotList, Long mId, String beginTime, String endTime) throws Exception;
 
-    /**
-     * 根据单据明细来批量更新当前库存
-     * @param depotItem
-     */
     @Transactional(value = "transactionManager", rollbackFor = Exception.class)
-    public void updateCurrentStock(DepotItem depotItem) throws Exception {
-        updateCurrentStockFun(depotItem.getMaterialId(), depotItem.getDepotId());
-        if(depotItem.getAnotherDepotId()!=null){
-            updateCurrentStockFun(depotItem.getMaterialId(), depotItem.getAnotherDepotId());
-        }
-    }
+    void updateCurrentStock(DepotItem depotItem) throws Exception;
 
-    /**
-     * 根据单据明细来批量更新当前成本价
-     * @param depotItem
-     */
     @Transactional(value = "transactionManager", rollbackFor = Exception.class)
-    public void updateCurrentUnitPrice(DepotItem depotItem) throws Exception {
-        Boolean forceFlag = systemConfigService.getForceApprovalFlag();
-        Boolean inOutManageFlag = systemConfigService.getInOutManageFlag();
-        //查询多单位信息
-        Unit unitInfo = materialService.findUnit(depotItem.getMaterialId());
-        List<DepotItemVo4DetailByTypeAndMId> itemList = findDetailByDepotIdsAndMaterialIdList(null, forceFlag, inOutManageFlag, depotItem.getSku(),
-                depotItem.getBatchNumber(), null, null, null, depotItem.getMaterialId(), null, null);
-        Collections.reverse(itemList); //倒序之后变成按时间从前往后排序
-        BigDecimal currentNumber = BigDecimal.ZERO;
-        BigDecimal currentUnitPrice = BigDecimal.ZERO;
-        BigDecimal currentAllPrice = BigDecimal.ZERO;
-        for(DepotItemVo4DetailByTypeAndMId item: itemList) {
-            BigDecimal basicNumber = item.getBnum()!=null?item.getBnum():BigDecimal.ZERO;
-            //数量*单价  另外计算新的成本价
-            BigDecimal allPrice = unitService.parseAllPriceByUnit(item.getAllPrice()!=null?item.getAllPrice():BigDecimal.ZERO, unitInfo, item.getMaterialUnit());
-            if(basicNumber.compareTo(BigDecimal.ZERO)!=0 && allPrice.compareTo(BigDecimal.ZERO)!=0) {
-                //入库
-                if (BusinessConstants.DEPOTHEAD_TYPE_IN.equals(item.getType())) {
-                    //零售退货、销售退货
-                    if (BusinessConstants.SUB_TYPE_RETAIL_RETURN.equals(item.getSubType()) || BusinessConstants.SUB_TYPE_SALES_RETURN.equals(item.getSubType())) {
-                        //数量*当前的成本单价
-                        currentNumber = currentNumber.add(basicNumber);
-                        currentAllPrice = currentAllPrice.add(basicNumber.multiply(currentUnitPrice));
-                    } else {
-                        currentAllPrice = currentAllPrice.add(allPrice);
-                        currentNumber = currentNumber.add(basicNumber);
-                        //只有当前库存总金额和当前库存数量都大于0才计算移动平均价
-                        if (currentAllPrice.compareTo(BigDecimal.ZERO) > 0 && currentNumber.compareTo(BigDecimal.ZERO) > 0) {
-                            currentUnitPrice = currentAllPrice.divide(currentNumber, 2, BigDecimal.ROUND_HALF_UP);
-                        } else {
-                            currentUnitPrice = item.getUnitPrice();
-                        }
-                    }
-                }
-                //出库
-                if (BusinessConstants.DEPOTHEAD_TYPE_OUT.equals(item.getType())) {
-                    //采购退货
-                    if (BusinessConstants.SUB_TYPE_PURCHASE_RETURN.equals(item.getSubType())) {
-                        currentAllPrice = currentAllPrice.add(allPrice);
-                        currentNumber = currentNumber.add(basicNumber);
-                        //只有当前库存总金额和当前库存数量都大于0才计算移动平均价
-                        if (currentAllPrice.compareTo(BigDecimal.ZERO) > 0 && currentNumber.compareTo(BigDecimal.ZERO) > 0) {
-                            currentUnitPrice = currentAllPrice.divide(currentNumber, 2, BigDecimal.ROUND_HALF_UP);
-                        } else {
-                            currentUnitPrice = item.getUnitPrice();
-                        }
-                    } else {
-                        currentNumber = currentNumber.add(basicNumber);
-                        //数量*当前的成本单价
-                        currentAllPrice = currentAllPrice.add(basicNumber.multiply(currentUnitPrice));
-                    }
-                }
-                //防止单价金额溢出
-                if(currentUnitPrice.compareTo(BigDecimal.valueOf(100000000))>0 || currentUnitPrice.compareTo(BigDecimal.valueOf(-100000000))<0) {
-                    currentUnitPrice = BigDecimal.ZERO;
-                }
-            }
-        }
-        //更新实时库存中的当前单价
-        materialCurrentStockMapperEx.updateUnitPriceByMId(currentUnitPrice, depotItem.getMaterialId());
-    }
+    void updateCurrentUnitPrice(DepotItem depotItem) throws Exception;
 
-    /**
-     * 根据商品和仓库来更新当前库存
-     * @param mId
-     * @param dId
-     */
-    public void updateCurrentStockFun(Long mId, Long dId) throws Exception {
-        if(mId!=null && dId!=null) {
-            MaterialCurrentStockExample example = new MaterialCurrentStockExample();
-            example.createCriteria().andMaterialIdEqualTo(mId).andDepotIdEqualTo(dId)
-                    .andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
-            List<MaterialCurrentStock> list = materialCurrentStockMapper.selectByExample(example);
-            MaterialCurrentStock materialCurrentStock = new MaterialCurrentStock();
-            materialCurrentStock.setMaterialId(mId);
-            materialCurrentStock.setDepotId(dId);
-            materialCurrentStock.setCurrentNumber(getStockByParam(dId,mId,null,null));
-            if(list!=null && list.size()>0) {
-                Long mcsId = list.get(0).getId();
-                materialCurrentStock.setId(mcsId);
-                materialCurrentStockMapper.updateByPrimaryKeySelective(materialCurrentStock);
-            } else {
-                materialCurrentStockMapper.insertSelective(materialCurrentStock);
-            }
-        }
-    }
+    void updateCurrentStockFun(Long mId, Long dId) throws Exception;
 
     @Transactional(value = "transactionManager", rollbackFor = Exception.class)
-    public BigDecimal getFinishNumber(Long meId, Long id, Long headerId, Unit unitInfo, String materialUnit, String linkType) {
-        Long linkId = id;
-        String goToType = "";
-        DepotHead depotHead =depotHeadMapper.selectByPrimaryKey(headerId);
-        String linkStr = depotHead.getNumber(); //订单号
-        if("purchase".equals(linkType)) {
-            //针对以销定购的情况
-            if(BusinessConstants.SUB_TYPE_SALES_ORDER.equals(depotHead.getSubType())) {
-                goToType = BusinessConstants.SUB_TYPE_PURCHASE_ORDER;
-            }
-        } else if("other".equals(linkType)) {
-            //采购入库、采购退货、销售出库、销售退货都转其它入库
-            if(BusinessConstants.SUB_TYPE_PURCHASE.equals(depotHead.getSubType())
-                    || BusinessConstants.SUB_TYPE_PURCHASE_RETURN.equals(depotHead.getSubType())
-                    || BusinessConstants.SUB_TYPE_SALES.equals(depotHead.getSubType())
-                    || BusinessConstants.SUB_TYPE_SALES_RETURN.equals(depotHead.getSubType())) {
-                goToType = BusinessConstants.SUB_TYPE_OTHER;
-            }
-        } else if("basic".equals(linkType)) {
-            //采购订单转采购入库
-            if(BusinessConstants.SUB_TYPE_PURCHASE_ORDER.equals(depotHead.getSubType())) {
-                goToType = BusinessConstants.SUB_TYPE_PURCHASE;
-            }
-            //销售订单转销售出库
-            if(BusinessConstants.SUB_TYPE_SALES_ORDER.equals(depotHead.getSubType())) {
-                goToType = BusinessConstants.SUB_TYPE_SALES;
-            }
-            //采购入库转采购退货
-            if(BusinessConstants.SUB_TYPE_PURCHASE.equals(depotHead.getSubType())) {
-                goToType = BusinessConstants.SUB_TYPE_PURCHASE_RETURN;
-            }
-            //销售出库转销售退货
-            if(BusinessConstants.SUB_TYPE_SALES.equals(depotHead.getSubType())) {
-                goToType = BusinessConstants.SUB_TYPE_SALES_RETURN;
-            }
-        }
-        String noType = "normal";
-        if(BusinessConstants.SUB_TYPE_PURCHASE_APPLY.equals(depotHead.getSubType())) {
-            noType = "apply";
-        }
-        BigDecimal count = depotItemMapperEx.getFinishNumber(meId, linkId, linkStr, noType, goToType);
-        //根据多单位情况进行数量的转换
-        if(materialUnit.equals(unitInfo.getOtherUnit()) && unitInfo.getRatio()!=null && unitInfo.getRatio().compareTo(BigDecimal.ZERO)!=0) {
-            count = count.divide(unitInfo.getRatio(),2,BigDecimal.ROUND_HALF_UP);
-        }
-        if(materialUnit.equals(unitInfo.getOtherUnitTwo()) && unitInfo.getRatioTwo()!=null && unitInfo.getRatioTwo().compareTo(BigDecimal.ZERO)!=0) {
-            count = count.divide(unitInfo.getRatioTwo(),2,BigDecimal.ROUND_HALF_UP);
-        }
-        if(materialUnit.equals(unitInfo.getOtherUnitThree()) && unitInfo.getRatioThree()!=null && unitInfo.getRatioThree().compareTo(BigDecimal.ZERO)!=0) {
-            count = count.divide(unitInfo.getRatioThree(),2,BigDecimal.ROUND_HALF_UP);
-        }
-        return count;
-    }
+    BigDecimal getFinishNumber(Long meId, Long id, Long headerId, Unit unitInfo, String materialUnit, String linkType);
 
-    /**
-     * 除去此单据之外的已入库|已出库|已转采购
-     * @param currentSubType
-     * @param meId
-     * @param linkId
-     * @param preHeaderId
-     * @param currentHeaderId
-     * @param unitInfo
-     * @param materialUnit
-     * @return
-     */
     @Transactional(value = "transactionManager", rollbackFor = Exception.class)
-    public BigDecimal getRealFinishNumber(String currentSubType, Long meId, Long linkId, Long preHeaderId, Long currentHeaderId, Unit unitInfo, String materialUnit) {
-        String goToType = currentSubType;
-        DepotHead depotHead =depotHeadMapper.selectByPrimaryKey(preHeaderId);
-        String linkStr = depotHead.getNumber(); //订单号
-        String linkType = "normal";
-        if(BusinessConstants.SUB_TYPE_PURCHASE_APPLY.equals(depotHead.getSubType())) {
-            linkType = "apply";
-        }
-        BigDecimal count = depotItemMapperEx.getRealFinishNumber(meId, linkId, linkStr, linkType, currentHeaderId, goToType);
-        //根据多单位情况进行数量的转换
-        if(materialUnit.equals(unitInfo.getOtherUnit()) && unitInfo.getRatio()!=null && unitInfo.getRatio().compareTo(BigDecimal.ZERO)!=0) {
-            count = count.divide(unitInfo.getRatio(),2,BigDecimal.ROUND_HALF_UP);
-        }
-        if(materialUnit.equals(unitInfo.getOtherUnitTwo()) && unitInfo.getRatioTwo()!=null && unitInfo.getRatioTwo().compareTo(BigDecimal.ZERO)!=0) {
-            count = count.divide(unitInfo.getRatioTwo(),2,BigDecimal.ROUND_HALF_UP);
-        }
-        if(materialUnit.equals(unitInfo.getOtherUnitThree()) && unitInfo.getRatioThree()!=null && unitInfo.getRatioThree().compareTo(BigDecimal.ZERO)!=0) {
-            count = count.divide(unitInfo.getRatioThree(),2,BigDecimal.ROUND_HALF_UP);
-        }
-        return count;
-    }
+    BigDecimal getRealFinishNumber(String currentSubType, Long meId, Long linkId, Long preHeaderId, Long currentHeaderId, Unit unitInfo, String materialUnit);
 
-    public List<DepotItemVoBatchNumberList> getBatchNumberList(String number, String name, Long depotId, String barCode,
-                                                               String batchNumber, Boolean forceFlag, Boolean inOutManageFlag) throws Exception {
-        List<DepotItemVoBatchNumberList> reslist = new ArrayList<>();
-        List<DepotItemVoBatchNumberList> list =  depotItemMapperEx.getBatchNumberList(StringUtil.toNull(number), name,
-                depotId, barCode, batchNumber, forceFlag, inOutManageFlag);
-        for(DepotItemVoBatchNumberList bn: list) {
-            if(bn.getTotalNum()!=null && bn.getTotalNum().compareTo(BigDecimal.ZERO)>0) {
-                bn.setExpirationDateStr(Tools.parseDateToStr(bn.getExpirationDate()));
-                if(bn.getUnitId()!=null) {
-                    Unit unit = unitService.getUnit(bn.getUnitId());
-                    String commodityUnit = bn.getCommodityUnit();
-                    bn.setTotalNum(unitService.parseStockByUnit(bn.getTotalNum(), unit, commodityUnit));
-                }
-                reslist.add(bn);
-            }
-        }
-        return reslist;
-    }
+    List<DepotItemVoBatchNumberList> getBatchNumberList(String number, String name, Long depotId, String barCode,
+                                                        String batchNumber, Boolean forceFlag, Boolean inOutManageFlag) throws Exception;
 
-    /**
-     * 查询某个批号的商品库存
-     * @param depotId
-     * @param barCode
-     * @param batchNumber
-     * @return
-     * @throws Exception
-     */
-    public BigDecimal getOneBatchNumberStock(Long depotId, String barCode, String batchNumber) throws Exception {
-        BigDecimal totalNum = BigDecimal.ZERO;
-        Boolean forceFlag = systemConfigService.getForceApprovalFlag();
-        Boolean inOutManageFlag = systemConfigService.getInOutManageFlag();
-        List<DepotItemVoBatchNumberList> list =  depotItemMapperEx.getBatchNumberList(null, null,
-                depotId, barCode, batchNumber, forceFlag, inOutManageFlag);
-        if(list!=null && list.size()>0) {
-            DepotItemVoBatchNumberList bn = list.get(0);
-            totalNum = bn.getTotalNum();
-            if(bn.getTotalNum()!=null && bn.getTotalNum().compareTo(BigDecimal.ZERO)>0) {
-                if(bn.getUnitId()!=null) {
-                    Unit unit = unitService.getUnit(bn.getUnitId());
-                    String commodityUnit = bn.getCommodityUnit();
-                    totalNum = unitService.parseStockByUnit(bn.getTotalNum(), unit, commodityUnit);
-                }
-            }
-        }
-        return totalNum;
-    }
+    BigDecimal getOneBatchNumberStock(Long depotId, String barCode, String batchNumber) throws Exception;
 
-    public Long getCountByMaterialAndDepot(Long mId, Long depotId) {
-        return depotItemMapperEx.getCountByMaterialAndDepot(mId, depotId);
-    }
+    Long getCountByMaterialAndDepot(Long mId, Long depotId);
 
-    public JSONObject parseMapByExcelData(String barCodes, List<Map<String, String>> detailList, String prefixNo) throws Exception {
-        JSONObject map = new JSONObject();
-        JSONArray arr = new JSONArray();
-        List<MaterialVo4Unit> list = depotItemMapperEx.getBillItemByParam(barCodes);
-        Map<String, MaterialVo4Unit> materialMap = new HashMap<>();
-        Map<String, Long> depotMap = new HashMap<>();
-        for (MaterialVo4Unit material: list) {
-            materialMap.put(material.getmBarCode(), material);
-        }
-        JSONArray depotArr = depotService.findDepotByCurrentUser();
-        for (Object depotObj: depotArr) {
-            if(depotObj!=null) {
-                JSONObject depotObject = JSONObject.parseObject(depotObj.toString());
-                depotMap.put(depotObject.getString("depotName"), depotObject.getLong("id"));
-            }
-        }
-        for (Map<String, String> detailMap: detailList) {
-            JSONObject item = new JSONObject();
-            String barCode = detailMap.get("barCode");
-            if(StringUtil.isNotEmpty(barCode)) {
-                MaterialVo4Unit m = materialMap.get(barCode);
-                if(m!=null) {
-                    //判断仓库是否存在
-                    String depotName = detailMap.get("depotName");
-                    if(StringUtil.isNotEmpty(depotName)) {
-                        if(depotMap.get(depotName)!=null) {
-                            item.put("depotName", depotName);
-                            item.put("depotId", depotMap.get(depotName));
-                        } else {
-                            throw new BusinessRunTimeException(ExceptionConstants.DEPOT_ITEM_DEPOTNAME_IS_NOT_EXIST_CODE,
-                                    String.format(ExceptionConstants.DEPOT_ITEM_DEPOTNAME_IS_NOT_EXIST_MSG, depotName));
-                        }
-                    }
-                    item.put("barCode", barCode);
-                    item.put("name", m.getName());
-                    item.put("standard", m.getStandard());
-                    if(StringUtil.isNotEmpty(m.getModel())) {
-                        item.put("model", m.getModel());
-                    }
-                    if(StringUtil.isNotEmpty(m.getColor())) {
-                        item.put("color", m.getColor());
-                    }
-                    if(StringUtil.isNotEmpty(m.getSku())) {
-                        item.put("sku", m.getSku());
-                    }
-                    BigDecimal stock = BigDecimal.ZERO;
-                    if(StringUtil.isNotEmpty(m.getSku())){
-                        stock = getSkuStockByParam(null, m.getMeId(),null,null);
-                    } else {
-                        stock = getCurrentStockByParam(null, m.getId());
-                    }
-                    item.put("stock", stock);
-                    item.put("unit", m.getCommodityUnit());
-                    BigDecimal operNumber = BigDecimal.ZERO;
-                    BigDecimal unitPrice = BigDecimal.ZERO;
-                    BigDecimal taxRate = BigDecimal.ZERO;
-                    if(StringUtil.isNotEmpty(detailMap.get("num"))) {
-                        operNumber = new BigDecimal(detailMap.get("num"));
-                    }
-                    if(StringUtil.isNotEmpty(detailMap.get("unitPrice"))) {
-                        unitPrice = new BigDecimal(detailMap.get("unitPrice"));
-                    } else {
-                        if("CGDD".equals(prefixNo)) {
-                            unitPrice = m.getPurchaseDecimal();
-                        } else if("XSDD".equals(prefixNo)) {
-                            unitPrice = m.getWholesaleDecimal();
-                        }
-                    }
-                    if(StringUtil.isNotEmpty(detailMap.get("taxRate"))) {
-                        taxRate = new BigDecimal(detailMap.get("taxRate"));
-                    }
-                    String remark = detailMap.get("remark");
-                    item.put("operNumber", operNumber);
-                    item.put("unitPrice", unitPrice);
-                    BigDecimal allPrice = BigDecimal.ZERO;
-                    if(unitPrice!=null && unitPrice.compareTo(BigDecimal.ZERO)!=0) {
-                        allPrice = unitPrice.multiply(operNumber);
-                    }
-                    BigDecimal taxMoney = BigDecimal.ZERO;
-                    if(taxRate.compareTo(BigDecimal.ZERO) != 0) {
-                        taxMoney = taxRate.multiply(allPrice).divide(BigDecimal.valueOf(100), 2, BigDecimal.ROUND_HALF_UP);
-                    }
-                    BigDecimal taxLastMoney = allPrice.add(taxMoney);
-                    item.put("allPrice", allPrice);
-                    item.put("taxRate", taxRate);
-                    item.put("taxMoney", taxMoney);
-                    item.put("taxLastMoney", taxLastMoney);
-                    item.put("remark", remark);
-                    arr.add(item);
-                } else {
-                    throw new BusinessRunTimeException(ExceptionConstants.DEPOT_ITEM_BARCODE_IS_NOT_EXIST_CODE,
-                            String.format(ExceptionConstants.DEPOT_ITEM_BARCODE_IS_NOT_EXIST_MSG, barCode));
-                }
-            }
-        }
-        map.put("rows", arr);
-        return map;
-    }
+    JSONObject parseMapByExcelData(String barCodes, List<Map<String, String>> detailList, String prefixNo) throws Exception;
 
-    public BigDecimal getLastUnitPriceByParam(Long organId, Long meId, String prefixNo) {
-        String type = "";
-        String subType = "";
-        if("XSDD".equals(prefixNo)) {
-            type = "其它";
-            subType = "销售订单";
-        } else if("XSCK".equals(prefixNo)) {
-            type = "出库";
-            subType = "销售";
-        } else if("XSTH".equals(prefixNo)) {
-            type = "入库";
-            subType = "销售退货";
-        } else if("QTCK".equals(prefixNo)) {
-            type = "出库";
-            subType = "其它";
-        }
-        return depotItemMapperEx.getLastUnitPriceByParam(organId, meId, type, subType);
-    }
+    BigDecimal getLastUnitPriceByParam(Long organId, Long meId, String prefixNo);
 
-    public BigDecimal getCurrentStockByParam(Long depotId, Long mId) {
-        BigDecimal stock = depotItemMapperEx.getCurrentStockByParam(depotId, mId);
-        return stock!=null? stock: BigDecimal.ZERO;
-    }
+    BigDecimal getCurrentStockByParam(Long depotId, Long mId);
 
-    /**
-     * 获取扩展信息
-     *
-     * @return
-     */
-    public String getOtherInfo(String[] mpArr, DepotItemVo4WithInfoEx diEx)throws Exception {
-        String materialOther = "";
-        for (int i = 0; i < mpArr.length; i++) {
-            if (mpArr[i].equals("自定义1")) {
-                materialOther = materialOther + ((diEx.getMOtherField1() == null || diEx.getMOtherField1().equals("")) ? "" : "(" + diEx.getMOtherField1() + ")");
-            }
-            if (mpArr[i].equals("自定义2")) {
-                materialOther = materialOther + ((diEx.getMOtherField2() == null || diEx.getMOtherField2().equals("")) ? "" : "(" + diEx.getMOtherField2() + ")");
-            }
-            if (mpArr[i].equals("自定义3")) {
-                materialOther = materialOther + ((diEx.getMOtherField3() == null || diEx.getMOtherField3().equals("")) ? "" : "(" + diEx.getMOtherField3() + ")");
-            }
-        }
-        return materialOther;
-    }
+    String getOtherInfo(String[] mpArr, DepotItemVo4WithInfoEx diEx)throws Exception;
 }

+ 1770 - 0
src/main/java/com/jsh/erp/service/impl/DepotHeadServiceImpl.java

@@ -0,0 +1,1770 @@
+package com.jsh.erp.service.impl;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.jsh.erp.constants.BusinessConstants;
+import com.jsh.erp.constants.ExceptionConstants;
+import com.jsh.erp.datasource.entities.*;
+import com.jsh.erp.datasource.mappers.DepotHeadMapper;
+import com.jsh.erp.datasource.mappers.DepotHeadMapperEx;
+import com.jsh.erp.datasource.mappers.DepotItemMapperEx;
+import com.jsh.erp.datasource.vo.*;
+import com.jsh.erp.exception.BusinessRunTimeException;
+import com.jsh.erp.exception.JshException;
+import com.jsh.erp.service.*;
+import com.jsh.erp.utils.ExcelUtils;
+import com.jsh.erp.utils.PageUtils;
+import com.jsh.erp.utils.StringUtil;
+import com.jsh.erp.utils.Tools;
+import jxl.Workbook;
+import jxl.write.WritableWorkbook;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import java.io.File;
+import java.math.BigDecimal;
+import java.sql.Timestamp;
+import java.util.*;
+import java.util.stream.Collectors;
+
+import static com.jsh.erp.utils.Tools.getCenternTime;
+import static com.jsh.erp.utils.Tools.getNow3;
+
+@Service
+public class DepotHeadServiceImpl extends ServiceImpl<DepotHeadMapper, DepotHead> implements DepotHeadService {
+    private Logger logger = LoggerFactory.getLogger(DepotHeadServiceImpl.class);
+
+    @Resource
+    private DepotHeadMapper depotHeadMapper;
+    @Resource
+    private DepotHeadMapperEx depotHeadMapperEx;
+    @Resource
+    private UserService userService;
+    @Resource
+    private RoleService roleService;
+    @Resource
+    private DepotService depotService;
+    @Resource
+    DepotItemService depotItemService;
+    @Resource
+    private SupplierService supplierService;
+    @Resource
+    private UserBusinessService userBusinessService;
+    @Resource
+    private SystemConfigService systemConfigService;
+    @Resource
+    private SerialNumberService serialNumberService;
+    @Resource
+    private OrgaUserRelService orgaUserRelService;
+    @Resource
+    private PersonService personService;
+    @Resource
+    private AccountService accountService;
+    @Resource
+    private AccountHeadService accountHeadService;
+    @Resource
+    private AccountItemService accountItemService;
+    @Resource
+    private SequenceService sequenceService;
+    @Resource
+    DepotItemMapperEx depotItemMapperEx;
+    @Resource
+    private LogService logService;
+
+    @Override
+    public DepotHead getDepotHead(long id)throws Exception {
+        DepotHead result=null;
+        try{
+            result=depotHeadMapper.selectByPrimaryKey(id);
+        }catch(Exception e){
+            JshException.readFail(logger, e);
+        }
+        return result;
+    }
+
+    @Override
+    public List<DepotHead> getDepotHead()throws Exception {
+        DepotHeadExample example = new DepotHeadExample();
+        example.createCriteria().andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
+        List<DepotHead> list=null;
+        try{
+            list=depotHeadMapper.selectByExample(example);
+        }catch(Exception e){
+            JshException.readFail(logger, e);
+        }
+        return list;
+    }
+
+    @Override
+    public List<DepotHeadVo4List> select(String type, String subType, String hasDebt, String status, String purchaseStatus, String number, String linkApply, String linkNumber,
+                                         String beginTime, String endTime, String materialParam, Long organId, Long creator, Long depotId, Long accountId, String remark) throws Exception {
+        List<DepotHeadVo4List> list = new ArrayList<>();
+        try{
+            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
+            Long userId = userService.getUserId(request);
+            String priceLimit = userService.getRoleTypeByUserId(userId).getPriceLimit();
+            String billCategory = getBillCategory(subType);
+            String [] depotArray = getDepotArray(subType);
+            String [] creatorArray = getCreatorArray();
+            String [] statusArray = StringUtil.isNotEmpty(status) ? status.split(",") : null;
+            String [] purchaseStatusArray = StringUtil.isNotEmpty(purchaseStatus) ? purchaseStatus.split(",") : null;
+            String [] organArray = getOrganArray(subType, purchaseStatus);
+            //以销定购,查看全部数据
+            creatorArray = StringUtil.isNotEmpty(purchaseStatus) ? null: creatorArray;
+            Map<Long,String> personMap = personService.getPersonMap();
+            Map<Long,String> accountMap = accountService.getAccountMap();
+            beginTime = Tools.parseDayToTime(beginTime,BusinessConstants.DAY_FIRST_TIME);
+            endTime = Tools.parseDayToTime(endTime,BusinessConstants.DAY_LAST_TIME);
+            PageUtils.startPage();
+            list = depotHeadMapperEx.selectByConditionDepotHead(type, subType, creatorArray, hasDebt,
+                    statusArray, purchaseStatusArray, number, linkApply, linkNumber, beginTime, endTime,
+                    materialParam, organId, organArray, creator, depotId, depotArray, accountId, remark);
+            if (null != list) {
+                List<Long> idList = new ArrayList<>();
+                List<String> numberList = new ArrayList<>();
+                for (DepotHeadVo4List dh : list) {
+                    idList.add(dh.getId());
+                    numberList.add(dh.getNumber());
+                }
+                //通过批量查询去构造map
+                Map<String,BigDecimal> finishDepositMap = getFinishDepositMapByNumberList(numberList);
+                Map<Long,Integer> financialBillNoMap = getFinancialBillNoMapByBillIdList(idList);
+                Map<String,Integer> billSizeMap = getBillSizeMapByLinkNumberList(numberList);
+                Map<Long,String> materialsListMap = findMaterialsListMapByHeaderIdList(idList);
+                Map<Long,BigDecimal> materialCountListMap = getMaterialCountListMapByHeaderIdList(idList);
+                for (DepotHeadVo4List dh : list) {
+                    if(accountMap!=null && StringUtil.isNotEmpty(dh.getAccountIdList()) && StringUtil.isNotEmpty(dh.getAccountMoneyList())) {
+                        String accountStr = accountService.getAccountStrByIdAndMoney(accountMap, dh.getAccountIdList(), dh.getAccountMoneyList());
+                        dh.setAccountName(accountStr);
+                    }
+                    if(dh.getAccountIdList() != null) {
+                        String accountidlistStr = dh.getAccountIdList().replace("[", "").replace("]", "").replaceAll("\"", "");
+                        dh.setAccountIdList(accountidlistStr);
+                    }
+                    if(dh.getAccountMoneyList() != null) {
+                        String accountmoneylistStr = dh.getAccountMoneyList().replace("[", "").replace("]", "").replaceAll("\"", "");
+                        dh.setAccountMoneyList(accountmoneylistStr);
+                    }
+                    if(dh.getChangeAmount() != null) {
+                        dh.setChangeAmount(roleService.parseBillPriceByLimit(dh.getChangeAmount().abs(), billCategory, priceLimit, request));
+                    } else {
+                        dh.setChangeAmount(BigDecimal.ZERO);
+                    }
+                    if(dh.getTotalPrice() != null) {
+                        BigDecimal lastTotalPrice = BusinessConstants.SUB_TYPE_CHECK_ENTER.equals(dh.getSubType())||
+                                BusinessConstants.SUB_TYPE_REPLAY.equals(dh.getSubType())?dh.getTotalPrice():dh.getTotalPrice().abs();
+                        dh.setTotalPrice(roleService.parseBillPriceByLimit(lastTotalPrice, billCategory, priceLimit, request));
+                    }
+                    BigDecimal discountLastMoney = dh.getDiscountLastMoney()!=null?dh.getDiscountLastMoney():BigDecimal.ZERO;
+                    dh.setDiscountLastMoney(roleService.parseBillPriceByLimit(discountLastMoney, billCategory, priceLimit, request));
+                    BigDecimal backAmount = dh.getBackAmount()!=null?dh.getBackAmount():BigDecimal.ZERO;
+                    dh.setBackAmount(roleService.parseBillPriceByLimit(backAmount, billCategory, priceLimit, request));
+                    if(dh.getDeposit() == null) {
+                        dh.setDeposit(BigDecimal.ZERO);
+                    } else {
+                        dh.setDeposit(roleService.parseBillPriceByLimit(dh.getDeposit(), billCategory, priceLimit, request));
+                    }
+                    //已经完成的欠款
+                    if(finishDepositMap!=null) {
+                        BigDecimal finishDeposit = finishDepositMap.get(dh.getNumber()) != null ? finishDepositMap.get(dh.getNumber()) : BigDecimal.ZERO;
+                        dh.setFinishDeposit(roleService.parseBillPriceByLimit(finishDeposit, billCategory, priceLimit, request));
+                    }
+                    //欠款计算
+                    BigDecimal otherMoney = dh.getOtherMoney()!=null?dh.getOtherMoney():BigDecimal.ZERO;
+                    BigDecimal deposit = dh.getDeposit()!=null?dh.getDeposit():BigDecimal.ZERO;
+                    BigDecimal changeAmount = dh.getChangeAmount()!=null?dh.getChangeAmount():BigDecimal.ZERO;
+                    BigDecimal debt = discountLastMoney.add(otherMoney).subtract((deposit.add(changeAmount)));
+                    dh.setDebt(roleService.parseBillPriceByLimit(debt, billCategory, priceLimit, request));
+                    //是否有付款单或收款单
+                    if(financialBillNoMap!=null) {
+                        Integer financialBillNoSize = financialBillNoMap.get(dh.getId());
+                        dh.setHasFinancialFlag(financialBillNoSize!=null && financialBillNoSize>0);
+                    }
+                    //是否有退款单
+                    if(billSizeMap!=null) {
+                        Integer billListSize = billSizeMap.get(dh.getNumber());
+                        dh.setHasBackFlag(billListSize!=null && billListSize>0);
+                    }
+                    if(StringUtil.isNotEmpty(dh.getSalesMan())) {
+                        dh.setSalesManStr(personService.getPersonByMapAndIds(personMap,dh.getSalesMan()));
+                    }
+                    if(dh.getOperTime() != null) {
+                        dh.setOperTimeStr(getCenternTime(dh.getOperTime()));
+                    }
+                    //商品信息简述
+                    if(materialsListMap!=null) {
+                        dh.setMaterialsList(materialsListMap.get(dh.getId()));
+                    }
+                    //商品总数量
+                    if(materialCountListMap!=null) {
+                        dh.setMaterialCount(materialCountListMap.get(dh.getId()));
+                    }
+                    //以销定购的情况(不能显示销售单据的金额和客户名称)
+                    if(StringUtil.isNotEmpty(purchaseStatus)) {
+                        dh.setOrganName("****");
+                        dh.setTotalPrice(null);
+                        dh.setDiscountLastMoney(null);
+                    }
+                }
+            }
+        } catch(Exception e){
+            JshException.readFail(logger, e);
+        }
+        return list;
+    }
+
+    /**
+     * 根据单据类型获取仓库数组
+     * @param subType
+     * @return
+     * @throws Exception
+     */
+    @Override
+    public String[] getDepotArray(String subType) throws Exception {
+        String [] depotArray = null;
+        if(!BusinessConstants.SUB_TYPE_PURCHASE_APPLY.equals(subType)
+                && !BusinessConstants.SUB_TYPE_PURCHASE_ORDER.equals(subType)
+                && !BusinessConstants.SUB_TYPE_SALES_ORDER.equals(subType)) {
+            String depotIds = depotService.findDepotStrByCurrentUser();
+            depotArray = StringUtil.isNotEmpty(depotIds) ? depotIds.split(",") : null;
+        }
+        return depotArray;
+    }
+
+    /**
+     * 根据角色类型获取操作员数组
+     * @return
+     * @throws Exception
+     */
+    @Override
+    public String[] getCreatorArray() throws Exception {
+        String creator = getCreatorByCurrentUser();
+        String [] creatorArray=null;
+        if(StringUtil.isNotEmpty(creator)){
+            creatorArray = creator.split(",");
+        }
+        return creatorArray;
+    }
+
+    /**
+     * 根据角色类型获取操作员数组
+     * @param organizationId
+     * @return
+     * @throws Exception
+     */
+    @Override
+    public String[] getCreatorArrayByOrg(Long organizationId) throws Exception {
+        List<Long> userIdList = orgaUserRelService.getUserIdListByOrgId(organizationId);
+        if(userIdList.size()>0) {
+            List<String> userIdStrList = userIdList.stream().map(Object::toString).collect(Collectors.toList());
+            return StringUtil.listToStringArray(userIdStrList);
+        } else {
+            return "-1".split(",");
+        }
+    }
+
+    /**
+     * 获取机构数组
+     * @return
+     */
+    @Override
+    public String[] getOrganArray(String subType, String purchaseStatus) throws Exception {
+        String [] organArray = null;
+        String type = "UserCustomer";
+        Long userId = userService.getCurrentUser().getId();
+        //获取权限信息
+        String ubValue = userBusinessService.getUBValueByTypeAndKeyId(type, userId.toString());
+        List<Supplier> supplierList = supplierService.findBySelectCus();
+        if(BusinessConstants.SUB_TYPE_SALES_ORDER.equals(subType) || BusinessConstants.SUB_TYPE_SALES.equals(subType)
+                ||BusinessConstants.SUB_TYPE_SALES_RETURN.equals(subType) ) {
+            //采购订单里面选择销售订单的时候不要过滤
+            if(StringUtil.isEmpty(purchaseStatus)) {
+                if (null != supplierList && supplierList.size() > 0) {
+                    boolean customerFlag = systemConfigService.getCustomerFlag();
+                    List<String> organList = new ArrayList<>();
+                    for (Supplier supplier : supplierList) {
+                        boolean flag = ubValue.contains("[" + supplier.getId().toString() + "]");
+                        if (!customerFlag || flag) {
+                            organList.add(supplier.getId().toString());
+                        }
+                    }
+                    if(organList.size() > 0) {
+                        organArray = StringUtil.listToStringArray(organList);
+                    }
+                }
+            }
+        }
+        return organArray;
+    }
+
+    /**
+     * 根据角色类型获取操作员
+     * @return
+     * @throws Exception
+     */
+    @Override
+    public String getCreatorByCurrentUser() throws Exception {
+        String creator = "";
+        User user = userService.getCurrentUser();
+        String roleType = userService.getRoleTypeByUserId(user.getId()).getType(); //角色类型
+        if(BusinessConstants.ROLE_TYPE_PRIVATE.equals(roleType)) {
+            creator = user.getId().toString();
+        } else if(BusinessConstants.ROLE_TYPE_THIS_ORG.equals(roleType)) {
+            creator = orgaUserRelService.getUserIdListByUserId(user.getId());
+        }
+        return creator;
+    }
+
+    @Override
+    public Map<String, BigDecimal> getFinishDepositMapByNumberList(List<String> numberList) {
+        Map<String,BigDecimal> finishDepositMap = new HashMap<>();
+        if(numberList.size()>0) {
+            List<FinishDepositVo> list = depotHeadMapperEx.getFinishDepositByNumberList(numberList);
+            if(list!=null && list.size()>0) {
+                for (FinishDepositVo finishDepositVo : list) {
+                    if(finishDepositVo!=null) {
+                        finishDepositMap.put(finishDepositVo.getNumber(), finishDepositVo.getFinishDeposit());
+                    }
+                }
+            }
+        }
+        return finishDepositMap;
+    }
+
+    @Override
+    public Map<String, Integer> getBillSizeMapByLinkNumberList(List<String> numberList) throws Exception {
+        Map<String, Integer> billListMap = new HashMap<>();
+        if(numberList.size()>0) {
+            List<DepotHead> list = getBillListByLinkNumberList(numberList);
+            if(list!=null && list.size()>0) {
+                for (DepotHead depotHead : list) {
+                    if(depotHead!=null) {
+                        billListMap.put(depotHead.getLinkNumber(), list.size());
+                    }
+                }
+            }
+        }
+        return billListMap;
+    }
+
+    @Override
+    public Map<Long,Integer> getFinancialBillNoMapByBillIdList(List<Long> idList) {
+        Map<Long, Integer> billListMap = new HashMap<>();
+        if(idList.size()>0) {
+            List<AccountItem> list = accountHeadService.getFinancialBillNoByBillIdList(idList);
+            if(list!=null && list.size()>0) {
+                for (AccountItem accountItem : list) {
+                    if(accountItem!=null) {
+                        billListMap.put(accountItem.getBillId(), list.size());
+                    }
+                }
+            }
+        }
+        return billListMap;
+    }
+
+    @Override
+    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
+    public int insertDepotHead(JSONObject obj, HttpServletRequest request)throws Exception {
+        DepotHead depotHead = JSONObject.parseObject(obj.toJSONString(), DepotHead.class);
+        depotHead.setCreateTime(new Timestamp(System.currentTimeMillis()));
+        depotHead.setStatus(BusinessConstants.BILLS_STATUS_UN_AUDIT);
+        int result=0;
+        try{
+            result=depotHeadMapper.insert(depotHead);
+            logService.insertLog("单据", BusinessConstants.LOG_OPERATION_TYPE_ADD, request);
+        }catch(Exception e){
+            JshException.writeFail(logger, e);
+        }
+        return result;
+    }
+
+    @Override
+    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
+    public int updateDepotHead(JSONObject obj, HttpServletRequest request) throws Exception{
+        DepotHead depotHead = JSONObject.parseObject(obj.toJSONString(), DepotHead.class);
+        DepotHead dh=null;
+        try{
+            dh = depotHeadMapper.selectByPrimaryKey(depotHead.getId());
+        }catch(Exception e){
+            JshException.readFail(logger, e);
+        }
+        depotHead.setStatus(dh.getStatus());
+        depotHead.setCreateTime(dh.getCreateTime());
+        int result=0;
+        try{
+            result = depotHeadMapper.updateByPrimaryKey(depotHead);
+            logService.insertLog("单据",
+                    new StringBuffer(BusinessConstants.LOG_OPERATION_TYPE_EDIT).append(depotHead.getId()).toString(), request);
+        }catch(Exception e){
+            JshException.writeFail(logger, e);
+        }
+        return result;
+    }
+
+    @Override
+    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
+    public int deleteDepotHead(Long id, HttpServletRequest request)throws Exception {
+        return batchDeleteBillByIds(id.toString());
+    }
+
+    @Override
+    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
+    public int batchDeleteDepotHead(String ids, HttpServletRequest request)throws Exception {
+        return batchDeleteBillByIds(ids);
+    }
+
+    @Override
+    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
+    public int batchDeleteBillByIds(String ids)throws Exception {
+        StringBuffer sb = new StringBuffer();
+        sb.append(BusinessConstants.LOG_OPERATION_TYPE_DELETE);
+        List<DepotHead> dhList = getDepotHeadListByIds(ids);
+        for(DepotHead depotHead: dhList){
+            //只有未审核的单据才能被删除
+            if(!"0".equals(depotHead.getStatus())) {
+                throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_UN_AUDIT_DELETE_FAILED_CODE,
+                        String.format(ExceptionConstants.DEPOT_HEAD_UN_AUDIT_DELETE_FAILED_MSG));
+            }
+        }
+        for(DepotHead depotHead: dhList){
+            sb.append("[").append(depotHead.getNumber()).append("]");
+            User userInfo = userService.getCurrentUser();
+            //删除入库单据,先校验序列号是否出库,如果未出库则同时删除序列号,如果已出库则不能删除单据
+            if (BusinessConstants.DEPOTHEAD_TYPE_IN.equals(depotHead.getType())) {
+                List<DepotItem> depotItemList = depotItemMapperEx.findDepotItemListBydepotheadId(depotHead.getId(), BusinessConstants.ENABLE_SERIAL_NUMBER_ENABLED);
+                if (depotItemList != null && depotItemList.size() > 0) {
+                    //单据明细里面存在序列号商品
+                    int serialNumberSellCount = depotHeadMapperEx.getSerialNumberBySell(depotHead.getNumber());
+                    if (serialNumberSellCount > 0) {
+                        //已出库则不能删除单据
+                        throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_SERIAL_IS_SELL_CODE,
+                                String.format(ExceptionConstants.DEPOT_HEAD_SERIAL_IS_SELL_MSG, depotHead.getNumber()));
+                    } else {
+                        //删除序列号
+                        SerialNumberExample example = new SerialNumberExample();
+                        example.createCriteria().andInBillNoEqualTo(depotHead.getNumber());
+                        serialNumberService.deleteByExample(example);
+                    }
+                }
+            }
+            //删除出库数据回收序列号
+            if (BusinessConstants.DEPOTHEAD_TYPE_OUT.equals(depotHead.getType())
+                    && !BusinessConstants.SUB_TYPE_TRANSFER.equals(depotHead.getSubType())) {
+                //查询单据子表列表
+                List<DepotItem> depotItemList = depotItemMapperEx.findDepotItemListBydepotheadId(depotHead.getId(), BusinessConstants.ENABLE_SERIAL_NUMBER_ENABLED);
+                /**回收序列号*/
+                if (depotItemList != null && depotItemList.size() > 0) {
+                    for (DepotItem depotItem : depotItemList) {
+                        //BasicNumber=OperNumber*ratio
+                        serialNumberService.cancelSerialNumber(depotItem.getMaterialId(), depotHead.getNumber(), (depotItem.getBasicNumber() == null ? 0 : depotItem.getBasicNumber()).intValue(), userInfo);
+                    }
+                }
+            }
+            List<DepotItem> list = depotItemService.getListByHeaderId(depotHead.getId());
+            //删除单据子表数据
+            depotItemMapperEx.batchDeleteDepotItemByDepotHeadIds(new Long[]{depotHead.getId()});
+            //删除单据主表信息
+            batchDeleteDepotHeadByIds(depotHead.getId().toString());
+            //将关联的单据置为审核状态-针对采购入库、销售出库、盘点复盘、其它入库、其它出库
+            if(StringUtil.isNotEmpty(depotHead.getLinkNumber())){
+                if((BusinessConstants.DEPOTHEAD_TYPE_IN.equals(depotHead.getType()) &&
+                        BusinessConstants.SUB_TYPE_PURCHASE.equals(depotHead.getSubType()))
+                        || (BusinessConstants.DEPOTHEAD_TYPE_OUT.equals(depotHead.getType()) &&
+                        BusinessConstants.SUB_TYPE_SALES.equals(depotHead.getSubType()))
+                        || (BusinessConstants.DEPOTHEAD_TYPE_OTHER.equals(depotHead.getType()) &&
+                        BusinessConstants.SUB_TYPE_REPLAY.equals(depotHead.getSubType()))
+                        || (BusinessConstants.DEPOTHEAD_TYPE_IN.equals(depotHead.getType()) &&
+                        BusinessConstants.SUB_TYPE_OTHER.equals(depotHead.getSubType()))
+                        || (BusinessConstants.DEPOTHEAD_TYPE_OUT.equals(depotHead.getType()) &&
+                        BusinessConstants.SUB_TYPE_OTHER.equals(depotHead.getSubType()))) {
+                    String status = BusinessConstants.BILLS_STATUS_AUDIT;
+                    //查询除当前单据之外的关联单据列表
+                    List<DepotHead> exceptCurrentList = getListByLinkNumberExceptCurrent(depotHead.getLinkNumber(), depotHead.getNumber(), depotHead.getType());
+                    if(exceptCurrentList!=null && exceptCurrentList.size()>0) {
+                        status = BusinessConstants.BILLS_STATUS_SKIPING;
+                    }
+                    DepotHead dh = new DepotHead();
+                    dh.setStatus(status);
+                    DepotHeadExample example = new DepotHeadExample();
+                    example.createCriteria().andNumberEqualTo(depotHead.getLinkNumber());
+                    depotHeadMapper.updateByExampleSelective(dh, example);
+                }
+            }
+            //将关联的单据置为审核状态-针对请购单转采购订单的情况
+            if(StringUtil.isNotEmpty(depotHead.getLinkApply())){
+                if(BusinessConstants.DEPOTHEAD_TYPE_OTHER.equals(depotHead.getType()) &&
+                        BusinessConstants.SUB_TYPE_PURCHASE_ORDER.equals(depotHead.getSubType())) {
+                    String status = BusinessConstants.BILLS_STATUS_AUDIT;
+                    //查询除当前单据之外的关联单据列表
+                    List<DepotHead> exceptCurrentList = getListByLinkApplyExceptCurrent(depotHead.getLinkApply(), depotHead.getNumber(), depotHead.getType());
+                    if(exceptCurrentList!=null && exceptCurrentList.size()>0) {
+                        status = BusinessConstants.BILLS_STATUS_SKIPING;
+                    }
+                    DepotHead dh = new DepotHead();
+                    dh.setStatus(status);
+                    DepotHeadExample example = new DepotHeadExample();
+                    example.createCriteria().andNumberEqualTo(depotHead.getLinkApply());
+                    depotHeadMapper.updateByExampleSelective(dh, example);
+                }
+            }
+            //将关联的销售订单单据置为未采购状态-针对销售订单转采购订单的情况
+            if(StringUtil.isNotEmpty(depotHead.getLinkNumber())){
+                if(BusinessConstants.DEPOTHEAD_TYPE_OTHER.equals(depotHead.getType()) &&
+                        BusinessConstants.SUB_TYPE_PURCHASE_ORDER.equals(depotHead.getSubType())) {
+                    DepotHead dh = new DepotHead();
+                    //获取分批操作后单据的商品和商品数量(汇总)
+                    List<DepotItemVo4MaterialAndSum> batchList = depotItemMapperEx.getBatchBillDetailMaterialSum(depotHead.getLinkNumber(), "normal", depotHead.getType());
+                    if(batchList.size()>0) {
+                        dh.setPurchaseStatus(BusinessConstants.PURCHASE_STATUS_SKIPING);
+                    } else {
+                        dh.setPurchaseStatus(BusinessConstants.PURCHASE_STATUS_UN_AUDIT);
+                    }
+                    DepotHeadExample example = new DepotHeadExample();
+                    example.createCriteria().andNumberEqualTo(depotHead.getLinkNumber());
+                    depotHeadMapper.updateByExampleSelective(dh, example);
+                }
+            }
+            //对于零售出库单据,更新会员的预收款信息
+            if (BusinessConstants.DEPOTHEAD_TYPE_OUT.equals(depotHead.getType())
+                    && BusinessConstants.SUB_TYPE_RETAIL.equals(depotHead.getSubType())){
+                if(BusinessConstants.PAY_TYPE_PREPAID.equals(depotHead.getPayType())) {
+                    if (depotHead.getOrganId() != null) {
+                        //更新会员预付款
+                        supplierService.updateAdvanceIn(depotHead.getOrganId());
+                    }
+                }
+            }
+            for (DepotItem depotItem : list) {
+                //更新当前库存
+                depotItemService.updateCurrentStock(depotItem);
+                //更新当前成本价
+                depotItemService.updateCurrentUnitPrice(depotItem);
+            }
+        }
+        //路径列表
+        List<String> pathList = new ArrayList<>();
+        for(DepotHead depotHead: dhList){
+            if(StringUtil.isNotEmpty(depotHead.getFileName())) {
+                pathList.add(depotHead.getFileName());
+            }
+        }
+        //逻辑删除文件
+        systemConfigService.deleteFileByPathList(pathList);
+        logService.insertLog("单据", sb.toString(),
+                ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest());
+        return 1;
+    }
+
+    /**
+     * 删除单据主表信息
+     * @param ids
+     * @return
+     * @throws Exception
+     */
+    @Override
+    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
+    public int batchDeleteDepotHeadByIds(String ids)throws Exception {
+        User userInfo=userService.getCurrentUser();
+        String [] idArray=ids.split(",");
+        int result=0;
+        try{
+            result = depotHeadMapperEx.batchDeleteDepotHeadByIds(new Date(),userInfo==null?null:userInfo.getId(),idArray);
+        }catch(Exception e){
+            JshException.writeFail(logger, e);
+        }
+        return result;
+    }
+
+    @Override
+    public List<DepotHead> getDepotHeadListByIds(String ids)throws Exception {
+        List<Long> idList = StringUtil.strToLongList(ids);
+        List<DepotHead> list = new ArrayList<>();
+        try{
+            DepotHeadExample example = new DepotHeadExample();
+            example.createCriteria().andIdIn(idList);
+            list = depotHeadMapper.selectByExample(example);
+        }catch(Exception e){
+            JshException.readFail(logger, e);
+        }
+        return list;
+    }
+
+    /**
+     * 校验单据编号是否存在
+     * @param id
+     * @param number
+     * @return
+     * @throws Exception
+     */
+    @Override
+    public int checkIsBillNumberExist(Long id, String number)throws Exception {
+        DepotHeadExample example = new DepotHeadExample();
+        example.createCriteria().andIdNotEqualTo(id).andNumberEqualTo(number).andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
+        List<DepotHead> list = null;
+        try{
+            list = depotHeadMapper.selectByExample(example);
+        }catch(Exception e){
+            JshException.readFail(logger, e);
+        }
+        return list==null?0:list.size();
+    }
+
+    @Override
+    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
+    public int batchSetStatus(String status, String depotHeadIDs)throws Exception {
+        int result = 0;
+        List<Long> dhIds = new ArrayList<>();
+        List<Long> ids = StringUtil.strToLongList(depotHeadIDs);
+        for(Long id: ids) {
+            DepotHead depotHead = getDepotHead(id);
+            if("0".equals(status)){
+                //进行反审核操作
+                if("1".equals(depotHead.getStatus()) && "0".equals(depotHead.getPurchaseStatus())) {
+                    dhIds.add(id);
+                } else if("2".equals(depotHead.getPurchaseStatus())) {
+                    throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_PURCHASE_STATUS_TWO_CODE,
+                            String.format(ExceptionConstants.DEPOT_HEAD_PURCHASE_STATUS_TWO_MSG));
+                } else if("3".equals(depotHead.getPurchaseStatus())) {
+                    throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_PURCHASE_STATUS_THREE_CODE,
+                            String.format(ExceptionConstants.DEPOT_HEAD_PURCHASE_STATUS_THREE_MSG));
+                } else {
+                    throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_AUDIT_TO_UN_AUDIT_FAILED_CODE,
+                            String.format(ExceptionConstants.DEPOT_HEAD_AUDIT_TO_UN_AUDIT_FAILED_MSG));
+                }
+            } else if("1".equals(status)){
+                //进行审核操作
+                if("0".equals(depotHead.getStatus())) {
+                    dhIds.add(id);
+                } else {
+                    throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_UN_AUDIT_TO_AUDIT_FAILED_CODE,
+                            String.format(ExceptionConstants.DEPOT_HEAD_UN_AUDIT_TO_AUDIT_FAILED_MSG));
+                }
+            }
+        }
+        if(dhIds.size()>0) {
+            DepotHead depotHead = new DepotHead();
+            depotHead.setStatus(status);
+            DepotHeadExample example = new DepotHeadExample();
+            example.createCriteria().andIdIn(dhIds);
+            result = depotHeadMapper.updateByExampleSelective(depotHead, example);
+            //更新当前库存
+            if(systemConfigService.getForceApprovalFlag()) {
+                for(Long dhId: dhIds) {
+                    List<DepotItem> list = depotItemService.getListByHeaderId(dhId);
+                    for (DepotItem depotItem : list) {
+                        depotItemService.updateCurrentStock(depotItem);
+                    }
+                }
+            }
+        }
+        return result;
+    }
+
+    @Override
+    public Map<Long,String> findMaterialsListMapByHeaderIdList(List<Long> idList)throws Exception {
+        Map<Long,String> materialsListMap = new HashMap<>();
+        if(idList.size()>0) {
+            List<MaterialsListVo> list = depotHeadMapperEx.findMaterialsListMapByHeaderIdList(idList);
+            for (MaterialsListVo materialsListVo : list) {
+                String materialsList = materialsListVo.getMaterialsList();
+                if(StringUtil.isNotEmpty(materialsList)) {
+                    materialsList = materialsList.replace(",",",");
+                }
+                materialsListMap.put(materialsListVo.getHeaderId(), materialsList);
+            }
+        }
+        return materialsListMap;
+    }
+
+    @Override
+    public Map<Long,BigDecimal> getMaterialCountListMapByHeaderIdList(List<Long> idList)throws Exception {
+        Map<Long,BigDecimal> materialCountListMap = new HashMap<>();
+        if(idList.size()>0) {
+            List<MaterialCountVo> list = depotHeadMapperEx.getMaterialCountListByHeaderIdList(idList);
+            for(MaterialCountVo materialCountVo : list){
+                materialCountListMap.put(materialCountVo.getHeaderId(), materialCountVo.getMaterialCount());
+            }
+        }
+        return materialCountListMap;
+    }
+
+    @Override
+    public List<DepotHeadVo4InDetail> findInOutDetail(String beginTime, String endTime, String type, String[] creatorArray,
+                                                      String[] organArray, List<Long> categoryList, Boolean forceFlag, Boolean inOutManageFlag,
+                                                      String materialParam, List<Long> depotList, Integer oId, String number,
+                                                      Long creator, String remark, String column, String order, Integer offset, Integer rows) throws Exception{
+        List<DepotHeadVo4InDetail> list = null;
+        try{
+            list =depotHeadMapperEx.findInOutDetail(beginTime, endTime, type, creatorArray, organArray, categoryList, forceFlag, inOutManageFlag,
+                    materialParam, depotList, oId, number, creator, remark, column, order, offset, rows);
+        }catch(Exception e){
+            JshException.readFail(logger, e);
+        }
+        return list;
+    }
+
+    @Override
+    public int findInOutDetailCount(String beginTime, String endTime, String type, String[] creatorArray,
+                                    String[] organArray, List<Long> categoryList, Boolean forceFlag, Boolean inOutManageFlag, String materialParam, List<Long> depotList, Integer oId, String number,
+                                    Long creator, String remark) throws Exception{
+        int result = 0;
+        try{
+            result =depotHeadMapperEx.findInOutDetailCount(beginTime, endTime, type, creatorArray, organArray, categoryList, forceFlag, inOutManageFlag,
+                    materialParam, depotList, oId, number, creator, remark);
+        }catch(Exception e){
+            JshException.readFail(logger, e);
+        }
+        return result;
+    }
+
+    @Override
+    public DepotHeadVo4InDetail findInOutDetailStatistic(String beginTime, String endTime, String type, String[] creatorArray,
+                                                         String[] organArray, List<Long> categoryList, Boolean forceFlag, Boolean inOutManageFlag,
+                                                         String materialParam, List<Long> depotList, Integer oId, String number,
+                                                         Long creator, String remark) throws Exception{
+        DepotHeadVo4InDetail item = new DepotHeadVo4InDetail();
+        try{
+            List<DepotHeadVo4InDetail> list =depotHeadMapperEx.findInOutDetailStatistic(beginTime, endTime, type, creatorArray, organArray, categoryList, forceFlag, inOutManageFlag,
+                    materialParam, depotList, oId, number, creator, remark);
+            if(list.size()>0) {
+                item.setOperNumber(list.get(0).getOperNumber());
+                item.setAllPrice(list.get(0).getAllPrice());
+            }
+        }catch(Exception e){
+            JshException.readFail(logger, e);
+        }
+        return item;
+    }
+
+    @Override
+    public List<DepotHeadVo4InOutMCount> findInOutMaterialCount(String beginTime, String endTime, String type, List<Long> categoryList,
+                                                                Boolean forceFlag, Boolean inOutManageFlag, String materialParam,
+                                                                List<Long> depotList, Long organizationId, Integer oId, String column, String order,
+                                                                Integer offset, Integer rows)throws Exception {
+        List<DepotHeadVo4InOutMCount> list = null;
+        try{
+            String [] creatorArray = getCreatorArray();
+            if(creatorArray == null && organizationId != null) {
+                creatorArray = getCreatorArrayByOrg(organizationId);
+            }
+            String subType = "出库".equals(type)? "销售" : "";
+            String [] organArray = getOrganArray(subType, "");
+            list =depotHeadMapperEx.findInOutMaterialCount(beginTime, endTime, type, categoryList, forceFlag, inOutManageFlag, materialParam, depotList, oId,
+                    creatorArray, organArray, column, order, offset, rows);
+        }catch(Exception e){
+            JshException.readFail(logger, e);
+        }
+        return list;
+    }
+
+    @Override
+    public int findInOutMaterialCountTotal(String beginTime, String endTime, String type, List<Long> categoryList,
+                                           Boolean forceFlag, Boolean inOutManageFlag, String materialParam,
+                                           List<Long> depotList, Long organizationId, Integer oId)throws Exception {
+        int result = 0;
+        try{
+            String [] creatorArray = getCreatorArray();
+            if(creatorArray == null && organizationId != null) {
+                creatorArray = getCreatorArrayByOrg(organizationId);
+            }
+            String subType = "出库".equals(type)? "销售" : "";
+            String [] organArray = getOrganArray(subType, "");
+            result =depotHeadMapperEx.findInOutMaterialCountTotal(beginTime, endTime, type, categoryList, forceFlag, inOutManageFlag, materialParam, depotList, oId,
+                    creatorArray, organArray);
+        }catch(Exception e){
+            JshException.readFail(logger, e);
+        }
+        return result;
+    }
+
+    @Override
+    public DepotHeadVo4InOutMCount findInOutMaterialCountStatistic(String beginTime, String endTime, String type, List<Long> categoryList,
+                                                                   Boolean forceFlag, Boolean inOutManageFlag, String materialParam,
+                                                                   List<Long> depotList, Long organizationId, Integer oId) throws Exception {
+        DepotHeadVo4InOutMCount item = new DepotHeadVo4InOutMCount();
+        try{
+            String [] creatorArray = getCreatorArray();
+            if(creatorArray == null && organizationId != null) {
+                creatorArray = getCreatorArrayByOrg(organizationId);
+            }
+            String subType = "出库".equals(type)? "销售" : "";
+            String [] organArray = getOrganArray(subType, "");
+            List<DepotHeadVo4InOutMCount> list = depotHeadMapperEx.findInOutMaterialCountStatistic(beginTime, endTime, type, categoryList,
+                    forceFlag, inOutManageFlag, materialParam, depotList, oId, creatorArray, organArray);
+            if(list.size()>0) {
+                item.setNumSum(list.get(0).getNumSum());
+                item.setPriceSum(list.get(0).getPriceSum());
+            }
+        }catch(Exception e){
+            JshException.readFail(logger, e);
+        }
+        return item;
+    }
+
+    @Override
+    public List<DepotHeadVo4InDetail> findAllocationDetail(String beginTime, String endTime, String subType, String number,
+                                                           String[] creatorArray, List<Long> categoryList, Boolean forceFlag, String materialParam, List<Long> depotList, List<Long> depotFList,
+                                                           String remark, String column, String order, Integer offset, Integer rows) throws Exception{
+        List<DepotHeadVo4InDetail> list = null;
+        try{
+            list =depotHeadMapperEx.findAllocationDetail(beginTime, endTime, subType, number, creatorArray, categoryList, forceFlag,
+                    materialParam, depotList, depotFList, remark, column, order, offset, rows);
+        }catch(Exception e){
+            JshException.readFail(logger, e);
+        }
+        return list;
+    }
+
+    @Override
+    public int findAllocationDetailCount(String beginTime, String endTime, String subType, String number,
+                                         String[] creatorArray, List<Long> categoryList, Boolean forceFlag, String materialParam, List<Long> depotList, List<Long> depotFList,
+                                         String remark) throws Exception{
+        int result = 0;
+        try{
+            result =depotHeadMapperEx.findAllocationDetailCount(beginTime, endTime, subType, number, creatorArray, categoryList, forceFlag,
+                    materialParam, depotList, depotFList, remark);
+        }catch(Exception e){
+            JshException.readFail(logger, e);
+        }
+        return result;
+    }
+
+    @Override
+    public DepotHeadVo4InDetail findAllocationStatistic(String beginTime, String endTime, String subType, String number,
+                                                        String[] creatorArray, List<Long> categoryList, Boolean forceFlag, String materialParam, List<Long> depotList, List<Long> depotFList,
+                                                        String remark) throws Exception{
+        DepotHeadVo4InDetail item = new DepotHeadVo4InDetail();
+        try{
+            List<DepotHeadVo4InDetail> list =depotHeadMapperEx.findAllocationStatistic(beginTime, endTime, subType, number, creatorArray, categoryList, forceFlag,
+                    materialParam, depotList, depotFList, remark);
+            if(list.size()>0) {
+                item.setOperNumber(list.get(0).getOperNumber());
+                item.setAllPrice(list.get(0).getAllPrice());
+            }
+        }catch(Exception e){
+            JshException.readFail(logger, e);
+        }
+        return item;
+    }
+
+    @Override
+    public List<DepotHeadVo4StatementAccount> getStatementAccount(String beginTime, String endTime, Integer organId, String[] organArray,
+                                                                  Integer hasDebt, String supplierType, String type, String subType, String typeBack,
+                                                                  String subTypeBack, String billType, Integer offset, Integer rows) {
+        List<DepotHeadVo4StatementAccount> list = null;
+        try{
+            list = depotHeadMapperEx.getStatementAccount(beginTime, endTime, organId, organArray, hasDebt, supplierType, type, subType,typeBack, subTypeBack, billType, offset, rows);
+        } catch(Exception e){
+            JshException.readFail(logger, e);
+        }
+        return list;
+    }
+
+    @Override
+    public int getStatementAccountCount(String beginTime, String endTime, Integer organId, String[] organArray,
+                                        Integer hasDebt, String supplierType, String type, String subType, String typeBack, String subTypeBack, String billType) {
+        int result = 0;
+        try{
+            result = depotHeadMapperEx.getStatementAccountCount(beginTime, endTime, organId, organArray, hasDebt, supplierType, type, subType,typeBack, subTypeBack, billType);
+        } catch(Exception e){
+            JshException.readFail(logger, e);
+        }
+        return result;
+    }
+
+    @Override
+    public List<DepotHeadVo4StatementAccount> getStatementAccountTotalPay(String beginTime, String endTime, Integer organId, String[] organArray,
+                                                                          Integer hasDebt, String supplierType, String type, String subType,
+                                                                          String typeBack, String subTypeBack, String billType) {
+        List<DepotHeadVo4StatementAccount> list = null;
+        try{
+            list = depotHeadMapperEx.getStatementAccountTotalPay(beginTime, endTime, organId, organArray, hasDebt, supplierType, type, subType,typeBack, subTypeBack, billType);
+        } catch(Exception e){
+            JshException.readFail(logger, e);
+        }
+        return list;
+    }
+
+    @Override
+    public List<DepotHeadVo4List> getDetailByNumber(String number, HttpServletRequest request)throws Exception {
+        List<DepotHeadVo4List> resList = new ArrayList<>();
+        try{
+            Long userId = userService.getUserId(request);
+            String priceLimit = userService.getRoleTypeByUserId(userId).getPriceLimit();
+            Map<Long,String> personMap = personService.getPersonMap();
+            Map<Long,String> accountMap = accountService.getAccountMap();
+            List<DepotHeadVo4List> list = depotHeadMapperEx.getDetailByNumber(number);
+            if (null != list) {
+                List<Long> idList = new ArrayList<>();
+                List<String> numberList = new ArrayList<>();
+                for (DepotHeadVo4List dh : list) {
+                    idList.add(dh.getId());
+                    numberList.add(dh.getNumber());
+                }
+                //通过批量查询去构造map
+                Map<Long,Integer> financialBillNoMap = getFinancialBillNoMapByBillIdList(idList);
+                Map<String,Integer> billSizeMap = getBillSizeMapByLinkNumberList(numberList);
+                Map<Long,String> materialsListMap = findMaterialsListMapByHeaderIdList(idList);
+                DepotHeadVo4List dh = list.get(0);
+                String billCategory = getBillCategory(dh.getSubType());
+                if(accountMap!=null && StringUtil.isNotEmpty(dh.getAccountIdList()) && StringUtil.isNotEmpty(dh.getAccountMoneyList())) {
+                    String accountStr = accountService.getAccountStrByIdAndMoney(accountMap, dh.getAccountIdList(), dh.getAccountMoneyList());
+                    dh.setAccountName(accountStr);
+                }
+                if(dh.getAccountIdList() != null) {
+                    String accountidlistStr = dh.getAccountIdList().replace("[", "").replace("]", "").replaceAll("\"", "");
+                    dh.setAccountIdList(accountidlistStr);
+                }
+                if(dh.getAccountMoneyList() != null) {
+                    String accountmoneylistStr = dh.getAccountMoneyList().replace("[", "").replace("]", "").replaceAll("\"", "");
+                    dh.setAccountMoneyList(accountmoneylistStr);
+                }
+                if(dh.getChangeAmount() != null) {
+                    dh.setChangeAmount(roleService.parseBillPriceByLimit(dh.getChangeAmount().abs(), billCategory, priceLimit, request));
+                } else {
+                    dh.setChangeAmount(BigDecimal.ZERO);
+                }
+                if(dh.getTotalPrice() != null) {
+                    dh.setTotalPrice(roleService.parseBillPriceByLimit(dh.getTotalPrice().abs(), billCategory, priceLimit, request));
+                }
+                BigDecimal discountLastMoney = dh.getDiscountLastMoney()!=null?dh.getDiscountLastMoney():BigDecimal.ZERO;
+                dh.setDiscountLastMoney(roleService.parseBillPriceByLimit(discountLastMoney, billCategory, priceLimit, request));
+                BigDecimal backAmount = dh.getBackAmount()!=null?dh.getBackAmount():BigDecimal.ZERO;
+                dh.setBackAmount(roleService.parseBillPriceByLimit(backAmount, billCategory, priceLimit, request));
+                if(dh.getDeposit() == null) {
+                    dh.setDeposit(BigDecimal.ZERO);
+                } else {
+                    dh.setDeposit(roleService.parseBillPriceByLimit(dh.getDeposit(), billCategory, priceLimit, request));
+                }
+                //欠款计算
+                BigDecimal otherMoney = dh.getOtherMoney()!=null?dh.getOtherMoney():BigDecimal.ZERO;
+                BigDecimal deposit = dh.getDeposit()!=null?dh.getDeposit():BigDecimal.ZERO;
+                BigDecimal changeAmount = dh.getChangeAmount()!=null?dh.getChangeAmount():BigDecimal.ZERO;
+                BigDecimal debt = discountLastMoney.add(otherMoney).subtract((deposit.add(changeAmount)));
+                dh.setDebt(roleService.parseBillPriceByLimit(debt, billCategory, priceLimit, request));
+                //是否有付款单或收款单
+                if(financialBillNoMap!=null) {
+                    Integer financialBillNoSize = financialBillNoMap.get(dh.getId());
+                    dh.setHasFinancialFlag(financialBillNoSize!=null && financialBillNoSize>0);
+                }
+                //是否有退款单
+                if(billSizeMap!=null) {
+                    Integer billListSize = billSizeMap.get(dh.getNumber());
+                    dh.setHasBackFlag(billListSize!=null && billListSize>0);
+                }
+                if(StringUtil.isNotEmpty(dh.getSalesMan())) {
+                    dh.setSalesManStr(personService.getPersonByMapAndIds(personMap,dh.getSalesMan()));
+                }
+                if(dh.getOperTime() != null) {
+                    dh.setOperTimeStr(getCenternTime(dh.getOperTime()));
+                }
+                //商品信息简述
+                if(materialsListMap!=null) {
+                    dh.setMaterialsList(materialsListMap.get(dh.getId()));
+                }
+                dh.setCreatorName(userService.getUser(dh.getCreator()).getUsername());
+                resList.add(dh);
+            }
+        }catch(Exception e){
+            JshException.readFail(logger, e);
+        }
+        return resList;
+    }
+
+    /**
+     * 查询除当前单据之外的关联单据列表
+     * @param linkNumber
+     * @param number
+     * @return
+     * @throws Exception
+     */
+    @Override
+    public List<DepotHead> getListByLinkNumberExceptCurrent(String linkNumber, String number, String type)throws Exception {
+        DepotHeadExample example = new DepotHeadExample();
+        example.createCriteria().andLinkNumberEqualTo(linkNumber).andNumberNotEqualTo(number).andTypeEqualTo(type)
+                .andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
+        return depotHeadMapper.selectByExample(example);
+    }
+
+    /**
+     * 查询除当前单据之外的关联单据列表
+     * @param linkApply
+     * @param number
+     * @return
+     * @throws Exception
+     */
+    @Override
+    public List<DepotHead> getListByLinkApplyExceptCurrent(String linkApply, String number, String type)throws Exception {
+        DepotHeadExample example = new DepotHeadExample();
+        example.createCriteria().andLinkApplyEqualTo(linkApply).andNumberNotEqualTo(number).andTypeEqualTo(type)
+                .andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
+        return depotHeadMapper.selectByExample(example);
+    }
+
+    /**
+     * 根据原单号查询关联的单据列表(批量)
+     * @param linkNumberList
+     * @return
+     * @throws Exception
+     */
+    @Override
+    public List<DepotHead> getBillListByLinkNumberList(List<String> linkNumberList)throws Exception {
+        if(linkNumberList!=null && linkNumberList.size()>0) {
+            DepotHeadExample example = new DepotHeadExample();
+            example.createCriteria().andLinkNumberIn(linkNumberList).andSubTypeLike("退货").andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
+            return depotHeadMapper.selectByExample(example);
+        } else {
+            return new ArrayList<>();
+        }
+    }
+
+    /**
+     * 根据原单号查询关联的单据列表
+     * @param linkNumber
+     * @return
+     * @throws Exception
+     */
+    @Override
+    public List<DepotHead> getBillListByLinkNumber(String linkNumber)throws Exception {
+        DepotHeadExample example = new DepotHeadExample();
+        example.createCriteria().andLinkNumberEqualTo(linkNumber).andSubTypeLike("退货").andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
+        return depotHeadMapper.selectByExample(example);
+    }
+
+    /**
+     * 新增单据主表及单据子表信息
+     * @param beanJson
+     * @param rows
+     * @param request
+     * @throws Exception
+     */
+    @Override
+    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
+    public void addDepotHeadAndDetail(String beanJson, String rows,
+                                      HttpServletRequest request) throws Exception {
+        /**处理单据主表数据*/
+        DepotHead depotHead = JSONObject.parseObject(beanJson, DepotHead.class);
+        //校验单号是否重复
+        if(checkIsBillNumberExist(0L, depotHead.getNumber())>0) {
+            throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_BILL_NUMBER_EXIST_CODE,
+                    String.format(ExceptionConstants.DEPOT_HEAD_BILL_NUMBER_EXIST_MSG));
+        }
+        //校验是否同时录入关联请购单号和关联订单号
+        if(StringUtil.isNotEmpty(depotHead.getLinkNumber()) && StringUtil.isNotEmpty(depotHead.getLinkApply())) {
+            throw new BusinessRunTimeException(ExceptionConstants.DEPOT_ITEM_EXIST_REPEAT_NO_FAILED_CODE,
+                    String.format(ExceptionConstants.DEPOT_ITEM_EXIST_REPEAT_NO_FAILED_MSG));
+        }
+        String subType = depotHead.getSubType();
+        //结算账户校验
+        if("采购".equals(subType) || "采购退货".equals(subType) || "销售".equals(subType) || "销售退货".equals(subType)) {
+            if (StringUtil.isEmpty(depotHead.getAccountIdList()) && depotHead.getAccountId() == null) {
+                throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_ACCOUNT_FAILED_CODE,
+                        String.format(ExceptionConstants.DEPOT_HEAD_ACCOUNT_FAILED_MSG));
+            }
+        }
+        //判断用户是否已经登录过,登录过不再处理
+        User userInfo=userService.getCurrentUser();
+        depotHead.setCreator(userInfo==null?null:userInfo.getId());
+        depotHead.setCreateTime(new Timestamp(System.currentTimeMillis()));
+        if(StringUtil.isEmpty(depotHead.getStatus())) {
+            depotHead.setStatus(BusinessConstants.BILLS_STATUS_UN_AUDIT);
+        }
+        depotHead.setPurchaseStatus(BusinessConstants.BILLS_STATUS_UN_AUDIT);
+        depotHead.setPayType(depotHead.getPayType()==null?"现付":depotHead.getPayType());
+        if(StringUtil.isNotEmpty(depotHead.getAccountIdList())){
+            depotHead.setAccountIdList(depotHead.getAccountIdList().replace("[", "").replace("]", "").replaceAll("\"", ""));
+        }
+        if(StringUtil.isNotEmpty(depotHead.getAccountMoneyList())) {
+            //校验多账户的结算金额
+            String accountMoneyList = depotHead.getAccountMoneyList().replace("[", "").replace("]", "").replaceAll("\"", "");
+            BigDecimal sum = StringUtil.getArrSum(accountMoneyList.split(","));
+            BigDecimal manyAccountSum = sum.abs();
+            if(manyAccountSum.compareTo(depotHead.getChangeAmount().abs())!=0) {
+                throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_MANY_ACCOUNT_FAILED_CODE,
+                        String.format(ExceptionConstants.DEPOT_HEAD_MANY_ACCOUNT_FAILED_MSG));
+            }
+            depotHead.setAccountMoneyList(accountMoneyList);
+        }
+        //校验累计扣除订金是否超出订单中的金额
+        if(depotHead.getDeposit()!=null && StringUtil.isNotEmpty(depotHead.getLinkNumber())) {
+            BigDecimal finishDeposit = depotHeadMapperEx.getFinishDepositByNumberExceptCurrent(depotHead.getLinkNumber(), depotHead.getNumber());
+            //订单中的订金金额
+            BigDecimal changeAmount = getDepotHead(depotHead.getLinkNumber()).getChangeAmount();
+            if(changeAmount!=null) {
+                BigDecimal preDeposit = changeAmount.abs();
+                if(depotHead.getDeposit().add(finishDeposit).compareTo(preDeposit)>0) {
+                    throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_DEPOSIT_OVER_PRE_CODE,
+                            String.format(ExceptionConstants.DEPOT_HEAD_DEPOSIT_OVER_PRE_MSG));
+                }
+            }
+        }
+        //校验附件的数量
+        if(StringUtil.isNotEmpty(depotHead.getFileName())) {
+            String[] fileArr = depotHead.getFileName().split(",");
+            if(fileArr.length>4) {
+                throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_FILE_NUM_LIMIT_CODE,
+                        String.format(ExceptionConstants.DEPOT_HEAD_FILE_NUM_LIMIT_MSG, 4));
+            }
+        }
+        //添加主表
+        depotHeadMapper.insertSelective(depotHead);
+        /**入库和出库处理预付款信息*/
+        if(BusinessConstants.PAY_TYPE_PREPAID.equals(depotHead.getPayType())){
+            if(depotHead.getOrganId()!=null) {
+                BigDecimal currentAdvanceIn = supplierService.getSupplier(depotHead.getOrganId()).getAdvanceIn();
+                if(currentAdvanceIn.compareTo(depotHead.getTotalPrice())>=0) {
+                    //更新会员的预付款
+                    supplierService.updateAdvanceIn(depotHead.getOrganId());
+                } else {
+                    throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_MEMBER_PAY_LACK_CODE,
+                            String.format(ExceptionConstants.DEPOT_HEAD_MEMBER_PAY_LACK_MSG));
+                }
+            }
+        }
+        //根据单据编号查询单据id
+        DepotHeadExample dhExample = new DepotHeadExample();
+        dhExample.createCriteria().andNumberEqualTo(depotHead.getNumber()).andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
+        List<DepotHead> list = depotHeadMapper.selectByExample(dhExample);
+        if(list!=null) {
+            Long headId = list.get(0).getId();
+            /**入库和出库处理单据子表信息*/
+            depotItemService.saveDetials(rows,headId, "add",request);
+        }
+        logService.insertLog("单据",
+                new StringBuffer(BusinessConstants.LOG_OPERATION_TYPE_ADD).append(depotHead.getNumber()).toString(),
+                ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest());
+    }
+
+    /**
+     * 更新单据主表及单据子表信息
+     * @param beanJson
+     * @param rows
+     * @param request
+     * @throws Exception
+     */
+    @Override
+    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
+    public void updateDepotHeadAndDetail(String beanJson, String rows, HttpServletRequest request)throws Exception {
+        /**更新单据主表信息*/
+        DepotHead depotHead = JSONObject.parseObject(beanJson, DepotHead.class);
+        //校验单号是否重复
+        if(checkIsBillNumberExist(depotHead.getId(), depotHead.getNumber())>0) {
+            throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_BILL_NUMBER_EXIST_CODE,
+                    String.format(ExceptionConstants.DEPOT_HEAD_BILL_NUMBER_EXIST_MSG));
+        }
+        //校验是否同时录入关联请购单号和关联订单号
+        if(StringUtil.isNotEmpty(depotHead.getLinkNumber()) && StringUtil.isNotEmpty(depotHead.getLinkApply())) {
+            throw new BusinessRunTimeException(ExceptionConstants.DEPOT_ITEM_EXIST_REPEAT_NO_FAILED_CODE,
+                    String.format(ExceptionConstants.DEPOT_ITEM_EXIST_REPEAT_NO_FAILED_MSG));
+        }
+        //校验单据状态,如果不是未审核则提示
+        if(!"0".equals(getDepotHead(depotHead.getId()).getStatus())) {
+            throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_BILL_CANNOT_EDIT_CODE,
+                    String.format(ExceptionConstants.DEPOT_HEAD_BILL_CANNOT_EDIT_MSG));
+        }
+        //获取之前的会员id
+        Long preOrganId = getDepotHead(depotHead.getId()).getOrganId();
+        String subType = depotHead.getSubType();
+        //结算账户校验
+        if("采购".equals(subType) || "采购退货".equals(subType) || "销售".equals(subType) || "销售退货".equals(subType)) {
+            if (StringUtil.isEmpty(depotHead.getAccountIdList()) && depotHead.getAccountId() == null) {
+                throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_ACCOUNT_FAILED_CODE,
+                        String.format(ExceptionConstants.DEPOT_HEAD_ACCOUNT_FAILED_MSG));
+            }
+        }
+        if(StringUtil.isNotEmpty(depotHead.getAccountIdList())){
+            depotHead.setAccountIdList(depotHead.getAccountIdList().replace("[", "").replace("]", "").replaceAll("\"", ""));
+        }
+        if(StringUtil.isNotEmpty(depotHead.getAccountMoneyList())) {
+            //校验多账户的结算金额
+            String accountMoneyList = depotHead.getAccountMoneyList().replace("[", "").replace("]", "").replaceAll("\"", "");
+            BigDecimal sum = StringUtil.getArrSum(accountMoneyList.split(","));
+            BigDecimal manyAccountSum = sum.abs();
+            if(manyAccountSum.compareTo(depotHead.getChangeAmount().abs())!=0) {
+                throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_MANY_ACCOUNT_FAILED_CODE,
+                        String.format(ExceptionConstants.DEPOT_HEAD_MANY_ACCOUNT_FAILED_MSG));
+            }
+            depotHead.setAccountMoneyList(accountMoneyList);
+        }
+        //校验累计扣除订金是否超出订单中的金额
+        if(depotHead.getDeposit()!=null && StringUtil.isNotEmpty(depotHead.getLinkNumber())) {
+            BigDecimal finishDeposit = depotHeadMapperEx.getFinishDepositByNumberExceptCurrent(depotHead.getLinkNumber(), depotHead.getNumber());
+            //订单中的订金金额
+            BigDecimal changeAmount = getDepotHead(depotHead.getLinkNumber()).getChangeAmount();
+            if(changeAmount!=null) {
+                BigDecimal preDeposit = changeAmount.abs();
+                if(depotHead.getDeposit().add(finishDeposit).compareTo(preDeposit)>0) {
+                    throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_DEPOSIT_OVER_PRE_CODE,
+                            String.format(ExceptionConstants.DEPOT_HEAD_DEPOSIT_OVER_PRE_MSG));
+                }
+            }
+        }
+        //校验附件的数量
+        if(StringUtil.isNotEmpty(depotHead.getFileName())) {
+            String[] fileArr = depotHead.getFileName().split(",");
+            if(fileArr.length>4) {
+                throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_FILE_NUM_LIMIT_CODE,
+                        String.format(ExceptionConstants.DEPOT_HEAD_FILE_NUM_LIMIT_MSG, 4));
+            }
+        }
+        //修改单据主表
+        depotHeadMapper.updateByPrimaryKeySelective(depotHead);
+        //如果存在多账户结算需要将原账户的id置空
+        if(StringUtil.isNotEmpty(depotHead.getAccountIdList())) {
+            depotHeadMapperEx.setAccountIdToNull(depotHead.getId());
+        }
+        /**入库和出库处理预付款信息*/
+        if(BusinessConstants.PAY_TYPE_PREPAID.equals(depotHead.getPayType())){
+            if(depotHead.getOrganId()!=null){
+                BigDecimal currentAdvanceIn = supplierService.getSupplier(depotHead.getOrganId()).getAdvanceIn();
+                if(currentAdvanceIn.compareTo(depotHead.getTotalPrice())>=0) {
+                    //更新会员的预付款
+                    supplierService.updateAdvanceIn(depotHead.getOrganId());
+                    if(null != preOrganId && !preOrganId.equals(depotHead.getOrganId())) {
+                        //更新之前会员的预付款
+                        supplierService.updateAdvanceIn(preOrganId);
+                    }
+                } else {
+                    throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_MEMBER_PAY_LACK_CODE,
+                            String.format(ExceptionConstants.DEPOT_HEAD_MEMBER_PAY_LACK_MSG));
+                }
+            }
+        }
+        /**入库和出库处理单据子表信息*/
+        depotItemService.saveDetials(rows,depotHead.getId(), "update",request);
+        logService.insertLog("单据",
+                new StringBuffer(BusinessConstants.LOG_OPERATION_TYPE_EDIT).append(depotHead.getNumber()).toString(),
+                ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest());
+    }
+
+    @Override
+    public Map<String, Object> getBuyAndSaleStatistics(String today, String monthFirstDay, String yesterdayBegin, String yesterdayEnd,
+                                                       String yearBegin, String yearEnd, HttpServletRequest request) throws Exception {
+        Long userId = userService.getUserId(request);
+        String priceLimit = userService.getRoleTypeByUserId(userId).getPriceLimit();
+        Boolean forceFlag = systemConfigService.getForceApprovalFlag();
+        String[] creatorArray = getCreatorArray();
+        List<InOutPriceVo> inOutPriceVoList = depotHeadMapperEx.getBuyAndSaleStatisticsList(yearBegin, yearEnd, creatorArray, forceFlag);
+
+        String[] periods = {"today", "month", "yesterday", "year"};
+        String[] types = {"Buy", "BuyBack", "Sale", "SaleBack", "RetailSale", "RetailSaleBack"};
+
+        Map<String, BigDecimal> statistics = new HashMap<>();
+
+        // 初始化 statistics Map
+        for (String period : periods) {
+            for (String type : types) {
+                statistics.put(period + type, BigDecimal.ZERO);
+            }
+        }
+
+        Date todayDate = Tools.strToDate(today);
+        Date monthFirstDate = Tools.strToDate(monthFirstDay);
+        Date yesterdayStartDate = Tools.strToDate(yesterdayBegin);
+        Date yesterdayEndDate = Tools.strToDate(yesterdayEnd);
+        Date yearStartDate = Tools.strToDate(yearBegin);
+        Date yearEndDate = Tools.strToDate(yearEnd);
+
+        for (InOutPriceVo item : inOutPriceVoList) {
+            Date operTime = item.getOperTime();
+            BigDecimal discountLastMoney = item.getDiscountLastMoney();
+            BigDecimal totalPriceAbs = item.getTotalPrice().abs();
+
+            if (isWithinRange(operTime, todayDate, Tools.strToDate(getNow3()))) {
+                updateStatistics(statistics, item, "today", discountLastMoney, totalPriceAbs);
+            }
+
+            if (isWithinRange(operTime, monthFirstDate, Tools.strToDate(getNow3()))) {
+                updateStatistics(statistics, item, "month", discountLastMoney, totalPriceAbs);
+            }
+
+            if (isWithinRange(operTime, yesterdayStartDate, yesterdayEndDate)) {
+                updateStatistics(statistics, item, "yesterday", discountLastMoney, totalPriceAbs);
+            }
+
+            if (isWithinRange(operTime, yearStartDate, yearEndDate)) {
+                updateStatistics(statistics, item, "year", discountLastMoney, totalPriceAbs);
+            }
+        }
+
+        Map<String, Object> result = new HashMap<>();
+        for (String period : periods) {
+            result.put(period + "Buy", roleService.parseHomePriceByLimit(statistics.get(period + "Buy").subtract(statistics.get(period + "BuyBack")), "buy", priceLimit, "***", request));
+            result.put(period + "Sale", roleService.parseHomePriceByLimit(statistics.get(period + "Sale").subtract(statistics.get(period + "SaleBack")), "sale", priceLimit, "***", request));
+            result.put(period + "RetailSale", roleService.parseHomePriceByLimit(statistics.get(period + "RetailSale").subtract(statistics.get(period + "RetailSaleBack")), "retail", priceLimit, "***", request));
+        }
+
+        return result;
+    }
+
+    private boolean isWithinRange(Date operTime, Date startDate, Date endDate) {
+        return operTime.compareTo(startDate) >= 0 && operTime.compareTo(endDate) <= 0;
+    }
+
+    private void updateStatistics(Map<String, BigDecimal> statistics, InOutPriceVo item, String period, BigDecimal discountLastMoney, BigDecimal totalPriceAbs) {
+        switch (item.getType()) {
+            case "入库":
+                switch (item.getSubType()) {
+                    case "采购":
+                        statistics.put(period + "Buy", statistics.get(period + "Buy").add(discountLastMoney));
+                        break;
+                    case "销售退货":
+                        statistics.put(period + "SaleBack", statistics.get(period + "SaleBack").add(discountLastMoney));
+                        break;
+                    case "零售退货":
+                        statistics.put(period + "RetailSaleBack", statistics.get(period + "RetailSaleBack").add(totalPriceAbs));
+                        break;
+                }
+                break;
+            case "出库":
+                switch (item.getSubType()) {
+                    case "采购退货":
+                        statistics.put(period + "BuyBack", statistics.get(period + "BuyBack").add(discountLastMoney));
+                        break;
+                    case "销售":
+                        statistics.put(period + "Sale", statistics.get(period + "Sale").add(discountLastMoney));
+                        break;
+                    case "零售":
+                        statistics.put(period + "RetailSale", statistics.get(period + "RetailSale").add(totalPriceAbs));
+                        break;
+                }
+                break;
+        }
+    }
+
+
+    @Override
+    public DepotHead getDepotHead(String number)throws Exception {
+        DepotHead depotHead = new DepotHead();
+        try{
+            DepotHeadExample example = new DepotHeadExample();
+            example.createCriteria().andNumberEqualTo(number).andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
+            List<DepotHead> list = depotHeadMapper.selectByExample(example);
+            if(null!=list && list.size()>0) {
+                depotHead = list.get(0);
+            }
+        }catch(Exception e){
+            JshException.readFail(logger, e);
+        }
+        return depotHead;
+    }
+
+    @Override
+    public List<DepotHeadVo4List> debtList(Long organId, String materialParam, String number, String beginTime, String endTime,
+                                           String status, Integer offset, Integer rows) {
+        List<DepotHeadVo4List> resList = new ArrayList<>();
+        try{
+            String depotIds = depotService.findDepotStrByCurrentUser();
+            String [] depotArray=depotIds.split(",");
+            String [] creatorArray = getCreatorArray();
+            beginTime = Tools.parseDayToTime(beginTime,BusinessConstants.DAY_FIRST_TIME);
+            endTime = Tools.parseDayToTime(endTime,BusinessConstants.DAY_LAST_TIME);
+            List<DepotHeadVo4List> list=depotHeadMapperEx.debtList(organId, creatorArray, status, number,
+                    beginTime, endTime, materialParam, depotArray, offset, rows);
+            if (null != list) {
+                resList = parseDebtBillList(list);
+            }
+        }catch(Exception e){
+            JshException.readFail(logger, e);
+        }
+        return resList;
+    }
+
+    @Override
+    public int debtListCount(Long organId, String materialParam, String number, String beginTime, String endTime,
+                             String status) {
+        int total = 0;
+        try {
+            String depotIds = depotService.findDepotStrByCurrentUser();
+            String[] depotArray = depotIds.split(",");
+            String[] creatorArray = getCreatorArray();
+            beginTime = Tools.parseDayToTime(beginTime, BusinessConstants.DAY_FIRST_TIME);
+            endTime = Tools.parseDayToTime(endTime, BusinessConstants.DAY_LAST_TIME);
+            total = depotHeadMapperEx.debtListCount(organId, creatorArray, status, number,
+                    beginTime, endTime, materialParam, depotArray);
+        } catch(Exception e){
+            JshException.readFail(logger, e);
+        }
+        return total;
+    }
+
+    @Override
+    public void debtExport(Long organId, String materialParam, String number, String type, String subType,
+                           String beginTime, String endTime, String status, String mpList,
+                           HttpServletRequest request, HttpServletResponse response) {
+        try {
+            Long userId = userService.getUserId(request);
+            String priceLimit = userService.getRoleTypeByUserId(userId).getPriceLimit();
+            String billCategory = getBillCategory(subType);
+            String depotIds = depotService.findDepotStrByCurrentUser();
+            String[] depotArray = depotIds.split(",");
+            String[] creatorArray = getCreatorArray();
+            status = StringUtil.isNotEmpty(status) ? status : null;
+            beginTime = Tools.parseDayToTime(beginTime, BusinessConstants.DAY_FIRST_TIME);
+            endTime = Tools.parseDayToTime(endTime, BusinessConstants.DAY_LAST_TIME);
+            List<DepotHeadVo4List> dhList = new ArrayList<>();
+            List<DepotHeadVo4List> list = depotHeadMapperEx.debtList(organId, creatorArray, status, number,
+                    beginTime, endTime, materialParam, depotArray, null, null);
+            if (null != list) {
+                dhList = parseDebtBillList(list);
+            }
+            //生成Excel文件
+            String fileName = "单据信息";
+            File file = new File("/opt/"+ fileName);
+            WritableWorkbook wtwb = Workbook.createWorkbook(file);
+            String oneTip = "";
+            String sheetOneStr = "";
+            if("采购".equals(subType)) {
+                oneTip = "供应商对账列表";
+                sheetOneStr = "供应商,单据编号,关联单据,商品信息,单据日期,操作员,单据金额,本单欠款,已付欠款,待付欠款,备注";
+            } else if("出库".equals(type) && "销售".equals(subType)) {
+                oneTip = "客户对账列表";
+                sheetOneStr = "客户,单据编号,关联单据,商品信息,单据日期,操作员,单据金额,本单欠款,已收欠款,待收欠款,备注";
+            }
+            if(StringUtil.isNotEmpty(beginTime) && StringUtil.isNotEmpty(endTime)) {
+                oneTip = oneTip + "(" + beginTime + "至" + endTime + ")";
+            }
+            List<String> sheetOneList = StringUtil.strToStringList(sheetOneStr);
+            String[] sheetOneArr = StringUtil.listToStringArray(sheetOneList);
+            List<Long> idList = new ArrayList<>();
+            List<String[]> billList = new ArrayList<>();
+            Map<Long, BillListCacheVo> billListCacheVoMap = new HashMap<>();
+            for (DepotHeadVo4List dh : dhList) {
+                idList.add(dh.getId());
+                BillListCacheVo billListCacheVo = new BillListCacheVo();
+                billListCacheVo.setNumber(dh.getNumber());
+                billListCacheVo.setOrganName(dh.getOrganName());
+                billListCacheVo.setOperTimeStr(getCenternTime(dh.getOperTime()));
+                billListCacheVoMap.put(dh.getId(), billListCacheVo);
+                String[] objs = new String[sheetOneArr.length];
+                objs[0] = dh.getOrganName();
+                objs[1] = dh.getNumber();
+                objs[2] = dh.getLinkNumber();
+                objs[3] = dh.getMaterialsList();
+                objs[4] = dh.getOperTimeStr();
+                objs[5] = dh.getUserName();
+                BigDecimal discountLastMoney = dh.getDiscountLastMoney() == null ? BigDecimal.ZERO : dh.getDiscountLastMoney();
+                BigDecimal otherMoney = dh.getOtherMoney() == null ? BigDecimal.ZERO : dh.getOtherMoney();
+                BigDecimal deposit = dh.getDeposit() == null ? BigDecimal.ZERO : dh.getDeposit();
+                objs[6] = parseDecimalToStr(discountLastMoney.add(otherMoney).subtract(deposit), 2);
+                objs[7] = parseDecimalToStr(dh.getNeedDebt(), 2);
+                objs[8] = parseDecimalToStr(dh.getFinishDebt(), 2);
+                objs[9] = parseDecimalToStr(dh.getDebt(), 2);
+                objs[10] = dh.getRemark();
+                billList.add(objs);
+            }
+            ExcelUtils.exportObjectsManySheet(wtwb, oneTip, sheetOneArr, "单据列表", 0, billList);
+            //导出明细数据
+            if(idList.size()>0) {
+                List<DepotItemVo4WithInfoEx> dataList = depotItemMapperEx.getBillDetailListByIds(idList);
+                String[] mpArr = mpList.split(",");
+                String twoTip = "";
+                String sheetTwoStr = "";
+                if ("采购".equals(subType)) {
+                    twoTip = "供应商单据明细";
+                    sheetTwoStr = "供应商,单据编号,单据日期,仓库名称,条码,名称,规格,型号,颜色,品牌,制造商,扩展信息,单位,序列号,批号,有效期,多属性,数量,单价,金额,税率(%),税额,价税合计,重量,备注";
+                } else if ("销售".equals(subType)) {
+                    twoTip = "客户单据明细";
+                    sheetTwoStr = "客户,单据编号,单据日期,仓库名称,条码,名称,规格,型号,颜色,品牌,制造商,扩展信息,单位,序列号,批号,有效期,多属性,数量,单价,金额,税率(%),税额,价税合计,重量,备注";
+                }
+                if (StringUtil.isNotEmpty(beginTime) && StringUtil.isNotEmpty(endTime)) {
+                    twoTip = twoTip + "(" + beginTime + "至" + endTime + ")";
+                }
+                List<String> sheetTwoList = StringUtil.strToStringList(sheetTwoStr);
+                String[] sheetTwoArr = StringUtil.listToStringArray(sheetTwoList);
+                List<String[]> billDetail = new ArrayList<>();
+                for (DepotItemVo4WithInfoEx diEx : dataList) {
+                    String[] objs = new String[sheetTwoArr.length];
+                    BillListCacheVo billListCacheVo = billListCacheVoMap.get(diEx.getHeaderId());
+                    objs[0] = billListCacheVo != null ? billListCacheVo.getOrganName() : "";
+                    objs[1] = billListCacheVo != null ? billListCacheVo.getNumber() : "";
+                    objs[2] = billListCacheVo != null ? billListCacheVo.getOperTimeStr() : "";
+                    objs[3] = diEx.getDepotId() == null ? "" : diEx.getDepotName();
+                    objs[4] = diEx.getBarCode();
+                    objs[5] = diEx.getMName();
+                    objs[6] = diEx.getMStandard();
+                    objs[7] = diEx.getMModel();
+                    objs[8] = diEx.getMColor();
+                    objs[9] = diEx.getBrand();
+                    objs[10] = diEx.getMMfrs();
+                    objs[11] = depotItemService.getOtherInfo(mpArr, diEx);
+                    objs[12] = diEx.getMaterialUnit();
+                    objs[13] = diEx.getSnList();
+                    objs[14] = diEx.getBatchNumber();
+                    objs[15] = Tools.parseDateToStr(diEx.getExpirationDate());
+                    objs[16] = diEx.getSku();
+                    objs[17] = parseDecimalToStr(diEx.getOperNumber(), 2);
+                    objs[18] = parseDecimalToStr(roleService.parseBillPriceByLimit(diEx.getUnitPrice(), billCategory, priceLimit, request), 2);
+                    objs[19] = parseDecimalToStr(roleService.parseBillPriceByLimit(diEx.getAllPrice(), billCategory, priceLimit, request), 2);
+                    objs[20] = parseDecimalToStr(roleService.parseBillPriceByLimit(diEx.getTaxRate(), billCategory, priceLimit, request), 2);
+                    objs[21] = parseDecimalToStr(roleService.parseBillPriceByLimit(diEx.getTaxMoney(), billCategory, priceLimit, request), 2);
+                    objs[22] = parseDecimalToStr(roleService.parseBillPriceByLimit(diEx.getTaxLastMoney(), billCategory, priceLimit, request), 2);
+                    BigDecimal allWeight = diEx.getBasicNumber() == null || diEx.getWeight() == null ? BigDecimal.ZERO : diEx.getBasicNumber().multiply(diEx.getWeight());
+                    objs[23] = parseDecimalToStr(allWeight, 2);
+                    objs[24] = diEx.getRemark();
+                    billDetail.add(objs);
+                }
+                ExcelUtils.exportObjectsManySheet(wtwb, twoTip, sheetTwoArr, "单据明细", 1, billDetail);
+            }
+            wtwb.write();
+            wtwb.close();
+            ExcelUtils.downloadExcel(file, file.getName(), response);
+        } catch(Exception e){
+            JshException.readFail(logger, e);
+        }
+    }
+
+    @Override
+    public List<DepotHeadVo4List> parseDebtBillList(List<DepotHeadVo4List> list) throws Exception {
+        List<Long> idList = new ArrayList<>();
+        List<DepotHeadVo4List> dhList = new ArrayList<>();
+        for (DepotHeadVo4List dh : list) {
+            idList.add(dh.getId());
+        }
+        //通过批量查询去构造map
+        Map<Long,String> materialsListMap = findMaterialsListMapByHeaderIdList(idList);
+        for (DepotHeadVo4List dh : list) {
+            if(dh.getChangeAmount() != null) {
+                dh.setChangeAmount(dh.getChangeAmount().abs());
+            }
+            if(dh.getTotalPrice() != null) {
+                dh.setTotalPrice(dh.getTotalPrice().abs());
+            }
+            if(dh.getDeposit() == null) {
+                dh.setDeposit(BigDecimal.ZERO);
+            }
+            if(dh.getOperTime() != null) {
+                dh.setOperTimeStr(getCenternTime(dh.getOperTime()));
+            }
+            BigDecimal discountLastMoney = dh.getDiscountLastMoney()!=null?dh.getDiscountLastMoney():BigDecimal.ZERO;
+            BigDecimal otherMoney = dh.getOtherMoney()!=null?dh.getOtherMoney():BigDecimal.ZERO;
+            BigDecimal deposit = dh.getDeposit()!=null?dh.getDeposit():BigDecimal.ZERO;
+            BigDecimal changeAmount = dh.getChangeAmount()!=null?dh.getChangeAmount().abs():BigDecimal.ZERO;
+            //本单欠款(如果退货则为负数)
+            dh.setNeedDebt(discountLastMoney.add(otherMoney).subtract(deposit.add(changeAmount)));
+            if(BusinessConstants.SUB_TYPE_PURCHASE_RETURN.equals(dh.getSubType()) || BusinessConstants.SUB_TYPE_SALES_RETURN.equals(dh.getSubType())) {
+                dh.setNeedDebt(BigDecimal.ZERO.subtract(dh.getNeedDebt()));
+            }
+            BigDecimal needDebt = dh.getNeedDebt()!=null?dh.getNeedDebt():BigDecimal.ZERO;
+            BigDecimal finishDebt = accountItemService.getEachAmountByBillId(dh.getId());
+            finishDebt = finishDebt!=null?finishDebt:BigDecimal.ZERO;
+            //已收欠款
+            dh.setFinishDebt(finishDebt);
+            //待收欠款
+            dh.setDebt(needDebt.subtract(finishDebt));
+            //商品信息简述
+            if(materialsListMap!=null) {
+                dh.setMaterialsList(materialsListMap.get(dh.getId()));
+            }
+            dhList.add(dh);
+        }
+        return dhList;
+    }
+
+    @Override
+    public String getBillCategory(String subType) {
+        if(subType.equals("零售") || subType.equals("零售退货")) {
+            return "retail";
+        } else if(subType.equals("销售订单") || subType.equals("销售") || subType.equals("销售退货")) {
+            return "sale";
+        } else {
+            return "buy";
+        }
+    }
+
+    /**
+     * 格式化金额样式
+     * @param decimal
+     * @param num
+     * @return
+     */
+    private String parseDecimalToStr(BigDecimal decimal, Integer num) {
+        return decimal == null ? "" : decimal.setScale(num, BigDecimal.ROUND_HALF_UP).toString();
+    }
+
+    private String parseStatusToStr(String status, String type) {
+        if(StringUtil.isNotEmpty(status)) {
+            if("purchase".equals(type)) {
+                switch (status) {
+                    case "2":
+                        return "完成采购";
+                    case "3":
+                        return "部分采购";
+                }
+            } else if("sale".equals(type)) {
+                switch (status) {
+                    case "2":
+                        return "完成销售";
+                    case "3":
+                        return "部分销售";
+                }
+            }
+            switch (status) {
+                case "0":
+                    return "未审核";
+                case "1":
+                    return "已审核";
+                case "9":
+                    return "审核中";
+            }
+        }
+        return "";
+    }
+
+    @Override
+    public List<DepotHeadVo4List> waitBillList(String number, String materialParam, String type, String subType,
+                                               String beginTime, String endTime, String status, int offset, int rows) {
+        List<DepotHeadVo4List> resList = new ArrayList<>();
+        try{
+            String [] depotArray = getDepotArray("其它");
+            //给仓管可以看全部的单据(此时可以通过分配仓库去控制权限)
+            String [] creatorArray = null;
+            String [] subTypeArray = StringUtil.isNotEmpty(subType) ? subType.split(",") : null;
+            String [] statusArray = StringUtil.isNotEmpty(status) ? status.split(",") : null;
+            Map<Long,String> accountMap = accountService.getAccountMap();
+            beginTime = Tools.parseDayToTime(beginTime,BusinessConstants.DAY_FIRST_TIME);
+            endTime = Tools.parseDayToTime(endTime,BusinessConstants.DAY_LAST_TIME);
+            List<DepotHeadVo4List> list = depotHeadMapperEx.waitBillList(type, subTypeArray, creatorArray, statusArray, number, beginTime, endTime,
+                    materialParam, depotArray, offset, rows);
+            if (null != list) {
+                List<Long> idList = new ArrayList<>();
+                for (DepotHeadVo4List dh : list) {
+                    idList.add(dh.getId());
+                }
+                //通过批量查询去构造map
+                Map<Long,String> materialsListMap = findMaterialsListMapByHeaderIdList(idList);
+                Map<Long,BigDecimal> materialCountListMap = getMaterialCountListMapByHeaderIdList(idList);
+                for (DepotHeadVo4List dh : list) {
+                    if(accountMap!=null && StringUtil.isNotEmpty(dh.getAccountIdList()) && StringUtil.isNotEmpty(dh.getAccountMoneyList())) {
+                        String accountStr = accountService.getAccountStrByIdAndMoney(accountMap, dh.getAccountIdList(), dh.getAccountMoneyList());
+                        dh.setAccountName(accountStr);
+                    }
+                    if(dh.getOperTime() != null) {
+                        dh.setOperTimeStr(getCenternTime(dh.getOperTime()));
+                    }
+                    //商品信息简述
+                    if(materialsListMap!=null) {
+                        dh.setMaterialsList(materialsListMap.get(dh.getId()));
+                    }
+                    //商品总数量
+                    if(materialCountListMap!=null) {
+                        dh.setMaterialCount(materialCountListMap.get(dh.getId()));
+                    }
+                    resList.add(dh);
+                }
+            }
+        }catch(Exception e){
+            JshException.readFail(logger, e);
+        }
+        return resList;
+    }
+
+    @Override
+    public Long waitBillCount(String number, String materialParam, String type, String subType,
+                              String beginTime, String endTime, String status) {
+        Long result=null;
+        try{
+            String [] depotArray = getDepotArray("其它");
+            //给仓管可以看全部的单据(此时可以通过分配仓库去控制权限)
+            String [] creatorArray = null;
+            String [] subTypeArray = StringUtil.isNotEmpty(subType) ? subType.split(",") : null;
+            String [] statusArray = StringUtil.isNotEmpty(status) ? status.split(",") : null;
+            beginTime = Tools.parseDayToTime(beginTime,BusinessConstants.DAY_FIRST_TIME);
+            endTime = Tools.parseDayToTime(endTime,BusinessConstants.DAY_LAST_TIME);
+            result=depotHeadMapperEx.waitBillCount(type, subTypeArray, creatorArray, statusArray, number, beginTime, endTime,
+                    materialParam, depotArray);
+        }catch(Exception e){
+            JshException.readFail(logger, e);
+        }
+        return result;
+    }
+
+    @Override
+    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
+    public void batchAddDepotHeadAndDetail(String ids, HttpServletRequest request) throws Exception {
+        List<DepotHead> dhList = getDepotHeadListByIds(ids);
+        StringBuilder sb = new StringBuilder();
+        User userInfo=userService.getCurrentUser();
+        for(DepotHead depotHead : dhList) {
+            String prefixNo = BusinessConstants.DEPOTHEAD_TYPE_IN.equals(depotHead.getType())?"QTRK":"QTCK";
+            //关联单据单号
+            String oldNumber = depotHead.getNumber();
+            //校验单据最新状态不能进行批量操作
+            if("0".equals(depotHead.getStatus()) || "2".equals(depotHead.getStatus()) || "9".equals(depotHead.getStatus())) {
+                throw new BusinessRunTimeException(ExceptionConstants.DEPOT_ITEM_EXIST_NEW_STATUS_FAILED_CODE,
+                        String.format(ExceptionConstants.DEPOT_ITEM_EXIST_NEW_STATUS_FAILED_MSG, oldNumber, depotHead.getType()));
+            }
+            //校验是否是部分入库或者部分出库
+            if("3".equals(depotHead.getStatus())) {
+                throw new BusinessRunTimeException(ExceptionConstants.DEPOT_ITEM_EXIST_PARTIALLY_STATUS_FAILED_CODE,
+                        String.format(ExceptionConstants.DEPOT_ITEM_EXIST_PARTIALLY_STATUS_FAILED_MSG, oldNumber, depotHead.getType()));
+            }
+            depotHead.setLinkNumber(oldNumber);
+            //给单号重新赋值
+            String number = prefixNo + sequenceService.buildOnlyNumber();
+            depotHead.setNumber(number);
+            depotHead.setDefaultNumber(number);
+            depotHead.setOperTime(new Date());
+            depotHead.setSubType(BusinessConstants.SUB_TYPE_OTHER);
+            depotHead.setChangeAmount(BigDecimal.ZERO);
+            depotHead.setTotalPrice(BigDecimal.ZERO);
+            depotHead.setDiscountLastMoney(BigDecimal.ZERO);
+            depotHead.setCreator(userInfo==null?null:userInfo.getId());
+            depotHead.setOrganId(null);
+            depotHead.setAccountId(null);
+            depotHead.setAccountIdList(null);
+            depotHead.setAccountMoneyList(null);
+            depotHead.setFileName(null);
+            depotHead.setSalesMan(null);
+            depotHead.setStatus("0");
+            depotHead.setTenantId(null);
+            //查询明细
+            List<DepotItemVo4WithInfoEx> itemList = depotItemService.getDetailList(depotHead.getId());
+            depotHead.setId(null);
+            JSONArray rowArr = new JSONArray();
+            for(DepotItemVo4WithInfoEx item: itemList) {
+                if("1".equals(item.getEnableSerialNumber())) {
+                    throw new BusinessRunTimeException(ExceptionConstants.DEPOT_ITEM_EXIST_SERIAL_NUMBER_FAILED_CODE,
+                            String.format(ExceptionConstants.DEPOT_ITEM_EXIST_SERIAL_NUMBER_FAILED_MSG, oldNumber));
+                }
+                if("1".equals(item.getEnableBatchNumber())) {
+                    throw new BusinessRunTimeException(ExceptionConstants.DEPOT_ITEM_EXIST_BATCH_NUMBER_FAILED_CODE,
+                            String.format(ExceptionConstants.DEPOT_ITEM_EXIST_BATCH_NUMBER_FAILED_MSG, oldNumber));
+                }
+                item.setUnitPrice(BigDecimal.ZERO);
+                item.setAllPrice(BigDecimal.ZERO);
+                item.setLinkId(item.getId());
+                item.setTenantId(null);
+                String itemStr = JSONObject.toJSONString(item);
+                JSONObject itemObj = JSONObject.parseObject(itemStr);
+                itemObj.put("unit", itemObj.getString("materialUnit"));
+                rowArr.add(itemObj.toJSONString());
+            }
+            String rows = rowArr.toJSONString();
+            //新增其它入库单或其它出库单
+            sb.append("[").append(depotHead.getNumber()).append("]");
+            depotHeadMapper.insertSelective(depotHead);
+            //根据单据编号查询单据id
+            DepotHeadExample dhExample = new DepotHeadExample();
+            dhExample.createCriteria().andNumberEqualTo(depotHead.getNumber()).andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
+            List<DepotHead> list = depotHeadMapper.selectByExample(dhExample);
+            if(list!=null) {
+                Long headId = list.get(0).getId();
+                /**入库和出库处理单据子表信息*/
+                depotItemService.saveDetials(rows, headId, "add", request);
+            }
+        }
+        logService.insertLog("单据",
+                new StringBuffer(BusinessConstants.LOG_OPERATION_TYPE_BATCH_ADD).append(sb).toString(),
+                ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest());
+    }
+}

+ 1498 - 0
src/main/java/com/jsh/erp/service/impl/DepotItemServiceImpl.java

@@ -0,0 +1,1498 @@
+package com.jsh.erp.service.impl;
+
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
+import com.jsh.erp.constants.BusinessConstants;
+import com.jsh.erp.constants.ExceptionConstants;
+import com.jsh.erp.datasource.entities.*;
+import com.jsh.erp.datasource.mappers.*;
+import com.jsh.erp.datasource.vo.DepotItemStockWarningCount;
+import com.jsh.erp.datasource.vo.DepotItemVo4Stock;
+import com.jsh.erp.datasource.vo.DepotItemVoBatchNumberList;
+import com.jsh.erp.datasource.vo.InOutPriceVo;
+import com.jsh.erp.exception.BusinessRunTimeException;
+import com.jsh.erp.exception.JshException;
+import com.jsh.erp.service.*;
+import com.jsh.erp.utils.StringUtil;
+import com.jsh.erp.utils.Tools;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.springframework.stereotype.Service;
+import org.springframework.transaction.annotation.Transactional;
+
+import javax.annotation.Resource;
+import javax.servlet.http.HttpServletRequest;
+import java.math.BigDecimal;
+import java.util.*;
+
+@Service
+public class DepotItemServiceImpl extends ServiceImpl<DepotItemMapper, DepotItem> implements DepotItemService {
+    private Logger logger = LoggerFactory.getLogger(DepotItemServiceImpl.class);
+
+    private final static String TYPE = "入库";
+    private final static String SUM_TYPE = "number";
+    private final static String IN = "in";
+    private final static String OUT = "out";
+
+    @Resource
+    private DepotItemMapper depotItemMapper;
+    @Resource
+    private DepotItemMapperEx depotItemMapperEx;
+    @Resource
+    private MaterialService materialService;
+    @Resource
+    private MaterialExtendService materialExtendService;
+    @Resource
+    private SerialNumberMapperEx serialNumberMapperEx;
+    @Resource
+    private DepotHeadService depotHeadService;
+    @Resource
+    private DepotHeadMapper depotHeadMapper;
+    @Resource
+    private SerialNumberService serialNumberService;
+    @Resource
+    private UserService userService;
+    @Resource
+    private SystemConfigService systemConfigService;
+    @Resource
+    private DepotService depotService;
+    @Resource
+    private UnitService unitService;
+    @Resource
+    private MaterialCurrentStockMapper materialCurrentStockMapper;
+    @Resource
+    private MaterialCurrentStockMapperEx materialCurrentStockMapperEx;
+    @Resource
+    private LogService logService;
+
+    @Override
+    public DepotItem getDepotItem(long id)throws Exception {
+        DepotItem result=null;
+        try{
+            result=depotItemMapper.selectByPrimaryKey(id);
+        }catch(Exception e){
+            JshException.readFail(logger, e);
+        }
+        return result;
+    }
+
+    @Override
+    public List<DepotItem> getDepotItem()throws Exception {
+        DepotItemExample example = new DepotItemExample();
+        example.createCriteria().andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
+        List<DepotItem> list=null;
+        try{
+            list=depotItemMapper.selectByExample(example);
+        }catch(Exception e){
+            JshException.readFail(logger, e);
+        }
+        return list;
+    }
+
+    @Override
+    public List<DepotItem> select(String name, Integer type, String remark, int offset, int rows)throws Exception {
+        List<DepotItem> list=null;
+        try{
+            list=depotItemMapperEx.selectByConditionDepotItem(name, type, remark, offset, rows);
+        }catch(Exception e){
+            JshException.readFail(logger, e);
+        }
+        return list;
+    }
+
+    @Override
+    public Long countDepotItem(String name, Integer type, String remark) throws Exception{
+        Long result =null;
+        try{
+            result=depotItemMapperEx.countsByDepotItem(name, type, remark);
+        }catch(Exception e){
+            JshException.readFail(logger, e);
+        }
+        return result;
+    }
+
+    @Override
+    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
+    public int insertDepotItem(JSONObject obj, HttpServletRequest request)throws Exception {
+        DepotItem depotItem = JSONObject.parseObject(obj.toJSONString(), DepotItem.class);
+        int result =0;
+        try{
+            result=depotItemMapper.insertSelective(depotItem);
+        }catch(Exception e){
+            JshException.readFail(logger, e);
+        }
+        return result;
+    }
+
+    @Override
+    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
+    public int updateDepotItem(JSONObject obj, HttpServletRequest request)throws Exception {
+        DepotItem depotItem = JSONObject.parseObject(obj.toJSONString(), DepotItem.class);
+        int result =0;
+        try{
+            result=depotItemMapper.updateByPrimaryKeySelective(depotItem);
+        }catch(Exception e){
+            JshException.readFail(logger, e);
+        }
+        return result;
+    }
+
+    @Override
+    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
+    public int deleteDepotItem(Long id, HttpServletRequest request)throws Exception {
+        int result =0;
+        try{
+            result=depotItemMapper.deleteByPrimaryKey(id);
+        }catch(Exception e){
+            JshException.writeFail(logger, e);
+        }
+        return result;
+    }
+
+    @Override
+    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
+    public int batchDeleteDepotItem(String ids, HttpServletRequest request)throws Exception {
+        List<Long> idList = StringUtil.strToLongList(ids);
+        DepotItemExample example = new DepotItemExample();
+        example.createCriteria().andIdIn(idList);
+        int result =0;
+        try{
+            result=depotItemMapper.deleteByExample(example);
+        }catch(Exception e){
+            JshException.writeFail(logger, e);
+        }
+        return result;
+    }
+
+    @Override
+    public int checkIsNameExist(Long id, String name)throws Exception {
+        DepotItemExample example = new DepotItemExample();
+        example.createCriteria().andIdNotEqualTo(id).andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
+        List<DepotItem> list =null;
+        try{
+            list=depotItemMapper.selectByExample(example);
+        }catch(Exception e){
+            JshException.readFail(logger, e);
+        }
+        return list==null?0:list.size();
+    }
+
+    @Override
+    public List<DepotItemVo4DetailByTypeAndMId> findDetailByDepotIdsAndMaterialIdList(String depotIds, Boolean forceFlag, Boolean inOutManageFlag, String sku, String batchNumber,
+                                                                                      String number, String beginTime, String endTime, Long mId, Integer offset, Integer rows)throws Exception {
+        Long depotId = null;
+        if(StringUtil.isNotEmpty(depotIds)) {
+            depotId = Long.parseLong(depotIds);
+        }
+        List<Long> depotList = depotService.parseDepotList(depotId);
+        Long[] depotIdArray = StringUtil.listToLongArray(depotList);
+        List<DepotItemVo4DetailByTypeAndMId> list =null;
+        try{
+            list = depotItemMapperEx.findDetailByDepotIdsAndMaterialIdList(depotIdArray, forceFlag, inOutManageFlag, sku, batchNumber, number, beginTime, endTime, mId, offset, rows);
+        }catch(Exception e){
+            JshException.readFail(logger, e);
+        }
+        return list;
+    }
+
+    @Override
+    public Long findDetailByDepotIdsAndMaterialIdCount(String depotIds, Boolean forceFlag, Boolean inOutManageFlag, String sku, String batchNumber,
+                                                       String number, String beginTime, String endTime, Long mId)throws Exception {
+        Long depotId = null;
+        if(StringUtil.isNotEmpty(depotIds)) {
+            depotId = Long.parseLong(depotIds);
+        }
+        List<Long> depotList = depotService.parseDepotList(depotId);
+        Long[] depotIdArray = StringUtil.listToLongArray(depotList);
+        Long result =null;
+        try{
+            result = depotItemMapperEx.findDetailByDepotIdsAndMaterialIdCount(depotIdArray, forceFlag, inOutManageFlag, sku, batchNumber, number, beginTime, endTime, mId);
+        }catch(Exception e){
+            JshException.readFail(logger, e);
+        }
+        return result;
+    }
+
+    @Override
+    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
+    public int insertDepotItemWithObj(DepotItem depotItem)throws Exception {
+        int result =0;
+        try{
+            result = depotItemMapper.insertSelective(depotItem);
+        }catch(Exception e){
+            JshException.writeFail(logger, e);
+        }
+        return result;
+    }
+
+    @Override
+    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
+    public int updateDepotItemWithObj(DepotItem depotItem)throws Exception {
+        int result =0;
+        try{
+            result = depotItemMapper.updateByPrimaryKeySelective(depotItem);
+        }catch(Exception e){
+            JshException.writeFail(logger, e);
+        }
+        return result;
+    }
+
+    @Override
+    public List<DepotItem> getListByHeaderId(Long headerId)throws Exception {
+        List<DepotItem> list =null;
+        try{
+            DepotItemExample example = new DepotItemExample();
+            example.createCriteria().andHeaderIdEqualTo(headerId).andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
+            list = depotItemMapper.selectByExample(example);
+        }catch(Exception e){
+            JshException.readFail(logger, e);
+        }
+        return list;
+    }
+
+    /**
+     * 查询当前单据中指定商品的明细信息
+     * @param headerId
+     * @param meId
+     * @return
+     * @throws Exception
+     */
+    @Override
+    public DepotItem getItemByHeaderIdAndMaterial(Long headerId, Long meId)throws Exception {
+        DepotItem depotItem = new DepotItem();
+        try{
+            DepotItemExample example = new DepotItemExample();
+            example.createCriteria().andHeaderIdEqualTo(headerId).andMaterialExtendIdEqualTo(meId).andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
+            List<DepotItem> list = depotItemMapper.selectByExample(example);
+            if(list!=null && list.size()>0) {
+                depotItem = list.get(0);
+            }
+        }catch(Exception e){
+            JshException.readFail(logger, e);
+        }
+        return depotItem;
+    }
+
+    /**
+     * 查询被关联订单中指定商品的明细信息
+     * @param linkStr
+     * @param meId
+     * @return
+     * @throws Exception
+     */
+    @Override
+    public DepotItem getPreItemByHeaderIdAndMaterial(String linkStr, Long meId, Long linkId)throws Exception {
+        DepotItem depotItem = new DepotItem();
+        try{
+            DepotHead depotHead = depotHeadService.getDepotHead(linkStr);
+            if(null!=depotHead && null!=depotHead.getId()) {
+                DepotItemExample example = new DepotItemExample();
+                example.createCriteria().andHeaderIdEqualTo(depotHead.getId()).andMaterialExtendIdEqualTo(meId).andIdEqualTo(linkId).andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
+                List<DepotItem> list = depotItemMapper.selectByExample(example);
+                if(list!=null && list.size()>0) {
+                    depotItem = list.get(0);
+                }
+            }
+        }catch(Exception e){
+            JshException.readFail(logger, e);
+        }
+        return depotItem;
+    }
+
+    @Override
+    public List<DepotItemVo4WithInfoEx> getDetailList(Long headerId)throws Exception {
+        List<DepotItemVo4WithInfoEx> list =null;
+        try{
+            list = depotItemMapperEx.getDetailList(headerId);
+        }catch(Exception e){
+            JshException.readFail(logger, e);
+        }
+        return list;
+    }
+
+    @Override
+    public List<DepotItemVo4WithInfoEx> getInOutStock(String materialParam, List<Long> categoryIdList, String endTime, Integer offset, Integer rows)throws Exception {
+        List<DepotItemVo4WithInfoEx> list =null;
+        try{
+            list = depotItemMapperEx.getInOutStock(materialParam, categoryIdList, endTime, offset, rows);
+        }catch(Exception e){
+            JshException.readFail(logger, e);
+        }
+        return list;
+    }
+
+    @Override
+    public int getInOutStockCount(String materialParam, List<Long> categoryIdList, String endTime)throws Exception {
+        int result=0;
+        try{
+            result = depotItemMapperEx.getInOutStockCount(materialParam, categoryIdList, endTime);
+        }catch(Exception e){
+            JshException.readFail(logger, e);
+        }
+        return result;
+    }
+
+    @Override
+    public List<DepotItemVo4WithInfoEx> getListWithBuyOrSale(String materialParam, String billType,
+                                                             String beginTime, String endTime, String[] creatorArray, Long organId, String[] organArray, List<Long> categoryList, List<Long> depotList, Boolean forceFlag, Integer offset, Integer rows)throws Exception {
+        List<DepotItemVo4WithInfoEx> list =null;
+        try{
+            list = depotItemMapperEx.getListWithBuyOrSale(materialParam, billType, beginTime, endTime, creatorArray, organId, organArray, categoryList, depotList, forceFlag, offset, rows);
+        }catch(Exception e){
+            JshException.readFail(logger, e);
+        }
+        return list;
+    }
+
+    @Override
+    public int getListWithBuyOrSaleCount(String materialParam, String billType,
+                                         String beginTime, String endTime, String[] creatorArray, Long organId, String[] organArray, List<Long> categoryList, List<Long> depotList, Boolean forceFlag)throws Exception {
+        int result=0;
+        try{
+            result = depotItemMapperEx.getListWithBuyOrSaleCount(materialParam, billType, beginTime, endTime, creatorArray, organId, organArray, categoryList, depotList, forceFlag);
+        }catch(Exception e){
+            JshException.readFail(logger, e);
+        }
+        return result;
+    }
+
+    @Override
+    public BigDecimal buyOrSale(String type, String subType, Long MId, String beginTime, String endTime,
+                                String[] creatorArray, Long organId, String[] organArray, List<Long> depotList, Boolean forceFlag, String sumType) throws Exception{
+        BigDecimal result= BigDecimal.ZERO;
+        try{
+            if (SUM_TYPE.equals(sumType)) {
+                result= depotItemMapperEx.buyOrSaleNumber(type, subType, MId, beginTime, endTime, creatorArray, organId, organArray, depotList, forceFlag, sumType);
+            } else {
+                result= depotItemMapperEx.buyOrSalePrice(type, subType, MId, beginTime, endTime, creatorArray, organId, organArray, depotList, forceFlag, sumType);
+            }
+        }catch(Exception e){
+            JshException.readFail(logger, e);
+        }
+        return result;
+    }
+
+    @Override
+    public BigDecimal buyOrSalePriceTotal(String type, String subType, String materialParam, String beginTime, String endTime,
+                                          String[] creatorArray, Long organId, String[] organArray, List<Long> categoryList, List<Long> depotList, Boolean forceFlag) throws Exception{
+        BigDecimal result= BigDecimal.ZERO;
+        try{
+            result= depotItemMapperEx.buyOrSalePriceTotal(type, subType, materialParam, beginTime, endTime, creatorArray, organId, organArray, categoryList, depotList, forceFlag);
+        }catch(Exception e){
+            JshException.readFail(logger, e);
+        }
+        return result;
+
+    }
+
+    /**
+     * 统计采购、销售、零售的总金额列表
+     * @param beginTime
+     * @param endTime
+     * @return
+     * @throws Exception
+     */
+    @Override
+    public List<InOutPriceVo> inOrOutPriceList(String beginTime, String endTime) throws Exception{
+        List<InOutPriceVo> result = new ArrayList<>();
+        try{
+            String [] creatorArray = depotHeadService.getCreatorArray();
+            Boolean forceFlag = systemConfigService.getForceApprovalFlag();
+            result = depotItemMapperEx.inOrOutPriceList(beginTime, endTime, creatorArray, forceFlag);
+        }catch(Exception e){
+            JshException.readFail(logger, e);
+        }
+        return result;
+    }
+
+    /**
+     * 保存单据子表
+     * @param rows 子表数据字符
+     * @param headerId  单据主表id
+     * @param actionType    操作类型
+     */
+    @Override
+    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
+    public void saveDetials(String rows, Long headerId, String actionType, HttpServletRequest request) throws Exception{
+        //查询单据主表信息
+        DepotHead depotHead =depotHeadMapper.selectByPrimaryKey(headerId);
+        //删除序列号和回收序列号
+        deleteOrCancelSerialNumber(actionType, depotHead, headerId);
+        //删除单据的明细
+        deleteDepotItemHeadId(headerId);
+        JSONArray rowArr = JSONArray.parseArray(rows);
+        if (null != rowArr && rowArr.size()>0) {
+            //针对组装单、拆卸单校验是否存在组合件和普通子件
+            checkAssembleWithMaterialType(rowArr, depotHead.getSubType());
+            for (int i = 0; i < rowArr.size(); i++) {
+                DepotItem depotItem = new DepotItem();
+                JSONObject rowObj = JSONObject.parseObject(rowArr.getString(i));
+                depotItem.setHeaderId(headerId);
+                String batchNumber = rowObj.getString("batchNumber");
+                MaterialExtend materialExtend = materialExtendService.getInfoByBatchNumber(batchNumber);
+                if(materialExtend == null) {
+                    throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_BARCODE_IS_NOT_EXIST_CODE,
+                            String.format(ExceptionConstants.MATERIAL_BARCODE_IS_NOT_EXIST_MSG, batchNumber));
+                }
+                depotItem.setMaterialId(materialExtend.getMaterialId());
+                depotItem.setMaterialExtendId(materialExtend.getId());
+                depotItem.setMaterialUnit(rowObj.getString("unit"));
+                depotItem.setActualQuantityInStorage(rowObj.getBigDecimal("actualQuantityInStorage"));
+                depotItem.setWarehousingVariance(rowObj.getBigDecimal("warehousingVariance"));
+                depotItem.setReasonOfDifference(rowObj.getString("reasonOfDifference"));
+                depotItem.setWarehousingUser(rowObj.getLong("warehousingUser"));
+                depotItem.setWarehousingTime(rowObj.getDate("warehousingTime"));
+                Material material= materialService.getMaterial(depotItem.getMaterialId());
+                if (BusinessConstants.ENABLE_SERIAL_NUMBER_ENABLED.equals(material.getEnableSerialNumber()) ||
+                        BusinessConstants.ENABLE_BATCH_NUMBER_ENABLED.equals(material.getEnableBatchNumber())) {
+                    //组装拆卸单不能选择批号或序列号商品
+                    if(BusinessConstants.SUB_TYPE_ASSEMBLE.equals(depotHead.getSubType()) ||
+                            BusinessConstants.SUB_TYPE_DISASSEMBLE.equals(depotHead.getSubType())) {
+                        throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_ASSEMBLE_SELECT_ERROR_CODE,
+                                String.format(ExceptionConstants.MATERIAL_ASSEMBLE_SELECT_ERROR_MSG, batchNumber));
+                    }
+                    //调拨单不能选择批号或序列号商品(该场景走出库和入库单)
+                    if(BusinessConstants.SUB_TYPE_TRANSFER.equals(depotHead.getSubType())) {
+                        throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_TRANSFER_SELECT_ERROR_CODE,
+                                String.format(ExceptionConstants.MATERIAL_TRANSFER_SELECT_ERROR_MSG, batchNumber));
+                    }
+                    //盘点业务不能选择批号或序列号商品(该场景走出库和入库单)
+                    if(BusinessConstants.SUB_TYPE_CHECK_ENTER.equals(depotHead.getSubType())
+                       ||BusinessConstants.SUB_TYPE_REPLAY.equals(depotHead.getSubType())) {
+                        throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_STOCK_CHECK_ERROR_CODE,
+                                String.format(ExceptionConstants.MATERIAL_STOCK_CHECK_ERROR_MSG, batchNumber));
+                    }
+                }
+                if (StringUtil.isExist(rowObj.get("snList"))) {
+                    depotItem.setSnList(rowObj.getString("snList"));
+                    if(StringUtil.isExist(rowObj.get("depotId"))) {
+                        String [] snArray = depotItem.getSnList().split(",");
+                        int operNum = rowObj.getInteger("operNumber");
+                        if(snArray.length == operNum) {
+                            Long depotId = rowObj.getLong("depotId");
+                            BigDecimal inPrice = BigDecimal.ZERO;
+                            if (StringUtil.isExist(rowObj.get("unitPrice"))) {
+                                inPrice = rowObj.getBigDecimal("unitPrice");
+                            }
+                            serialNumberService.addSerialNumberByBill(depotHead.getType(), depotHead.getSubType(),
+                                    depotHead.getNumber(), materialExtend.getMaterialId(), depotId, inPrice, depotItem.getSnList());
+                        } else {
+                            throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_SN_NUMBERE_FAILED_CODE,
+                                    String.format(ExceptionConstants.DEPOT_HEAD_SN_NUMBERE_FAILED_MSG, batchNumber));
+                        }
+                    }
+                } else {
+                    //入库或出库
+                    if (BusinessConstants.DEPOTHEAD_TYPE_IN.equals(depotHead.getType()) ||
+                            BusinessConstants.DEPOTHEAD_TYPE_OUT.equals(depotHead.getType())) {
+                        //序列号不能为空
+                        if (BusinessConstants.ENABLE_SERIAL_NUMBER_ENABLED.equals(material.getEnableSerialNumber())) {
+                            //如果开启出入库管理,并且类型等于采购、采购退货、销售、销售退货,则跳过
+                            if(systemConfigService.getInOutManageFlag() &&
+                                    (BusinessConstants.SUB_TYPE_PURCHASE.equals(depotHead.getSubType())
+                                            ||BusinessConstants.SUB_TYPE_PURCHASE_RETURN.equals(depotHead.getSubType())
+                                            ||BusinessConstants.SUB_TYPE_SALES.equals(depotHead.getSubType())
+                                            ||BusinessConstants.SUB_TYPE_SALES_RETURN.equals(depotHead.getSubType()))) {
+                                //跳过
+                            } else {
+                                throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_SERIAL_NUMBERE_EMPTY_CODE,
+                                        String.format(ExceptionConstants.MATERIAL_SERIAL_NUMBERE_EMPTY_MSG, batchNumber));
+                            }
+                        }
+                    }
+                }
+                if (StringUtil.isExist(rowObj.get("batchNumber"))) {
+                    depotItem.setBatchNumber(rowObj.getString("batchNumber"));
+                } else {
+                    //入库或出库
+                    if(BusinessConstants.DEPOTHEAD_TYPE_IN.equals(depotHead.getType()) ||
+                            BusinessConstants.DEPOTHEAD_TYPE_OUT.equals(depotHead.getType())) {
+                        //批号不能为空
+                        if (BusinessConstants.ENABLE_BATCH_NUMBER_ENABLED.equals(material.getEnableBatchNumber())) {
+                            //如果开启出入库管理,并且类型等于采购、采购退货、销售、销售退货,则跳过
+                            if(systemConfigService.getInOutManageFlag() &&
+                                    (BusinessConstants.SUB_TYPE_PURCHASE.equals(depotHead.getSubType())
+                                            ||BusinessConstants.SUB_TYPE_PURCHASE_RETURN.equals(depotHead.getSubType())
+                                            ||BusinessConstants.SUB_TYPE_SALES.equals(depotHead.getSubType())
+                                            ||BusinessConstants.SUB_TYPE_SALES_RETURN.equals(depotHead.getSubType()))) {
+                                //跳过
+                            } else {
+                                throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_BATCH_NUMBERE_EMPTY_CODE,
+                                        String.format(ExceptionConstants.DEPOT_HEAD_BATCH_NUMBERE_EMPTY_MSG, batchNumber));
+                            }
+                        }
+                    }
+                }
+                if (StringUtil.isExist(rowObj.get("expirationDate"))) {
+                    depotItem.setExpirationDate(rowObj.getDate("expirationDate"));
+                }
+                if (StringUtil.isExist(rowObj.get("sku"))) {
+                    depotItem.setSku(rowObj.getString("sku"));
+                }
+                if (StringUtil.isExist(rowObj.get("linkId"))) {
+                    depotItem.setLinkId(rowObj.getLong("linkId"));
+                }
+                //以下进行单位换算
+                Unit unitInfo = materialService.findUnit(materialExtend.getMaterialId()); //查询多单位信息
+                if (StringUtil.isExist(rowObj.get("operNumber"))) {
+                    depotItem.setOperNumber(rowObj.getBigDecimal("operNumber"));
+                    String unit = rowObj.get("unit") == null ? "" :rowObj.get("unit").toString();
+                    BigDecimal oNumber = rowObj.getBigDecimal("operNumber");
+                    if (StringUtil.isNotEmpty(unitInfo.getName())) {
+                        String basicUnit = unitInfo.getBasicUnit(); //基本单位
+                        if (unit.equals(basicUnit)) { //如果等于基本单位
+                            depotItem.setBasicNumber(oNumber); //数量一致
+                        } else if (unit.equals(unitInfo.getOtherUnit())) { //如果等于副单位
+                            depotItem.setBasicNumber(oNumber.multiply(unitInfo.getRatio())); //数量乘以比例
+                        } else if (unit.equals(unitInfo.getOtherUnitTwo())) { //如果等于副单位2
+                            depotItem.setBasicNumber(oNumber.multiply(unitInfo.getRatioTwo())); //数量乘以比例
+                        } else if (unit.equals(unitInfo.getOtherUnitThree())) { //如果等于副单位3
+                            depotItem.setBasicNumber(oNumber.multiply(unitInfo.getRatioThree())); //数量乘以比例
+                        } else {
+                            depotItem.setBasicNumber(oNumber); //数量一致
+                        }
+                    } else {
+                        depotItem.setBasicNumber(oNumber); //其他情况
+                    }
+                }
+                //如果数量+已完成数量>原订单数量,给出预警(判断前提是存在关联订单|关联请购单)
+                String linkStr = StringUtil.isNotEmpty(depotHead.getLinkNumber())? depotHead.getLinkNumber(): depotHead.getLinkApply();
+                if (StringUtil.isNotEmpty(linkStr) && StringUtil.isExist(rowObj.get("preNumber")) && StringUtil.isExist(rowObj.get("finishNumber"))) {
+                    if("add".equals(actionType)) {
+                        //在新增模式进行状态赋值
+                        BigDecimal preNumber = rowObj.getBigDecimal("preNumber");
+                        BigDecimal finishNumber = rowObj.getBigDecimal("finishNumber");
+                        if(depotItem.getOperNumber().add(finishNumber).compareTo(preNumber)>0) {
+                            if(!systemConfigService.getOverLinkBillFlag()) {
+                                throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_NUMBER_NEED_EDIT_FAILED_CODE,
+                                        String.format(ExceptionConstants.DEPOT_HEAD_NUMBER_NEED_EDIT_FAILED_MSG, batchNumber));
+                            }
+                        }
+                    } else if("update".equals(actionType)) {
+                        //当前单据的类型
+                        String currentSubType = depotHead.getSubType();
+                        //在更新模式进行状态赋值
+                        String unit = rowObj.get("unit").toString();
+                        Long preHeaderId = depotHeadService.getDepotHead(linkStr).getId();
+                        if(null!=preHeaderId) {
+                            //前一个单据的数量
+                            BigDecimal preNumber = getPreItemByHeaderIdAndMaterial(linkStr, depotItem.getMaterialExtendId(), depotItem.getLinkId()).getOperNumber();
+                            //除去此单据之外的已入库|已出库
+                            BigDecimal realFinishNumber = getRealFinishNumber(currentSubType, depotItem.getMaterialExtendId(), depotItem.getLinkId(), preHeaderId, headerId, unitInfo, unit);
+                            if(preNumber!=null) {
+                                if (depotItem.getOperNumber().add(realFinishNumber).compareTo(preNumber) > 0) {
+                                    if (!systemConfigService.getOverLinkBillFlag()) {
+                                        throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_NUMBER_NEED_EDIT_FAILED_CODE,
+                                                String.format(ExceptionConstants.DEPOT_HEAD_NUMBER_NEED_EDIT_FAILED_MSG, batchNumber));
+                                    }
+                                }
+                            } else {
+                                throw new BusinessRunTimeException(ExceptionConstants.DEPOT_ITEM_PRE_BILL_IS_CHANGE_CODE,
+                                        ExceptionConstants.DEPOT_ITEM_PRE_BILL_IS_CHANGE_MSG);
+                            }
+                        }
+                    }
+                }
+                if (StringUtil.isExist(rowObj.get("unitPrice"))) {
+                    BigDecimal unitPrice = rowObj.getBigDecimal("unitPrice");
+                    depotItem.setUnitPrice(unitPrice);
+                    if(materialExtend.getLowDecimal()!=null) {
+                        //零售或销售单价低于最低售价,进行提示
+                        if("零售".equals(depotHead.getSubType()) || "销售".equals(depotHead.getSubType())) {
+                            if (unitPrice.compareTo(materialExtend.getLowDecimal()) < 0) {
+                                throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_UNIT_PRICE_LOW_CODE,
+                                        String.format(ExceptionConstants.DEPOT_HEAD_UNIT_PRICE_LOW_MSG, batchNumber));
+                            }
+                        }
+                    }
+                }
+                //如果是销售出库、销售退货、零售出库、零售退货则给采购单价字段赋值(如果是批次商品,则要根据批号去找之前的入库价)
+                if(BusinessConstants.SUB_TYPE_SALES.equals(depotHead.getSubType()) ||
+                    BusinessConstants.SUB_TYPE_SALES_RETURN.equals(depotHead.getSubType()) ||
+                    BusinessConstants.SUB_TYPE_RETAIL.equals(depotHead.getSubType()) ||
+                    BusinessConstants.SUB_TYPE_RETAIL_RETURN.equals(depotHead.getSubType())) {
+                    boolean moveAvgPriceFlag = systemConfigService.getMoveAvgPriceFlag();
+                    BigDecimal currentUnitPrice = materialCurrentStockMapperEx.getCurrentUnitPriceByMId(materialExtend.getMaterialId());
+                    currentUnitPrice = unitService.parseUnitPriceByUnit(currentUnitPrice, unitInfo, depotItem.getMaterialUnit());
+                    BigDecimal unitPrice = moveAvgPriceFlag? currentUnitPrice: materialExtend.getPurchaseDecimal();
+                    depotItem.setPurchaseUnitPrice(unitPrice);
+                    if(StringUtil.isNotEmpty(depotItem.getBatchNumber())) {
+                        depotItem.setPurchaseUnitPrice(getDepotItemByBatchNumber(depotItem.getMaterialExtendId(),depotItem.getBatchNumber()).getUnitPrice());
+                    }
+                }
+                if (StringUtil.isExist(rowObj.get("taxUnitPrice"))) {
+                    depotItem.setTaxUnitPrice(rowObj.getBigDecimal("taxUnitPrice"));
+                }
+                if (StringUtil.isExist(rowObj.get("allPrice"))) {
+                    depotItem.setAllPrice(rowObj.getBigDecimal("allPrice"));
+                }
+                if (StringUtil.isExist(rowObj.get("depotId"))) {
+                    depotItem.setDepotId(rowObj.getLong("depotId"));
+                } else {
+                    if(!BusinessConstants.SUB_TYPE_PURCHASE_APPLY.equals(depotHead.getSubType())
+                            && !BusinessConstants.SUB_TYPE_PURCHASE_ORDER.equals(depotHead.getSubType())
+                            && !BusinessConstants.SUB_TYPE_SALES_ORDER.equals(depotHead.getSubType())) {
+                        throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_DEPOT_FAILED_CODE,
+                                String.format(ExceptionConstants.DEPOT_HEAD_DEPOT_FAILED_MSG));
+                    }
+                }
+                if(BusinessConstants.SUB_TYPE_TRANSFER.equals(depotHead.getSubType())) {
+                    if (StringUtil.isExist(rowObj.get("anotherDepotId"))) {
+                        if(rowObj.getLong("anotherDepotId").equals(rowObj.getLong("depotId"))) {
+                            throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_ANOTHER_DEPOT_EQUAL_FAILED_CODE,
+                                    String.format(ExceptionConstants.DEPOT_HEAD_ANOTHER_DEPOT_EQUAL_FAILED_MSG));
+                        } else {
+                            depotItem.setAnotherDepotId(rowObj.getLong("anotherDepotId"));
+                        }
+                    } else {
+                        throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_ANOTHER_DEPOT_FAILED_CODE,
+                                String.format(ExceptionConstants.DEPOT_HEAD_ANOTHER_DEPOT_FAILED_MSG));
+                    }
+                }
+                if (StringUtil.isExist(rowObj.get("taxRate"))) {
+                    depotItem.setTaxRate(rowObj.getBigDecimal("taxRate"));
+                }
+                if (StringUtil.isExist(rowObj.get("taxMoney"))) {
+                    depotItem.setTaxMoney(rowObj.getBigDecimal("taxMoney"));
+                }
+                if (StringUtil.isExist(rowObj.get("taxLastMoney"))) {
+                    depotItem.setTaxLastMoney(rowObj.getBigDecimal("taxLastMoney"));
+                }
+                if (StringUtil.isExist(rowObj.get("mType"))) {
+                    depotItem.setMaterialType(rowObj.getString("mType"));
+                }
+                if (StringUtil.isExist(rowObj.get("remark"))) {
+                    depotItem.setRemark(rowObj.getString("remark"));
+                }
+                //出库时判断库存是否充足
+                if(BusinessConstants.DEPOTHEAD_TYPE_OUT.equals(depotHead.getType())){
+                    String stockMsg = material.getName() + "-" + batchNumber;
+                    BigDecimal stock = getCurrentStockByParam(depotItem.getDepotId(),depotItem.getMaterialId());
+                    if(StringUtil.isNotEmpty(depotItem.getSku())) {
+                        //对于sku商品要换个方式计算库存
+                        stock = getSkuStockByParam(depotItem.getDepotId(),depotItem.getMaterialExtendId(),null,null);
+                    }
+                    if(StringUtil.isNotEmpty(depotItem.getBatchNumber())) {
+                        //对于批次商品要换个方式计算库存
+                        stock = getOneBatchNumberStock(depotItem.getDepotId(), batchNumber, depotItem.getBatchNumber());
+                        stockMsg += "-批号" + depotItem.getBatchNumber();
+                    }
+                    BigDecimal thisRealNumber = depotItem.getBasicNumber()==null?BigDecimal.ZERO:depotItem.getBasicNumber();
+                    if(StringUtil.isNotEmpty(depotItem.getBatchNumber())) {
+                        //对于批次商品,直接使用当前填写的数量
+                        thisRealNumber = depotItem.getOperNumber()==null?BigDecimal.ZERO:depotItem.getOperNumber();
+                    }
+                    if(!systemConfigService.getMinusStockFlag() && stock.compareTo(thisRealNumber)<0){
+                        throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_STOCK_NOT_ENOUGH_CODE,
+                                String.format(ExceptionConstants.MATERIAL_STOCK_NOT_ENOUGH_MSG, stockMsg));
+                    }
+                    //出库时处理序列号
+                    if(!BusinessConstants.SUB_TYPE_TRANSFER.equals(depotHead.getSubType())) {
+                        //判断商品是否开启序列号,开启的售出序列号,未开启的跳过
+                        if(BusinessConstants.ENABLE_SERIAL_NUMBER_ENABLED.equals(material.getEnableSerialNumber())) {
+                            //如果开启出入库管理,并且类型等于采购、采购退货、销售、销售退货,则跳过
+                            if(systemConfigService.getInOutManageFlag() &&
+                                    (BusinessConstants.SUB_TYPE_PURCHASE.equals(depotHead.getSubType())
+                                            ||BusinessConstants.SUB_TYPE_PURCHASE_RETURN.equals(depotHead.getSubType())
+                                            ||BusinessConstants.SUB_TYPE_SALES.equals(depotHead.getSubType())
+                                            ||BusinessConstants.SUB_TYPE_SALES_RETURN.equals(depotHead.getSubType()))) {
+                                //跳过
+                            } else {
+                                //售出序列号,获得当前操作人
+                                User userInfo = userService.getCurrentUser();
+                                serialNumberService.checkAndUpdateSerialNumber(depotItem, depotHead.getNumber(), userInfo, StringUtil.toNull(depotItem.getSnList()));
+                            }
+                        }
+                    }
+                }
+                this.insertDepotItemWithObj(depotItem);
+                //更新当前库存
+                updateCurrentStock(depotItem);
+                //更新当前成本价
+                updateCurrentUnitPrice(depotItem);
+                //更新商品的价格
+                updateMaterialExtendPrice(materialExtend.getId(), depotHead.getSubType(), depotHead.getBillType(), rowObj);
+            }
+            //如果关联单据号非空则更新订单的状态,单据类型:采购入库单、销售出库单、盘点复盘单、其它入库单、其它出库单
+            if(BusinessConstants.SUB_TYPE_PURCHASE.equals(depotHead.getSubType())
+                    || BusinessConstants.SUB_TYPE_SALES.equals(depotHead.getSubType())
+                    || BusinessConstants.SUB_TYPE_REPLAY.equals(depotHead.getSubType())
+                    || BusinessConstants.SUB_TYPE_OTHER.equals(depotHead.getSubType())) {
+                if(StringUtil.isNotEmpty(depotHead.getLinkNumber())) {
+                    //单据状态:是否全部完成 2-全部完成 3-部分完成(针对订单的分批出入库)
+                    String billStatus = getBillStatusByParam(depotHead, depotHead.getLinkNumber(), "normal");
+                    changeBillStatus(depotHead.getLinkNumber(), billStatus);
+                }
+            }
+            //当前单据类型为采购订单的逻辑
+            if(BusinessConstants.SUB_TYPE_PURCHASE_ORDER.equals(depotHead.getSubType())) {
+                //如果关联单据号非空则更新订单的状态,此处针对销售订单转采购订单的场景
+                if(StringUtil.isNotEmpty(depotHead.getLinkNumber())) {
+                    String billStatus = getBillStatusByParam(depotHead, depotHead.getLinkNumber(), "normal");
+                    changeBillPurchaseStatus(depotHead.getLinkNumber(), billStatus);
+                }
+                //如果关联单据号非空则更新订单的状态,此处针对请购单转采购订单的场景
+                if(StringUtil.isNotEmpty(depotHead.getLinkApply())) {
+                    String billStatus = getBillStatusByParam(depotHead, depotHead.getLinkApply(), "apply");
+                    changeBillStatus(depotHead.getLinkApply(), billStatus);
+                }
+            }
+        } else {
+            throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_ROW_FAILED_CODE,
+                    String.format(ExceptionConstants.DEPOT_HEAD_ROW_FAILED_MSG));
+        }
+    }
+    /**
+     * 判断单据的状态
+     * 通过数组对比:原单据的商品和商品数量(汇总) 与 分批操作后单据的商品和商品数量(汇总)
+     * @param depotHead
+     * @param linkStr
+     * @return
+     */
+    @Override
+    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
+    public String getBillStatusByParam(DepotHead depotHead, String linkStr, String linkType) {
+        String res = BusinessConstants.BILLS_STATUS_SKIPED;
+        //获取原单据的商品和商品数量(汇总)
+        List<DepotItemVo4MaterialAndSum> linkList = depotItemMapperEx.getLinkBillDetailMaterialSum(linkStr);
+        //获取分批操作后单据的商品和商品数量(汇总)
+        List<DepotItemVo4MaterialAndSum> batchList = depotItemMapperEx.getBatchBillDetailMaterialSum(linkStr, linkType, depotHead.getType());
+        //将分批操作后的单据的商品和商品数据构造成Map
+        Map<Long, BigDecimal> materialSumMap = new HashMap<>();
+        for(DepotItemVo4MaterialAndSum materialAndSum : batchList) {
+            materialSumMap.put(materialAndSum.getMaterialExtendId(), materialAndSum.getOperNumber());
+        }
+        for(DepotItemVo4MaterialAndSum materialAndSum : linkList) {
+            //过滤掉原单里面有数量为0的商品
+            if(materialAndSum.getOperNumber().compareTo(BigDecimal.ZERO) != 0) {
+                BigDecimal materialSum = materialSumMap.get(materialAndSum.getMaterialExtendId());
+                if (materialSum != null) {
+                    if (materialSum.compareTo(materialAndSum.getOperNumber()) < 0) {
+                        res = BusinessConstants.BILLS_STATUS_SKIPING;
+                    }
+                } else {
+                    res = BusinessConstants.BILLS_STATUS_SKIPING;
+                }
+            }
+        }
+        return res;
+    }
+
+    /**
+     * 更新单据状态
+     * @param linkStr
+     * @param billStatus
+     */
+    @Override
+    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
+    public void changeBillStatus(String linkStr, String billStatus) {
+        DepotHead depotHeadOrders = new DepotHead();
+        depotHeadOrders.setStatus(billStatus);
+        DepotHeadExample example = new DepotHeadExample();
+        List<String> linkNoList = StringUtil.strToStringList(linkStr);
+        example.createCriteria().andNumberIn(linkNoList);
+        try{
+            depotHeadMapper.updateByExampleSelective(depotHeadOrders, example);
+        }catch(Exception e){
+            logger.error("异常码[{}],异常提示[{}],异常[{}]",
+                    ExceptionConstants.DATA_WRITE_FAIL_CODE,ExceptionConstants.DATA_WRITE_FAIL_MSG,e);
+            throw new BusinessRunTimeException(ExceptionConstants.DATA_WRITE_FAIL_CODE,
+                    ExceptionConstants.DATA_WRITE_FAIL_MSG);
+        }
+    }
+
+    /**
+     * 更新单据状态,此处针对销售订单转采购订单的场景
+     * @param linkStr
+     * @param billStatus
+     */
+    @Override
+    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
+    public void changeBillPurchaseStatus(String linkStr, String billStatus) {
+        DepotHead depotHeadOrders = new DepotHead();
+        depotHeadOrders.setPurchaseStatus(billStatus);
+        DepotHeadExample example = new DepotHeadExample();
+        List<String> linkNoList = StringUtil.strToStringList(linkStr);
+        example.createCriteria().andNumberIn(linkNoList);
+        try{
+            depotHeadMapper.updateByExampleSelective(depotHeadOrders, example);
+        }catch(Exception e){
+            logger.error("异常码[{}],异常提示[{}],异常[{}]",
+                    ExceptionConstants.DATA_WRITE_FAIL_CODE,ExceptionConstants.DATA_WRITE_FAIL_MSG,e);
+            throw new BusinessRunTimeException(ExceptionConstants.DATA_WRITE_FAIL_CODE,
+                    ExceptionConstants.DATA_WRITE_FAIL_MSG);
+        }
+    }
+
+    /**
+     * 根据批号查询单据明细信息
+     * @param materialExtendId
+     * @param batchNumber
+     * @return
+     */
+    @Override
+    public DepotItem getDepotItemByBatchNumber(Long materialExtendId, String batchNumber) {
+        List<DepotItem> depotItemList = depotItemMapperEx.getDepotItemByBatchNumber(materialExtendId, batchNumber);
+        if(null != depotItemList && depotItemList.size() > 0){
+            return depotItemList.get(0);
+        } else {
+            return new DepotItem();
+        }
+    }
+
+    @Override
+    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
+    public void deleteDepotItemHeadId(Long headerId)throws Exception {
+        try{
+            //1、查询删除前的单据明细
+            List<DepotItem> depotItemList = getListByHeaderId(headerId);
+            //2、删除单据明细
+            DepotItemExample example = new DepotItemExample();
+            example.createCriteria().andHeaderIdEqualTo(headerId);
+            depotItemMapper.deleteByExample(example);
+            //3、计算删除之后单据明细中商品的库存
+            for(DepotItem depotItem : depotItemList){
+                updateCurrentStock(depotItem);
+            }
+        }catch(Exception e){
+            JshException.writeFail(logger, e);
+        }
+    }
+
+    /**
+     * 删除序列号和回收序列号
+     * @param actionType
+     * @throws Exception
+     */
+    @Override
+    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
+    public void deleteOrCancelSerialNumber(String actionType, DepotHead depotHead, Long headerId) throws Exception {
+        if(actionType.equals("update")) {
+            User userInfo = userService.getCurrentUser();
+            if(BusinessConstants.DEPOTHEAD_TYPE_IN.equals(depotHead.getType())){
+                //入库逻辑
+                String number = depotHead.getNumber();
+                SerialNumberExample example = new SerialNumberExample();
+                example.createCriteria().andInBillNoEqualTo(number);
+                serialNumberService.deleteByExample(example);
+            } else if(BusinessConstants.DEPOTHEAD_TYPE_OUT.equals(depotHead.getType())){
+                //出库逻辑
+                DepotItemExample example = new DepotItemExample();
+                example.createCriteria().andHeaderIdEqualTo(headerId).andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
+                List<DepotItem> depotItemList = depotItemMapper.selectByExample(example);
+                if(null != depotItemList && depotItemList.size() > 0){
+                    for (DepotItem depotItem : depotItemList){
+                        if(StringUtil.isNotEmpty(depotItem.getSnList())){
+                            serialNumberService.cancelSerialNumber(depotItem.getMaterialId(), depotHead.getNumber(), (depotItem.getBasicNumber() == null ? 0 : depotItem.getBasicNumber()).intValue(), userInfo);
+                        }
+                    }
+                }
+            }
+        }
+    }
+
+    /**
+     * 针对组装单、拆卸单校验是否存在组合件和普通子件
+     * @param rowArr
+     * @param subType
+     */
+    @Override
+    public void checkAssembleWithMaterialType(JSONArray rowArr, String subType) {
+        if(BusinessConstants.SUB_TYPE_ASSEMBLE.equals(subType) ||
+                BusinessConstants.SUB_TYPE_DISASSEMBLE.equals(subType)) {
+            if(rowArr.size() > 1) {
+                JSONObject firstRowObj = JSONObject.parseObject(rowArr.getString(0));
+                JSONObject secondRowObj = JSONObject.parseObject(rowArr.getString(1));
+                String firstMaterialType = firstRowObj.getString("mType");
+                String secondMaterialType = secondRowObj.getString("mType");
+                if(!"组合件".equals(firstMaterialType) || !"普通子件".equals(secondMaterialType)) {
+                    throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_CHECK_ASSEMBLE_EMPTY_CODE,
+                            String.format(ExceptionConstants.DEPOT_HEAD_CHECK_ASSEMBLE_EMPTY_MSG));
+                }
+            } else {
+                throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_CHECK_ASSEMBLE_EMPTY_CODE,
+                        String.format(ExceptionConstants.DEPOT_HEAD_CHECK_ASSEMBLE_EMPTY_MSG));
+            }
+        }
+    }
+
+    /**
+     * 更新商品的价格
+     * @param meId
+     * @param subType
+     * @param rowObj
+     */
+    @Override
+    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
+    public void updateMaterialExtendPrice(Long meId, String subType, String billType, JSONObject rowObj) throws Exception {
+        if(systemConfigService.getUpdateUnitPriceFlag()) {
+            if (StringUtil.isExist(rowObj.get("unitPrice"))) {
+                BigDecimal unitPrice = rowObj.getBigDecimal("unitPrice");
+                MaterialExtend materialExtend = new MaterialExtend();
+                materialExtend.setId(meId);
+                if(BusinessConstants.SUB_TYPE_PURCHASE.equals(subType)) {
+                    materialExtend.setPurchaseDecimal(unitPrice);
+                }
+                if(BusinessConstants.SUB_TYPE_SALES.equals(subType)) {
+                    materialExtend.setWholesaleDecimal(unitPrice);
+                }
+                if(BusinessConstants.SUB_TYPE_RETAIL.equals(subType)) {
+                    materialExtend.setCommodityDecimal(unitPrice);
+                }
+                //其它入库-生产入库的情况更新采购单价
+                if(BusinessConstants.SUB_TYPE_OTHER.equals(subType)) {
+                    if(BusinessConstants.BILL_TYPE_PRODUCE_IN.equals(billType)) {
+                        materialExtend.setPurchaseDecimal(unitPrice);
+                    }
+                }
+                materialExtendService.updateMaterialExtend(materialExtend);
+            }
+        }
+    }
+
+    @Override
+    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
+    public List<DepotItemStockWarningCount> findStockWarningCount(Integer offset, Integer rows, String materialParam, List<Long> depotList, List<Long> categoryList) {
+        List<DepotItemStockWarningCount> list = null;
+        try{
+            list =depotItemMapperEx.findStockWarningCount(offset, rows, materialParam, depotList, categoryList);
+        }catch(Exception e){
+            JshException.readFail(logger, e);
+        }
+        return list;
+    }
+
+    @Override
+    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
+    public int findStockWarningCountTotal(String materialParam, List<Long> depotList, List<Long> categoryList) {
+        int result = 0;
+        try{
+            result =depotItemMapperEx.findStockWarningCountTotal(materialParam, depotList, categoryList);
+        }catch(Exception e){
+            JshException.readFail(logger, e);
+        }
+        return result;
+    }
+
+    /**
+     * 库存统计-sku
+     * @param depotId
+     * @param meId
+     * @param beginTime
+     * @param endTime
+     * @return
+     */
+    @Override
+    public BigDecimal getSkuStockByParam(Long depotId, Long meId, String beginTime, String endTime) throws Exception {
+        Boolean forceFlag = systemConfigService.getForceApprovalFlag();
+        Boolean inOutManageFlag = systemConfigService.getInOutManageFlag();
+        List<Long> depotList = depotService.parseDepotList(depotId);
+        //盘点复盘后数量的变动
+        BigDecimal stockCheckSum = depotItemMapperEx.getSkuStockCheckSumByDepotList(depotList, meId, forceFlag, beginTime, endTime);
+        DepotItemVo4Stock stockObj = depotItemMapperEx.getSkuStockByParamWithDepotList(depotList, meId, forceFlag, inOutManageFlag, beginTime, endTime);
+        BigDecimal stockSum = BigDecimal.ZERO;
+        if(stockObj!=null) {
+            BigDecimal inTotal = stockObj.getInTotal();
+            BigDecimal transfInTotal = stockObj.getTransfInTotal();
+            BigDecimal assemInTotal = stockObj.getAssemInTotal();
+            BigDecimal disAssemInTotal = stockObj.getDisAssemInTotal();
+            BigDecimal outTotal = stockObj.getOutTotal();
+            BigDecimal transfOutTotal = stockObj.getTransfOutTotal();
+            BigDecimal assemOutTotal = stockObj.getAssemOutTotal();
+            BigDecimal disAssemOutTotal = stockObj.getDisAssemOutTotal();
+            stockSum = inTotal.add(transfInTotal).add(assemInTotal).add(disAssemInTotal)
+                    .subtract(outTotal).subtract(transfOutTotal).subtract(assemOutTotal).subtract(disAssemOutTotal);
+        }
+        return stockCheckSum.add(stockSum);
+    }
+
+    /**
+     * 库存统计-单仓库
+     * @param depotId
+     * @param mId
+     * @param beginTime
+     * @param endTime
+     * @return
+     */
+    @Override
+    public BigDecimal getStockByParam(Long depotId, Long mId, String beginTime, String endTime) throws Exception {
+        List<Long> depotList = depotService.parseDepotList(depotId);
+        return getStockByParamWithDepotList(depotList, mId, beginTime, endTime);
+    }
+
+    /**
+     * 库存统计-多仓库
+     * @param depotList
+     * @param mId
+     * @param beginTime
+     * @param endTime
+     * @return
+     */
+    @Override
+    public BigDecimal getStockByParamWithDepotList(List<Long> depotList, Long mId, String beginTime, String endTime) throws Exception {
+        Boolean forceFlag = systemConfigService.getForceApprovalFlag();
+        Boolean inOutManageFlag = systemConfigService.getInOutManageFlag();
+        //初始库存
+        BigDecimal initStock = materialService.getInitStockByMidAndDepotList(depotList, mId);
+        //盘点复盘后数量的变动
+        BigDecimal stockCheckSum = depotItemMapperEx.getStockCheckSumByDepotList(depotList, mId, forceFlag, beginTime, endTime);
+        DepotItemVo4Stock stockObj = depotItemMapperEx.getStockByParamWithDepotList(depotList, mId, forceFlag, inOutManageFlag, beginTime, endTime);
+        BigDecimal stockSum = BigDecimal.ZERO;
+        if(stockObj!=null) {
+            BigDecimal inTotal = stockObj.getInTotal();
+            BigDecimal transfInTotal = stockObj.getTransfInTotal();
+            BigDecimal assemInTotal = stockObj.getAssemInTotal();
+            BigDecimal disAssemInTotal = stockObj.getDisAssemInTotal();
+            BigDecimal outTotal = stockObj.getOutTotal();
+            BigDecimal transfOutTotal = stockObj.getTransfOutTotal();
+            BigDecimal assemOutTotal = stockObj.getAssemOutTotal();
+            BigDecimal disAssemOutTotal = stockObj.getDisAssemOutTotal();
+            stockSum = inTotal.add(transfInTotal).add(assemInTotal).add(disAssemInTotal)
+                    .subtract(outTotal).subtract(transfOutTotal).subtract(assemOutTotal).subtract(disAssemOutTotal);
+        }
+        return initStock.add(stockCheckSum).add(stockSum);
+    }
+
+    /**
+     * 统计时间段内的入库和出库数量-多仓库
+     * @param depotList
+     * @param mId
+     * @param beginTime
+     * @param endTime
+     * @return
+     */
+    @Override
+    public Map<String, BigDecimal> getIntervalMapByParamWithDepotList(List<Long> depotList, Long mId, String beginTime, String endTime) throws Exception {
+        Boolean forceFlag = systemConfigService.getForceApprovalFlag();
+        Boolean inOutManageFlag = systemConfigService.getInOutManageFlag();
+        Map<String,BigDecimal> intervalMap = new HashMap<>();
+        BigDecimal inSum = BigDecimal.ZERO;
+        BigDecimal outSum = BigDecimal.ZERO;
+        //盘点复盘后数量的变动
+        BigDecimal stockCheckSum = depotItemMapperEx.getStockCheckSumByDepotList(depotList, mId, forceFlag, beginTime, endTime);
+        DepotItemVo4Stock stockObj = depotItemMapperEx.getStockByParamWithDepotList(depotList, mId, forceFlag, inOutManageFlag, beginTime, endTime);
+        if(stockObj!=null) {
+            BigDecimal inTotal = stockObj.getInTotal();
+            BigDecimal transfInTotal = stockObj.getTransfInTotal();
+            BigDecimal assemInTotal = stockObj.getAssemInTotal();
+            BigDecimal disAssemInTotal = stockObj.getDisAssemInTotal();
+            inSum = inTotal.add(transfInTotal).add(assemInTotal).add(disAssemInTotal);
+            BigDecimal outTotal = stockObj.getOutTotal();
+            BigDecimal transfOutTotal = stockObj.getTransfOutTotal();
+            BigDecimal assemOutTotal = stockObj.getAssemOutTotal();
+            BigDecimal disAssemOutTotal = stockObj.getDisAssemOutTotal();
+            outSum = outTotal.add(transfOutTotal).add(assemOutTotal).add(disAssemOutTotal);
+        }
+        if(stockCheckSum.compareTo(BigDecimal.ZERO)>0) {
+            inSum = inSum.add(stockCheckSum);
+        } else {
+            //盘点复盘数量为负数代表出库
+            outSum = outSum.subtract(stockCheckSum);
+        }
+        intervalMap.put("inSum", inSum);
+        intervalMap.put("outSum", outSum);
+        return intervalMap;
+    }
+
+    /**
+     * 根据单据明细来批量更新当前库存
+     * @param depotItem
+     */
+    @Override
+    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
+    public void updateCurrentStock(DepotItem depotItem) throws Exception {
+        updateCurrentStockFun(depotItem.getMaterialId(), depotItem.getDepotId());
+        if(depotItem.getAnotherDepotId()!=null){
+            updateCurrentStockFun(depotItem.getMaterialId(), depotItem.getAnotherDepotId());
+        }
+    }
+
+    /**
+     * 根据单据明细来批量更新当前成本价
+     * @param depotItem
+     */
+    @Override
+    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
+    public void updateCurrentUnitPrice(DepotItem depotItem) throws Exception {
+        Boolean forceFlag = systemConfigService.getForceApprovalFlag();
+        Boolean inOutManageFlag = systemConfigService.getInOutManageFlag();
+        //查询多单位信息
+        Unit unitInfo = materialService.findUnit(depotItem.getMaterialId());
+        List<DepotItemVo4DetailByTypeAndMId> itemList = findDetailByDepotIdsAndMaterialIdList(null, forceFlag, inOutManageFlag, depotItem.getSku(),
+                depotItem.getBatchNumber(), null, null, null, depotItem.getMaterialId(), null, null);
+        Collections.reverse(itemList); //倒序之后变成按时间从前往后排序
+        BigDecimal currentNumber = BigDecimal.ZERO;
+        BigDecimal currentUnitPrice = BigDecimal.ZERO;
+        BigDecimal currentAllPrice = BigDecimal.ZERO;
+        for(DepotItemVo4DetailByTypeAndMId item: itemList) {
+            BigDecimal basicNumber = item.getBnum()!=null?item.getBnum():BigDecimal.ZERO;
+            //数量*单价  另外计算新的成本价
+            BigDecimal allPrice = unitService.parseAllPriceByUnit(item.getAllPrice()!=null?item.getAllPrice():BigDecimal.ZERO, unitInfo, item.getMaterialUnit());
+            if(basicNumber.compareTo(BigDecimal.ZERO)!=0 && allPrice.compareTo(BigDecimal.ZERO)!=0) {
+                //入库
+                if (BusinessConstants.DEPOTHEAD_TYPE_IN.equals(item.getType())) {
+                    //零售退货、销售退货
+                    if (BusinessConstants.SUB_TYPE_RETAIL_RETURN.equals(item.getSubType()) || BusinessConstants.SUB_TYPE_SALES_RETURN.equals(item.getSubType())) {
+                        //数量*当前的成本单价
+                        currentNumber = currentNumber.add(basicNumber);
+                        currentAllPrice = currentAllPrice.add(basicNumber.multiply(currentUnitPrice));
+                    } else {
+                        currentAllPrice = currentAllPrice.add(allPrice);
+                        currentNumber = currentNumber.add(basicNumber);
+                        //只有当前库存总金额和当前库存数量都大于0才计算移动平均价
+                        if (currentAllPrice.compareTo(BigDecimal.ZERO) > 0 && currentNumber.compareTo(BigDecimal.ZERO) > 0) {
+                            currentUnitPrice = currentAllPrice.divide(currentNumber, 2, BigDecimal.ROUND_HALF_UP);
+                        } else {
+                            currentUnitPrice = item.getUnitPrice();
+                        }
+                    }
+                }
+                //出库
+                if (BusinessConstants.DEPOTHEAD_TYPE_OUT.equals(item.getType())) {
+                    //采购退货
+                    if (BusinessConstants.SUB_TYPE_PURCHASE_RETURN.equals(item.getSubType())) {
+                        currentAllPrice = currentAllPrice.add(allPrice);
+                        currentNumber = currentNumber.add(basicNumber);
+                        //只有当前库存总金额和当前库存数量都大于0才计算移动平均价
+                        if (currentAllPrice.compareTo(BigDecimal.ZERO) > 0 && currentNumber.compareTo(BigDecimal.ZERO) > 0) {
+                            currentUnitPrice = currentAllPrice.divide(currentNumber, 2, BigDecimal.ROUND_HALF_UP);
+                        } else {
+                            currentUnitPrice = item.getUnitPrice();
+                        }
+                    } else {
+                        currentNumber = currentNumber.add(basicNumber);
+                        //数量*当前的成本单价
+                        currentAllPrice = currentAllPrice.add(basicNumber.multiply(currentUnitPrice));
+                    }
+                }
+                //防止单价金额溢出
+                if(currentUnitPrice.compareTo(BigDecimal.valueOf(100000000))>0 || currentUnitPrice.compareTo(BigDecimal.valueOf(-100000000))<0) {
+                    currentUnitPrice = BigDecimal.ZERO;
+                }
+            }
+        }
+        //更新实时库存中的当前单价
+        materialCurrentStockMapperEx.updateUnitPriceByMId(currentUnitPrice, depotItem.getMaterialId());
+    }
+
+    /**
+     * 根据商品和仓库来更新当前库存
+     * @param mId
+     * @param dId
+     */
+    @Override
+    public void updateCurrentStockFun(Long mId, Long dId) throws Exception {
+        if(mId!=null && dId!=null) {
+            MaterialCurrentStockExample example = new MaterialCurrentStockExample();
+            example.createCriteria().andMaterialIdEqualTo(mId).andDepotIdEqualTo(dId)
+                    .andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
+            //获取商品当前库存信息
+            List<MaterialCurrentStock> list = materialCurrentStockMapper.selectByExample(example);
+            MaterialCurrentStock materialCurrentStock = new MaterialCurrentStock();
+            materialCurrentStock.setMaterialId(mId);
+            materialCurrentStock.setDepotId(dId);
+            materialCurrentStock.setCurrentNumber(getStockByParam(dId,mId,null,null));
+            if(list!=null && list.size()>0) {
+                Long mcsId = list.get(0).getId();
+                materialCurrentStock.setId(mcsId);
+                materialCurrentStockMapper.updateByPrimaryKeySelective(materialCurrentStock);
+            } else {
+                materialCurrentStockMapper.insertSelective(materialCurrentStock);
+            }
+        }
+    }
+
+    @Override
+    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
+    public BigDecimal getFinishNumber(Long meId, Long id, Long headerId, Unit unitInfo, String materialUnit, String linkType) {
+        Long linkId = id;
+        String goToType = "";
+        DepotHead depotHead =depotHeadMapper.selectByPrimaryKey(headerId);
+        String linkStr = depotHead.getNumber(); //订单号
+        if("purchase".equals(linkType)) {
+            //针对以销定购的情况
+            if(BusinessConstants.SUB_TYPE_SALES_ORDER.equals(depotHead.getSubType())) {
+                goToType = BusinessConstants.SUB_TYPE_PURCHASE_ORDER;
+            }
+        } else if("other".equals(linkType)) {
+            //采购入库、采购退货、销售出库、销售退货都转其它入库
+            if(BusinessConstants.SUB_TYPE_PURCHASE.equals(depotHead.getSubType())
+                    || BusinessConstants.SUB_TYPE_PURCHASE_RETURN.equals(depotHead.getSubType())
+                    || BusinessConstants.SUB_TYPE_SALES.equals(depotHead.getSubType())
+                    || BusinessConstants.SUB_TYPE_SALES_RETURN.equals(depotHead.getSubType())) {
+                goToType = BusinessConstants.SUB_TYPE_OTHER;
+            }
+        } else if("basic".equals(linkType)) {
+            //采购订单转采购入库
+            if(BusinessConstants.SUB_TYPE_PURCHASE_ORDER.equals(depotHead.getSubType())) {
+                goToType = BusinessConstants.SUB_TYPE_PURCHASE;
+            }
+            //销售订单转销售出库
+            if(BusinessConstants.SUB_TYPE_SALES_ORDER.equals(depotHead.getSubType())) {
+                goToType = BusinessConstants.SUB_TYPE_SALES;
+            }
+            //采购入库转采购退货
+            if(BusinessConstants.SUB_TYPE_PURCHASE.equals(depotHead.getSubType())) {
+                goToType = BusinessConstants.SUB_TYPE_PURCHASE_RETURN;
+            }
+            //销售出库转销售退货
+            if(BusinessConstants.SUB_TYPE_SALES.equals(depotHead.getSubType())) {
+                goToType = BusinessConstants.SUB_TYPE_SALES_RETURN;
+            }
+        }
+        String noType = "normal";
+        if(BusinessConstants.SUB_TYPE_PURCHASE_APPLY.equals(depotHead.getSubType())) {
+            noType = "apply";
+        }
+        BigDecimal count = depotItemMapperEx.getFinishNumber(meId, linkId, linkStr, noType, goToType);
+        //根据多单位情况进行数量的转换
+        if(materialUnit.equals(unitInfo.getOtherUnit()) && unitInfo.getRatio()!=null && unitInfo.getRatio().compareTo(BigDecimal.ZERO)!=0) {
+            count = count.divide(unitInfo.getRatio(),2,BigDecimal.ROUND_HALF_UP);
+        }
+        if(materialUnit.equals(unitInfo.getOtherUnitTwo()) && unitInfo.getRatioTwo()!=null && unitInfo.getRatioTwo().compareTo(BigDecimal.ZERO)!=0) {
+            count = count.divide(unitInfo.getRatioTwo(),2,BigDecimal.ROUND_HALF_UP);
+        }
+        if(materialUnit.equals(unitInfo.getOtherUnitThree()) && unitInfo.getRatioThree()!=null && unitInfo.getRatioThree().compareTo(BigDecimal.ZERO)!=0) {
+            count = count.divide(unitInfo.getRatioThree(),2,BigDecimal.ROUND_HALF_UP);
+        }
+        return count;
+    }
+
+    /**
+     * 除去此单据之外的已入库|已出库|已转采购
+     * @param currentSubType
+     * @param meId
+     * @param linkId
+     * @param preHeaderId
+     * @param currentHeaderId
+     * @param unitInfo
+     * @param materialUnit
+     * @return
+     */
+    @Override
+    @Transactional(value = "transactionManager", rollbackFor = Exception.class)
+    public BigDecimal getRealFinishNumber(String currentSubType, Long meId, Long linkId, Long preHeaderId, Long currentHeaderId, Unit unitInfo, String materialUnit) {
+        String goToType = currentSubType;
+        DepotHead depotHead =depotHeadMapper.selectByPrimaryKey(preHeaderId);
+        String linkStr = depotHead.getNumber(); //订单号
+        String linkType = "normal";
+        if(BusinessConstants.SUB_TYPE_PURCHASE_APPLY.equals(depotHead.getSubType())) {
+            linkType = "apply";
+        }
+        BigDecimal count = depotItemMapperEx.getRealFinishNumber(meId, linkId, linkStr, linkType, currentHeaderId, goToType);
+        //根据多单位情况进行数量的转换
+        if(materialUnit.equals(unitInfo.getOtherUnit()) && unitInfo.getRatio()!=null && unitInfo.getRatio().compareTo(BigDecimal.ZERO)!=0) {
+            count = count.divide(unitInfo.getRatio(),2,BigDecimal.ROUND_HALF_UP);
+        }
+        if(materialUnit.equals(unitInfo.getOtherUnitTwo()) && unitInfo.getRatioTwo()!=null && unitInfo.getRatioTwo().compareTo(BigDecimal.ZERO)!=0) {
+            count = count.divide(unitInfo.getRatioTwo(),2,BigDecimal.ROUND_HALF_UP);
+        }
+        if(materialUnit.equals(unitInfo.getOtherUnitThree()) && unitInfo.getRatioThree()!=null && unitInfo.getRatioThree().compareTo(BigDecimal.ZERO)!=0) {
+            count = count.divide(unitInfo.getRatioThree(),2,BigDecimal.ROUND_HALF_UP);
+        }
+        return count;
+    }
+
+    @Override
+    public List<DepotItemVoBatchNumberList> getBatchNumberList(String number, String name, Long depotId, String barCode,
+                                                               String batchNumber, Boolean forceFlag, Boolean inOutManageFlag) throws Exception {
+        List<DepotItemVoBatchNumberList> reslist = new ArrayList<>();
+        List<DepotItemVoBatchNumberList> list =  depotItemMapperEx.getBatchNumberList(StringUtil.toNull(number), name,
+                depotId, barCode, batchNumber, forceFlag, inOutManageFlag);
+        for(DepotItemVoBatchNumberList bn: list) {
+            if(bn.getTotalNum()!=null && bn.getTotalNum().compareTo(BigDecimal.ZERO)>0) {
+                bn.setExpirationDateStr(Tools.parseDateToStr(bn.getExpirationDate()));
+                if(bn.getUnitId()!=null) {
+                    Unit unit = unitService.getUnit(bn.getUnitId());
+                    String commodityUnit = bn.getCommodityUnit();
+                    bn.setTotalNum(unitService.parseStockByUnit(bn.getTotalNum(), unit, commodityUnit));
+                }
+                reslist.add(bn);
+            }
+        }
+        return reslist;
+    }
+
+    /**
+     * 查询某个批号的商品库存
+     * @param depotId
+     * @param barCode
+     * @param batchNumber
+     * @return
+     * @throws Exception
+     */
+    @Override
+    public BigDecimal getOneBatchNumberStock(Long depotId, String barCode, String batchNumber) throws Exception {
+        BigDecimal totalNum = BigDecimal.ZERO;
+        Boolean forceFlag = systemConfigService.getForceApprovalFlag();
+        Boolean inOutManageFlag = systemConfigService.getInOutManageFlag();
+        List<DepotItemVoBatchNumberList> list =  depotItemMapperEx.getBatchNumberList(null, null,
+                depotId, barCode, batchNumber, forceFlag, inOutManageFlag);
+        if(list!=null && list.size()>0) {
+            DepotItemVoBatchNumberList bn = list.get(0);
+            totalNum = bn.getTotalNum();
+            if(bn.getTotalNum()!=null && bn.getTotalNum().compareTo(BigDecimal.ZERO)>0) {
+                if(bn.getUnitId()!=null) {
+                    Unit unit = unitService.getUnit(bn.getUnitId());
+                    String commodityUnit = bn.getCommodityUnit();
+                    totalNum = unitService.parseStockByUnit(bn.getTotalNum(), unit, commodityUnit);
+                }
+            }
+        }
+        return totalNum;
+    }
+
+    @Override
+    public Long getCountByMaterialAndDepot(Long mId, Long depotId) {
+        return depotItemMapperEx.getCountByMaterialAndDepot(mId, depotId);
+    }
+
+    @Override
+    public JSONObject parseMapByExcelData(String barCodes, List<Map<String, String>> detailList, String prefixNo) throws Exception {
+        JSONObject map = new JSONObject();
+        JSONArray arr = new JSONArray();
+        List<MaterialVo4Unit> list = depotItemMapperEx.getBillItemByParam(barCodes);
+        Map<String, MaterialVo4Unit> materialMap = new HashMap<>();
+        Map<String, Long> depotMap = new HashMap<>();
+        for (MaterialVo4Unit material: list) {
+            materialMap.put(material.getmBarCode(), material);
+        }
+        JSONArray depotArr = depotService.findDepotByCurrentUser();
+        for (Object depotObj: depotArr) {
+            if(depotObj!=null) {
+                JSONObject depotObject = JSONObject.parseObject(depotObj.toString());
+                depotMap.put(depotObject.getString("depotName"), depotObject.getLong("id"));
+            }
+        }
+        for (Map<String, String> detailMap: detailList) {
+            JSONObject item = new JSONObject();
+            String barCode = detailMap.get("barCode");
+            if(StringUtil.isNotEmpty(barCode)) {
+                MaterialVo4Unit m = materialMap.get(barCode);
+                if(m!=null) {
+                    //判断仓库是否存在
+                    String depotName = detailMap.get("depotName");
+                    if(StringUtil.isNotEmpty(depotName)) {
+                        if(depotMap.get(depotName)!=null) {
+                            item.put("depotName", depotName);
+                            item.put("depotId", depotMap.get(depotName));
+                        } else {
+                            throw new BusinessRunTimeException(ExceptionConstants.DEPOT_ITEM_DEPOTNAME_IS_NOT_EXIST_CODE,
+                                    String.format(ExceptionConstants.DEPOT_ITEM_DEPOTNAME_IS_NOT_EXIST_MSG, depotName));
+                        }
+                    }
+                    item.put("barCode", barCode);
+                    item.put("name", m.getName());
+                    item.put("standard", m.getStandard());
+                    if(StringUtil.isNotEmpty(m.getModel())) {
+                        item.put("model", m.getModel());
+                    }
+                    if(StringUtil.isNotEmpty(m.getColor())) {
+                        item.put("color", m.getColor());
+                    }
+                    if(StringUtil.isNotEmpty(m.getSku())) {
+                        item.put("sku", m.getSku());
+                    }
+                    BigDecimal stock = BigDecimal.ZERO;
+                    if(StringUtil.isNotEmpty(m.getSku())){
+                        stock = getSkuStockByParam(null, m.getMeId(),null,null);
+                    } else {
+                        stock = getCurrentStockByParam(null, m.getId());
+                    }
+                    item.put("stock", stock);
+                    item.put("unit", m.getCommodityUnit());
+                    BigDecimal operNumber = BigDecimal.ZERO;
+                    BigDecimal unitPrice = BigDecimal.ZERO;
+                    BigDecimal taxRate = BigDecimal.ZERO;
+                    if(StringUtil.isNotEmpty(detailMap.get("num"))) {
+                        operNumber = new BigDecimal(detailMap.get("num"));
+                    }
+                    if(StringUtil.isNotEmpty(detailMap.get("unitPrice"))) {
+                        unitPrice = new BigDecimal(detailMap.get("unitPrice"));
+                    } else {
+                        if("CGDD".equals(prefixNo)) {
+                            unitPrice = m.getPurchaseDecimal();
+                        } else if("XSDD".equals(prefixNo)) {
+                            unitPrice = m.getWholesaleDecimal();
+                        }
+                    }
+                    if(StringUtil.isNotEmpty(detailMap.get("taxRate"))) {
+                        taxRate = new BigDecimal(detailMap.get("taxRate"));
+                    }
+                    String remark = detailMap.get("remark");
+                    item.put("operNumber", operNumber);
+                    item.put("unitPrice", unitPrice);
+                    BigDecimal allPrice = BigDecimal.ZERO;
+                    if(unitPrice!=null && unitPrice.compareTo(BigDecimal.ZERO)!=0) {
+                        allPrice = unitPrice.multiply(operNumber);
+                    }
+                    BigDecimal taxMoney = BigDecimal.ZERO;
+                    if(taxRate.compareTo(BigDecimal.ZERO) != 0) {
+                        taxMoney = taxRate.multiply(allPrice).divide(BigDecimal.valueOf(100), 2, BigDecimal.ROUND_HALF_UP);
+                    }
+                    BigDecimal taxLastMoney = allPrice.add(taxMoney);
+                    item.put("allPrice", allPrice);
+                    item.put("taxRate", taxRate);
+                    item.put("taxMoney", taxMoney);
+                    item.put("taxLastMoney", taxLastMoney);
+                    item.put("remark", remark);
+                    arr.add(item);
+                } else {
+                    throw new BusinessRunTimeException(ExceptionConstants.DEPOT_ITEM_BARCODE_IS_NOT_EXIST_CODE,
+                            String.format(ExceptionConstants.DEPOT_ITEM_BARCODE_IS_NOT_EXIST_MSG, barCode));
+                }
+            }
+        }
+        map.put("rows", arr);
+        return map;
+    }
+
+    @Override
+    public BigDecimal getLastUnitPriceByParam(Long organId, Long meId, String prefixNo) {
+        String type = "";
+        String subType = "";
+        if("XSDD".equals(prefixNo)) {
+            type = "其它";
+            subType = "销售订单";
+        } else if("XSCK".equals(prefixNo)) {
+            type = "出库";
+            subType = "销售";
+        } else if("XSTH".equals(prefixNo)) {
+            type = "入库";
+            subType = "销售退货";
+        } else if("QTCK".equals(prefixNo)) {
+            type = "出库";
+            subType = "其它";
+        }
+        return depotItemMapperEx.getLastUnitPriceByParam(organId, meId, type, subType);
+    }
+
+    @Override
+    public BigDecimal getCurrentStockByParam(Long depotId, Long mId) {
+        BigDecimal stock = depotItemMapperEx.getCurrentStockByParam(depotId, mId);
+        return stock!=null? stock: BigDecimal.ZERO;
+    }
+
+    /**
+     * 获取扩展信息
+     *
+     * @return
+     */
+    @Override
+    public String getOtherInfo(String[] mpArr, DepotItemVo4WithInfoEx diEx)throws Exception {
+        String materialOther = "";
+        for (int i = 0; i < mpArr.length; i++) {
+            if (mpArr[i].equals("自定义1")) {
+                materialOther = materialOther + ((diEx.getMOtherField1() == null || diEx.getMOtherField1().equals("")) ? "" : "(" + diEx.getMOtherField1() + ")");
+            }
+            if (mpArr[i].equals("自定义2")) {
+                materialOther = materialOther + ((diEx.getMOtherField2() == null || diEx.getMOtherField2().equals("")) ? "" : "(" + diEx.getMOtherField2() + ")");
+            }
+            if (mpArr[i].equals("自定义3")) {
+                materialOther = materialOther + ((diEx.getMOtherField3() == null || diEx.getMOtherField3().equals("")) ? "" : "(" + diEx.getMOtherField3() + ")");
+            }
+        }
+        return materialOther;
+    }
+}

+ 9 - 0
src/main/resources/mapper_xml/DepotHeadMapper.xml

@@ -256,6 +256,9 @@
       <if test="deleteFlag != null">
         delete_flag,
       </if>
+      <if test="voucherPicture != null">
+        voucher_picture,
+      </if>
     </trim>
     <trim prefix="values (" suffix=")" suffixOverrides=",">
       <if test="id != null">
@@ -354,6 +357,9 @@
       <if test="deleteFlag != null">
         #{deleteFlag,jdbcType=VARCHAR},
       </if>
+      <if test="voucherPicture != null">
+        #{voucherPicture,jdbcType=VARCHAR},
+      </if>
     </trim>
   </insert>
   <select id="countByExample" parameterType="com.jsh.erp.datasource.entities.DepotHeadExample" resultType="java.lang.Long">
@@ -600,6 +606,9 @@
       <if test="deleteFlag != null">
         delete_flag = #{deleteFlag,jdbcType=VARCHAR},
       </if>
+      <if test="voucherPicture != null">
+        voucher_picture = #{voucherPicture,jdbcType=VARCHAR},
+      </if>
     </set>
     where id = #{id,jdbcType=BIGINT}
   </update>

+ 31 - 0
src/main/resources/mapper_xml/DepotItemMapper.xml

@@ -149,6 +149,7 @@
       #{expirationDate,jdbcType=TIMESTAMP}, #{linkId,jdbcType=BIGINT}, #{tenantId,jdbcType=BIGINT}, 
       #{deleteFlag,jdbcType=VARCHAR})
   </insert>
+
   <insert id="insertSelective" parameterType="com.jsh.erp.datasource.entities.DepotItem">
     insert into jsh_depot_item
     <trim prefix="(" suffix=")" suffixOverrides=",">
@@ -227,6 +228,21 @@
       <if test="deleteFlag != null">
         delete_flag,
       </if>
+      <if test="actualQuantityInStorage != null">
+        actual_quantity_in_storage,
+      </if>
+      <if test="warehousingVariance != null">
+        warehousing_variance,
+      </if>
+      <if test="reasonOfDifference != null">
+        reason_of_difference,
+      </if>
+      <if test="warehousingUser != null">
+        warehousing_user,
+      </if>
+      <if test="warehousingTime != null">
+        warehousing_time,
+      </if>
     </trim>
     <trim prefix="values (" suffix=")" suffixOverrides=",">
       <if test="id != null">
@@ -304,6 +320,21 @@
       <if test="deleteFlag != null">
         #{deleteFlag,jdbcType=VARCHAR},
       </if>
+      <if test="actualQuantityInStorage != null">
+        #{actualQuantityInStorage,jdbcType=DECIMAL},
+      </if>
+      <if test="warehousingVariance != null">
+        #{warehousingVariance,jdbcType=DECIMAL},
+      </if>
+      <if test="reasonOfDifference != null">
+        #{reasonOfDifference,jdbcType=VARCHAR},
+      </if>
+      <if test="warehousingUser != null">
+        #{warehousingUser,jdbcType=BIGINT},
+      </if>
+      <if test="warehousingTime != null">
+        #{warehousingTime,jdbcType=DATE},
+      </if>
     </trim>
   </insert>
   <select id="countByExample" parameterType="com.jsh.erp.datasource.entities.DepotItemExample" resultType="java.lang.Long">