DepotItemServiceImpl.java 81 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576
  1. package com.jsh.erp.service.impl;
  2. import com.alibaba.fastjson.JSONArray;
  3. import com.alibaba.fastjson.JSONObject;
  4. import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  5. import com.jsh.erp.constants.BusinessConstants;
  6. import com.jsh.erp.constants.ExceptionConstants;
  7. import com.jsh.erp.datasource.entities.*;
  8. import com.jsh.erp.datasource.mappers.*;
  9. import com.jsh.erp.datasource.pda.vo.PDADepotItemVO;
  10. import com.jsh.erp.datasource.vo.DepotHeadXsddRequestVO;
  11. import com.jsh.erp.datasource.vo.DepotItemStockWarningCount;
  12. import com.jsh.erp.datasource.vo.DepotItemVo4Stock;
  13. import com.jsh.erp.datasource.vo.DepotItemVoBatchNumberList;
  14. import com.jsh.erp.datasource.vo.DepotItemXsddRequestVO;
  15. import com.jsh.erp.datasource.vo.InOutPriceVo;
  16. import com.jsh.erp.exception.BusinessRunTimeException;
  17. import com.jsh.erp.exception.JshException;
  18. import com.jsh.erp.service.*;
  19. import com.jsh.erp.utils.StringUtil;
  20. import com.jsh.erp.utils.Tools;
  21. import org.slf4j.Logger;
  22. import org.slf4j.LoggerFactory;
  23. import org.springframework.beans.BeanUtils;
  24. import org.springframework.stereotype.Service;
  25. import org.springframework.transaction.annotation.Transactional;
  26. import javax.annotation.Resource;
  27. import javax.servlet.http.HttpServletRequest;
  28. import java.math.BigDecimal;
  29. import java.util.*;
  30. @Service
  31. public class DepotItemServiceImpl extends ServiceImpl<DepotItemMapper, DepotItem> implements DepotItemService {
  32. private Logger logger = LoggerFactory.getLogger(DepotItemServiceImpl.class);
  33. private final static String TYPE = "入库";
  34. private final static String SUM_TYPE = "number";
  35. private final static String IN = "in";
  36. private final static String OUT = "out";
  37. @Resource
  38. private DepotItemMapper depotItemMapper;
  39. @Resource
  40. private DepotItemMapperEx depotItemMapperEx;
  41. @Resource
  42. private MaterialService materialService;
  43. @Resource
  44. private MaterialExtendService materialExtendService;
  45. @Resource
  46. private SerialNumberMapperEx serialNumberMapperEx;
  47. @Resource
  48. private DepotHeadService depotHeadService;
  49. @Resource
  50. private DepotHeadMapper depotHeadMapper;
  51. @Resource
  52. private SerialNumberService serialNumberService;
  53. @Resource
  54. private UserService userService;
  55. @Resource
  56. private SystemConfigService systemConfigService;
  57. @Resource
  58. private DepotService depotService;
  59. @Resource
  60. private UnitService unitService;
  61. @Resource
  62. private MaterialCurrentStockMapper materialCurrentStockMapper;
  63. @Resource
  64. private MaterialCurrentStockMapperEx materialCurrentStockMapperEx;
  65. @Resource
  66. private LogService logService;
  67. @Resource
  68. private MaterialExtendMapper materialExtendMapper;
  69. /**
  70. * pda根据订单信息查询商品列表
  71. * @return
  72. */
  73. @Override
  74. public List<PDADepotItemVO> pdaList(Long id) {
  75. return depotItemMapper.pdaList(id);
  76. }
  77. @Override
  78. public DepotItem getDepotItem(long id)throws Exception {
  79. DepotItem result=null;
  80. try{
  81. result=depotItemMapper.selectByPrimaryKey(id);
  82. }catch(Exception e){
  83. JshException.readFail(logger, e);
  84. }
  85. return result;
  86. }
  87. @Override
  88. public List<DepotItem> getDepotItem()throws Exception {
  89. DepotItemExample example = new DepotItemExample();
  90. example.createCriteria().andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
  91. List<DepotItem> list=null;
  92. try{
  93. list=depotItemMapper.selectByExample(example);
  94. }catch(Exception e){
  95. JshException.readFail(logger, e);
  96. }
  97. return list;
  98. }
  99. @Override
  100. public List<DepotItem> select(String name, Integer type, String remark, int offset, int rows)throws Exception {
  101. List<DepotItem> list=null;
  102. try{
  103. list=depotItemMapperEx.selectByConditionDepotItem(name, type, remark, offset, rows);
  104. }catch(Exception e){
  105. JshException.readFail(logger, e);
  106. }
  107. return list;
  108. }
  109. @Override
  110. public Long countDepotItem(String name, Integer type, String remark) throws Exception{
  111. Long result =null;
  112. try{
  113. result=depotItemMapperEx.countsByDepotItem(name, type, remark);
  114. }catch(Exception e){
  115. JshException.readFail(logger, e);
  116. }
  117. return result;
  118. }
  119. @Override
  120. @Transactional(value = "transactionManager", rollbackFor = Exception.class)
  121. public int insertDepotItem(JSONObject obj, HttpServletRequest request)throws Exception {
  122. DepotItem depotItem = JSONObject.parseObject(obj.toJSONString(), DepotItem.class);
  123. int result =0;
  124. try{
  125. result=depotItemMapper.insertSelective(depotItem);
  126. }catch(Exception e){
  127. JshException.readFail(logger, e);
  128. }
  129. return result;
  130. }
  131. @Override
  132. @Transactional(value = "transactionManager", rollbackFor = Exception.class)
  133. public int updateDepotItem(JSONObject obj, HttpServletRequest request)throws Exception {
  134. DepotItem depotItem = JSONObject.parseObject(obj.toJSONString(), DepotItem.class);
  135. int result =0;
  136. try{
  137. result=depotItemMapper.updateByPrimaryKeySelective(depotItem);
  138. }catch(Exception e){
  139. JshException.readFail(logger, e);
  140. }
  141. return result;
  142. }
  143. @Override
  144. @Transactional(value = "transactionManager", rollbackFor = Exception.class)
  145. public int deleteDepotItem(Long id, HttpServletRequest request)throws Exception {
  146. int result =0;
  147. try{
  148. result=depotItemMapper.deleteByPrimaryKey(id);
  149. }catch(Exception e){
  150. JshException.writeFail(logger, e);
  151. }
  152. return result;
  153. }
  154. @Override
  155. @Transactional(value = "transactionManager", rollbackFor = Exception.class)
  156. public int batchDeleteDepotItem(String ids, HttpServletRequest request)throws Exception {
  157. List<Long> idList = StringUtil.strToLongList(ids);
  158. DepotItemExample example = new DepotItemExample();
  159. example.createCriteria().andIdIn(idList);
  160. int result =0;
  161. try{
  162. result=depotItemMapper.deleteByExample(example);
  163. }catch(Exception e){
  164. JshException.writeFail(logger, e);
  165. }
  166. return result;
  167. }
  168. @Override
  169. public int checkIsNameExist(Long id, String name)throws Exception {
  170. DepotItemExample example = new DepotItemExample();
  171. example.createCriteria().andIdNotEqualTo(id).andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
  172. List<DepotItem> list =null;
  173. try{
  174. list=depotItemMapper.selectByExample(example);
  175. }catch(Exception e){
  176. JshException.readFail(logger, e);
  177. }
  178. return list==null?0:list.size();
  179. }
  180. @Override
  181. public List<DepotItemVo4DetailByTypeAndMId> findDetailByDepotIdsAndMaterialIdList(String depotIds, Boolean forceFlag, Boolean inOutManageFlag, String sku, String batchNumber,
  182. String number, String beginTime, String endTime, Long mId, Integer offset, Integer rows)throws Exception {
  183. Long depotId = null;
  184. if(StringUtil.isNotEmpty(depotIds)) {
  185. depotId = Long.parseLong(depotIds);
  186. }
  187. List<Long> depotList = depotService.parseDepotList(depotId);
  188. Long[] depotIdArray = StringUtil.listToLongArray(depotList);
  189. List<DepotItemVo4DetailByTypeAndMId> list =null;
  190. try{
  191. list = depotItemMapperEx.findDetailByDepotIdsAndMaterialIdList(depotIdArray, forceFlag, inOutManageFlag, sku, batchNumber, number, beginTime, endTime, mId, offset, rows);
  192. }catch(Exception e){
  193. JshException.readFail(logger, e);
  194. }
  195. return list;
  196. }
  197. @Override
  198. public Long findDetailByDepotIdsAndMaterialIdCount(String depotIds, Boolean forceFlag, Boolean inOutManageFlag, String sku, String batchNumber,
  199. String number, String beginTime, String endTime, Long mId)throws Exception {
  200. Long depotId = null;
  201. if(StringUtil.isNotEmpty(depotIds)) {
  202. depotId = Long.parseLong(depotIds);
  203. }
  204. List<Long> depotList = depotService.parseDepotList(depotId);
  205. Long[] depotIdArray = StringUtil.listToLongArray(depotList);
  206. Long result =null;
  207. try{
  208. result = depotItemMapperEx.findDetailByDepotIdsAndMaterialIdCount(depotIdArray, forceFlag, inOutManageFlag, sku, batchNumber, number, beginTime, endTime, mId);
  209. }catch(Exception e){
  210. JshException.readFail(logger, e);
  211. }
  212. return result;
  213. }
  214. /**
  215. * 插入单据子表
  216. * @param depotItem 单据子表
  217. */
  218. @Override
  219. @Transactional(value = "transactionManager", rollbackFor = Exception.class)
  220. public int insertDepotItemWithObj(DepotItem depotItem)throws Exception {
  221. int result =0;
  222. try{
  223. result = depotItemMapper.insertSelective(depotItem);
  224. }catch(Exception e){
  225. JshException.writeFail(logger, e);
  226. }
  227. return result;
  228. }
  229. @Override
  230. @Transactional(value = "transactionManager", rollbackFor = Exception.class)
  231. public int updateDepotItemWithObj(DepotItem depotItem)throws Exception {
  232. int result =0;
  233. try{
  234. result = depotItemMapper.updateByPrimaryKeySelective(depotItem);
  235. }catch(Exception e){
  236. JshException.writeFail(logger, e);
  237. }
  238. return result;
  239. }
  240. @Override
  241. public List<DepotItem> getListByHeaderId(Long headerId)throws Exception {
  242. List<DepotItem> list =null;
  243. try{
  244. DepotItemExample example = new DepotItemExample();
  245. example.createCriteria().andHeaderIdEqualTo(headerId).andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
  246. list = depotItemMapper.selectByExample(example);
  247. }catch(Exception e){
  248. JshException.readFail(logger, e);
  249. }
  250. return list;
  251. }
  252. /**
  253. * 查询当前单据中指定商品的明细信息
  254. * @param headerId
  255. * @param meId
  256. * @return
  257. * @throws Exception
  258. */
  259. @Override
  260. public DepotItem getItemByHeaderIdAndMaterial(Long headerId, Long meId)throws Exception {
  261. DepotItem depotItem = new DepotItem();
  262. try{
  263. DepotItemExample example = new DepotItemExample();
  264. example.createCriteria().andHeaderIdEqualTo(headerId).andMaterialExtendIdEqualTo(meId).andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
  265. List<DepotItem> list = depotItemMapper.selectByExample(example);
  266. if(list!=null && list.size()>0) {
  267. depotItem = list.get(0);
  268. }
  269. }catch(Exception e){
  270. JshException.readFail(logger, e);
  271. }
  272. return depotItem;
  273. }
  274. /**
  275. * 查询被关联订单中指定商品的明细信息
  276. * @param linkStr
  277. * @param meId
  278. * @return
  279. * @throws Exception
  280. */
  281. @Override
  282. public DepotItem getPreItemByHeaderIdAndMaterial(String linkStr, Long meId, Long linkId)throws Exception {
  283. DepotItem depotItem = new DepotItem();
  284. try{
  285. DepotHead depotHead = depotHeadService.getDepotHead(linkStr);
  286. if(null!=depotHead && null!=depotHead.getId()) {
  287. DepotItemExample example = new DepotItemExample();
  288. example.createCriteria().andHeaderIdEqualTo(depotHead.getId()).andMaterialExtendIdEqualTo(meId).andIdEqualTo(linkId).andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
  289. List<DepotItem> list = depotItemMapper.selectByExample(example);
  290. if(list!=null && list.size()>0) {
  291. depotItem = list.get(0);
  292. }
  293. }
  294. }catch(Exception e){
  295. JshException.readFail(logger, e);
  296. }
  297. return depotItem;
  298. }
  299. @Override
  300. public List<DepotItemVo4WithInfoEx> getDetailList(Long headerId)throws Exception {
  301. List<DepotItemVo4WithInfoEx> list =null;
  302. try{
  303. list = depotItemMapperEx.getDetailList(headerId);
  304. }catch(Exception e){
  305. JshException.readFail(logger, e);
  306. }
  307. return list;
  308. }
  309. @Override
  310. public List<DepotItemVo4WithInfoEx> getInOutStock(String materialParam, List<Long> categoryIdList, String endTime, Integer offset, Integer rows)throws Exception {
  311. List<DepotItemVo4WithInfoEx> list =null;
  312. try{
  313. list = depotItemMapperEx.getInOutStock(materialParam, categoryIdList, endTime, offset, rows);
  314. }catch(Exception e){
  315. JshException.readFail(logger, e);
  316. }
  317. return list;
  318. }
  319. @Override
  320. public int getInOutStockCount(String materialParam, List<Long> categoryIdList, String endTime)throws Exception {
  321. int result=0;
  322. try{
  323. result = depotItemMapperEx.getInOutStockCount(materialParam, categoryIdList, endTime);
  324. }catch(Exception e){
  325. JshException.readFail(logger, e);
  326. }
  327. return result;
  328. }
  329. @Override
  330. public List<DepotItemVo4WithInfoEx> getListWithBuyOrSale(String materialParam, String billType,
  331. String beginTime, String endTime, String[] creatorArray, Long organId, String[] organArray, List<Long> categoryList, List<Long> depotList, Boolean forceFlag, Integer offset, Integer rows)throws Exception {
  332. List<DepotItemVo4WithInfoEx> list =null;
  333. try{
  334. list = depotItemMapperEx.getListWithBuyOrSale(materialParam, billType, beginTime, endTime, creatorArray, organId, organArray, categoryList, depotList, forceFlag, offset, rows);
  335. }catch(Exception e){
  336. JshException.readFail(logger, e);
  337. }
  338. return list;
  339. }
  340. @Override
  341. public int getListWithBuyOrSaleCount(String materialParam, String billType,
  342. String beginTime, String endTime, String[] creatorArray, Long organId, String[] organArray, List<Long> categoryList, List<Long> depotList, Boolean forceFlag)throws Exception {
  343. int result=0;
  344. try{
  345. result = depotItemMapperEx.getListWithBuyOrSaleCount(materialParam, billType, beginTime, endTime, creatorArray, organId, organArray, categoryList, depotList, forceFlag);
  346. }catch(Exception e){
  347. JshException.readFail(logger, e);
  348. }
  349. return result;
  350. }
  351. @Override
  352. public BigDecimal buyOrSale(String type, String subType, Long MId, String beginTime, String endTime,
  353. String[] creatorArray, Long organId, String[] organArray, List<Long> depotList, Boolean forceFlag, String sumType) throws Exception{
  354. BigDecimal result= BigDecimal.ZERO;
  355. try{
  356. if (SUM_TYPE.equals(sumType)) {
  357. result= depotItemMapperEx.buyOrSaleNumber(type, subType, MId, beginTime, endTime, creatorArray, organId, organArray, depotList, forceFlag, sumType);
  358. } else {
  359. result= depotItemMapperEx.buyOrSalePrice(type, subType, MId, beginTime, endTime, creatorArray, organId, organArray, depotList, forceFlag, sumType);
  360. }
  361. }catch(Exception e){
  362. JshException.readFail(logger, e);
  363. }
  364. return result;
  365. }
  366. @Override
  367. public BigDecimal buyOrSalePriceTotal(String type, String subType, String materialParam, String beginTime, String endTime,
  368. String[] creatorArray, Long organId, String[] organArray, List<Long> categoryList, List<Long> depotList, Boolean forceFlag) throws Exception{
  369. BigDecimal result= BigDecimal.ZERO;
  370. try{
  371. result= depotItemMapperEx.buyOrSalePriceTotal(type, subType, materialParam, beginTime, endTime, creatorArray, organId, organArray, categoryList, depotList, forceFlag);
  372. }catch(Exception e){
  373. JshException.readFail(logger, e);
  374. }
  375. return result;
  376. }
  377. /**
  378. * 统计采购、销售、零售的总金额列表
  379. * @param beginTime
  380. * @param endTime
  381. * @return
  382. * @throws Exception
  383. */
  384. @Override
  385. public List<InOutPriceVo> inOrOutPriceList(String beginTime, String endTime) throws Exception{
  386. List<InOutPriceVo> result = new ArrayList<>();
  387. try{
  388. String [] creatorArray = depotHeadService.getCreatorArray();
  389. Boolean forceFlag = systemConfigService.getForceApprovalFlag();
  390. result = depotItemMapperEx.inOrOutPriceList(beginTime, endTime, creatorArray, forceFlag);
  391. }catch(Exception e){
  392. JshException.readFail(logger, e);
  393. }
  394. return result;
  395. }
  396. /**
  397. * 保存单据子表
  398. * @param rows 子表数据字符
  399. * @param headerId 单据主表id
  400. * @param actionType 操作类型
  401. */
  402. @Override
  403. @Transactional(value = "transactionManager", rollbackFor = Exception.class)
  404. public void saveDetials(String rows, Long headerId, String actionType, HttpServletRequest request) throws Exception{
  405. //查询单据主表信息
  406. DepotHead depotHead =depotHeadMapper.selectByPrimaryKey(headerId);
  407. //删除序列号和回收序列号
  408. deleteOrCancelSerialNumber(actionType, depotHead, headerId);
  409. //删除单据的明细
  410. deleteDepotItemHeadId(headerId);
  411. JSONArray rowArr = JSONArray.parseArray(rows);
  412. if (null != rowArr && rowArr.size()>0) {
  413. //针对组装单、拆卸单校验是否存在组合件和普通子件
  414. checkAssembleWithMaterialType(rowArr, depotHead.getSubType());
  415. for (int i = 0; i < rowArr.size(); i++) {
  416. DepotItem depotItem = new DepotItem();
  417. JSONObject rowObj = JSONObject.parseObject(rowArr.getString(i));
  418. depotItem.setHeaderId(headerId);
  419. String batchNumber = rowObj.getString("batchNumber");
  420. MaterialExtend materialExtend = materialExtendService.getInfoByBatchNumber(batchNumber);
  421. if(materialExtend == null) {
  422. throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_BARCODE_IS_NOT_EXIST_CODE,
  423. String.format(ExceptionConstants.MATERIAL_BARCODE_IS_NOT_EXIST_MSG, batchNumber));
  424. }
  425. depotItem.setMaterialId(materialExtend.getMaterialId());
  426. depotItem.setMaterialExtendId(materialExtend.getId());
  427. depotItem.setMaterialUnit(rowObj.getString("unit"));
  428. depotItem.setActualQuantityInStorage(rowObj.getBigDecimal("actualQuantityInStorage"));
  429. depotItem.setWarehousingVariance(rowObj.getBigDecimal("warehousingVariance"));
  430. depotItem.setReasonOfDifference(rowObj.getString("reasonOfDifference"));
  431. depotItem.setWarehousingUser(rowObj.getLong("warehousingUser"));
  432. depotItem.setWarehousingTime(rowObj.getDate("warehousingTime"));
  433. Material material= materialService.getMaterial(depotItem.getMaterialId());
  434. if (BusinessConstants.ENABLE_SERIAL_NUMBER_ENABLED.equals(material.getEnableSerialNumber()) ||
  435. BusinessConstants.ENABLE_BATCH_NUMBER_ENABLED.equals(material.getEnableBatchNumber())) {
  436. //组装拆卸单不能选择批号或序列号商品
  437. if(BusinessConstants.SUB_TYPE_ASSEMBLE.equals(depotHead.getSubType()) ||
  438. BusinessConstants.SUB_TYPE_DISASSEMBLE.equals(depotHead.getSubType())) {
  439. throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_ASSEMBLE_SELECT_ERROR_CODE,
  440. String.format(ExceptionConstants.MATERIAL_ASSEMBLE_SELECT_ERROR_MSG, batchNumber));
  441. }
  442. //调拨单不能选择批号或序列号商品(该场景走出库和入库单)
  443. if(BusinessConstants.SUB_TYPE_TRANSFER.equals(depotHead.getSubType())) {
  444. throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_TRANSFER_SELECT_ERROR_CODE,
  445. String.format(ExceptionConstants.MATERIAL_TRANSFER_SELECT_ERROR_MSG, batchNumber));
  446. }
  447. //盘点业务不能选择批号或序列号商品(该场景走出库和入库单)
  448. if(BusinessConstants.SUB_TYPE_CHECK_ENTER.equals(depotHead.getSubType())
  449. ||BusinessConstants.SUB_TYPE_REPLAY.equals(depotHead.getSubType())) {
  450. throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_STOCK_CHECK_ERROR_CODE,
  451. String.format(ExceptionConstants.MATERIAL_STOCK_CHECK_ERROR_MSG, batchNumber));
  452. }
  453. }
  454. if (StringUtil.isExist(rowObj.get("snList"))) {
  455. depotItem.setSnList(rowObj.getString("snList"));
  456. if(StringUtil.isExist(rowObj.get("depotId"))) {
  457. String [] snArray = depotItem.getSnList().split(",");
  458. int operNum = rowObj.getInteger("operNumber");
  459. if(snArray.length == operNum) {
  460. Long depotId = rowObj.getLong("depotId");
  461. BigDecimal inPrice = BigDecimal.ZERO;
  462. if (StringUtil.isExist(rowObj.get("unitPrice"))) {
  463. inPrice = rowObj.getBigDecimal("unitPrice");
  464. }
  465. serialNumberService.addSerialNumberByBill(depotHead.getType(), depotHead.getSubType(),
  466. depotHead.getNumber(), materialExtend.getMaterialId(), depotId, inPrice, depotItem.getSnList());
  467. } else {
  468. throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_SN_NUMBERE_FAILED_CODE,
  469. String.format(ExceptionConstants.DEPOT_HEAD_SN_NUMBERE_FAILED_MSG, batchNumber));
  470. }
  471. }
  472. } else {
  473. //入库或出库
  474. if (BusinessConstants.DEPOTHEAD_TYPE_IN.equals(depotHead.getType()) ||
  475. BusinessConstants.DEPOTHEAD_TYPE_OUT.equals(depotHead.getType())) {
  476. //序列号不能为空
  477. if (BusinessConstants.ENABLE_SERIAL_NUMBER_ENABLED.equals(material.getEnableSerialNumber())) {
  478. //如果开启出入库管理,并且类型等于采购、采购退货、销售、销售退货,则跳过
  479. if(systemConfigService.getInOutManageFlag() &&
  480. (BusinessConstants.SUB_TYPE_PURCHASE.equals(depotHead.getSubType())
  481. ||BusinessConstants.SUB_TYPE_PURCHASE_RETURN.equals(depotHead.getSubType())
  482. ||BusinessConstants.SUB_TYPE_SALES.equals(depotHead.getSubType())
  483. ||BusinessConstants.SUB_TYPE_SALES_RETURN.equals(depotHead.getSubType()))) {
  484. //跳过
  485. } else {
  486. throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_SERIAL_NUMBERE_EMPTY_CODE,
  487. String.format(ExceptionConstants.MATERIAL_SERIAL_NUMBERE_EMPTY_MSG, batchNumber));
  488. }
  489. }
  490. }
  491. }
  492. if (StringUtil.isExist(rowObj.get("batchNumber"))) {
  493. depotItem.setBatchNumber(rowObj.getString("batchNumber"));
  494. } else {
  495. //入库或出库
  496. if(BusinessConstants.DEPOTHEAD_TYPE_IN.equals(depotHead.getType()) ||
  497. BusinessConstants.DEPOTHEAD_TYPE_OUT.equals(depotHead.getType())) {
  498. //批号不能为空
  499. if (BusinessConstants.ENABLE_BATCH_NUMBER_ENABLED.equals(material.getEnableBatchNumber())) {
  500. //如果开启出入库管理,并且类型等于采购、采购退货、销售、销售退货,则跳过
  501. if(systemConfigService.getInOutManageFlag() &&
  502. (BusinessConstants.SUB_TYPE_PURCHASE.equals(depotHead.getSubType())
  503. ||BusinessConstants.SUB_TYPE_PURCHASE_RETURN.equals(depotHead.getSubType())
  504. ||BusinessConstants.SUB_TYPE_SALES.equals(depotHead.getSubType())
  505. ||BusinessConstants.SUB_TYPE_SALES_RETURN.equals(depotHead.getSubType()))) {
  506. //跳过
  507. } else {
  508. throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_BATCH_NUMBERE_EMPTY_CODE,
  509. String.format(ExceptionConstants.DEPOT_HEAD_BATCH_NUMBERE_EMPTY_MSG, batchNumber));
  510. }
  511. }
  512. }
  513. }
  514. if (StringUtil.isExist(rowObj.get("expirationDate"))) {
  515. depotItem.setExpirationDate(rowObj.getDate("expirationDate"));
  516. }
  517. if (StringUtil.isExist(rowObj.get("sku"))) {
  518. depotItem.setSku(rowObj.getString("sku"));
  519. }
  520. if (StringUtil.isExist(rowObj.get("linkId"))) {
  521. depotItem.setLinkId(rowObj.getLong("linkId"));
  522. }
  523. //以下进行单位换算
  524. Unit unitInfo = materialService.findUnit(materialExtend.getMaterialId()); //查询多单位信息
  525. if (StringUtil.isExist(rowObj.get("operNumber"))) {
  526. //获取子表单商品数量
  527. depotItem.setOperNumber(rowObj.getBigDecimal("operNumber"));
  528. //获取子表单商品单位
  529. String unit = rowObj.get("unit") == null ? "" :rowObj.get("unit").toString();
  530. BigDecimal oNumber = rowObj.getBigDecimal("operNumber");
  531. if (StringUtil.isNotEmpty(unitInfo.getName())) {
  532. String basicUnit = unitInfo.getBasicUnit(); //基本单位
  533. if (unit.equals(basicUnit)) { //如果等于基本单位
  534. depotItem.setBasicNumber(oNumber); //数量一致
  535. } else if (unit.equals(unitInfo.getOtherUnit())) { //如果等于副单位
  536. depotItem.setBasicNumber(oNumber.multiply(unitInfo.getRatio())); //数量乘以比例
  537. } else if (unit.equals(unitInfo.getOtherUnitTwo())) { //如果等于副单位2
  538. depotItem.setBasicNumber(oNumber.multiply(unitInfo.getRatioTwo())); //数量乘以比例
  539. } else if (unit.equals(unitInfo.getOtherUnitThree())) { //如果等于副单位3
  540. depotItem.setBasicNumber(oNumber.multiply(unitInfo.getRatioThree())); //数量乘以比例
  541. } else {
  542. depotItem.setBasicNumber(oNumber); //数量一致
  543. }
  544. } else {
  545. depotItem.setBasicNumber(oNumber); //其他情况
  546. }
  547. }
  548. //如果数量+已完成数量>原订单数量,给出预警(判断前提是存在关联订单|关联请购单)
  549. String linkStr = StringUtil.isNotEmpty(depotHead.getLinkNumber())? depotHead.getLinkNumber(): depotHead.getLinkApply();
  550. if (StringUtil.isNotEmpty(linkStr) && StringUtil.isExist(rowObj.get("preNumber")) && StringUtil.isExist(rowObj.get("finishNumber"))) {
  551. if("add".equals(actionType)) {
  552. //在新增模式进行状态赋值
  553. BigDecimal preNumber = rowObj.getBigDecimal("preNumber");
  554. BigDecimal finishNumber = rowObj.getBigDecimal("finishNumber");
  555. if(depotItem.getOperNumber().add(finishNumber).compareTo(preNumber)>0) {
  556. if(!systemConfigService.getOverLinkBillFlag()) {
  557. throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_NUMBER_NEED_EDIT_FAILED_CODE,
  558. String.format(ExceptionConstants.DEPOT_HEAD_NUMBER_NEED_EDIT_FAILED_MSG, batchNumber));
  559. }
  560. }
  561. } else if("update".equals(actionType)) {
  562. //当前单据的类型
  563. String currentSubType = depotHead.getSubType();
  564. //在更新模式进行状态赋值
  565. String unit = rowObj.get("unit").toString();
  566. Long preHeaderId = depotHeadService.getDepotHead(linkStr).getId();
  567. if(null!=preHeaderId) {
  568. //前一个单据的数量
  569. BigDecimal preNumber = getPreItemByHeaderIdAndMaterial(linkStr, depotItem.getMaterialExtendId(), depotItem.getLinkId()).getOperNumber();
  570. //除去此单据之外的已入库|已出库
  571. BigDecimal realFinishNumber = getRealFinishNumber(currentSubType, depotItem.getMaterialExtendId(), depotItem.getLinkId(), preHeaderId, headerId, unitInfo, unit);
  572. if(preNumber!=null) {
  573. if (depotItem.getOperNumber().add(realFinishNumber).compareTo(preNumber) > 0) {
  574. if (!systemConfigService.getOverLinkBillFlag()) {
  575. throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_NUMBER_NEED_EDIT_FAILED_CODE,
  576. String.format(ExceptionConstants.DEPOT_HEAD_NUMBER_NEED_EDIT_FAILED_MSG, batchNumber));
  577. }
  578. }
  579. } else {
  580. throw new BusinessRunTimeException(ExceptionConstants.DEPOT_ITEM_PRE_BILL_IS_CHANGE_CODE,
  581. ExceptionConstants.DEPOT_ITEM_PRE_BILL_IS_CHANGE_MSG);
  582. }
  583. }
  584. }
  585. }
  586. if (StringUtil.isExist(rowObj.get("unitPrice"))) {
  587. BigDecimal unitPrice = rowObj.getBigDecimal("unitPrice");
  588. depotItem.setUnitPrice(unitPrice);
  589. if(materialExtend.getLowDecimal()!=null) {
  590. //零售或销售单价低于最低售价,进行提示
  591. if("零售".equals(depotHead.getSubType()) || "销售".equals(depotHead.getSubType())) {
  592. if (unitPrice.compareTo(materialExtend.getLowDecimal()) < 0) {
  593. throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_UNIT_PRICE_LOW_CODE,
  594. String.format(ExceptionConstants.DEPOT_HEAD_UNIT_PRICE_LOW_MSG, batchNumber));
  595. }
  596. }
  597. }
  598. }
  599. //如果是销售出库、销售退货、零售出库、零售退货则给采购单价字段赋值(如果是批次商品,则要根据批号去找之前的入库价)
  600. if(BusinessConstants.SUB_TYPE_SALES.equals(depotHead.getSubType()) ||
  601. BusinessConstants.SUB_TYPE_SALES_RETURN.equals(depotHead.getSubType()) ||
  602. BusinessConstants.SUB_TYPE_RETAIL.equals(depotHead.getSubType()) ||
  603. BusinessConstants.SUB_TYPE_RETAIL_RETURN.equals(depotHead.getSubType())) {
  604. boolean moveAvgPriceFlag = systemConfigService.getMoveAvgPriceFlag();
  605. BigDecimal currentUnitPrice = materialCurrentStockMapperEx.getCurrentUnitPriceByMId(materialExtend.getMaterialId());
  606. currentUnitPrice = unitService.parseUnitPriceByUnit(currentUnitPrice, unitInfo, depotItem.getMaterialUnit());
  607. BigDecimal unitPrice = moveAvgPriceFlag? currentUnitPrice: materialExtend.getPurchaseDecimal();
  608. depotItem.setPurchaseUnitPrice(unitPrice);
  609. if(StringUtil.isNotEmpty(depotItem.getBatchNumber())) {
  610. depotItem.setPurchaseUnitPrice(getDepotItemByBatchNumber(depotItem.getMaterialExtendId(),depotItem.getBatchNumber()).getUnitPrice());
  611. }
  612. }
  613. if (StringUtil.isExist(rowObj.get("taxUnitPrice"))) {
  614. depotItem.setTaxUnitPrice(rowObj.getBigDecimal("taxUnitPrice"));
  615. }
  616. if (StringUtil.isExist(rowObj.get("allPrice"))) {
  617. depotItem.setAllPrice(rowObj.getBigDecimal("allPrice"));
  618. }
  619. if (StringUtil.isExist(rowObj.get("depotId"))) {
  620. depotItem.setDepotId(rowObj.getLong("depotId"));
  621. } else {
  622. if(!BusinessConstants.SUB_TYPE_PURCHASE_APPLY.equals(depotHead.getSubType())
  623. && !BusinessConstants.SUB_TYPE_PURCHASE_ORDER.equals(depotHead.getSubType())
  624. && !BusinessConstants.SUB_TYPE_SALES_ORDER.equals(depotHead.getSubType())) {
  625. throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_DEPOT_FAILED_CODE,
  626. String.format(ExceptionConstants.DEPOT_HEAD_DEPOT_FAILED_MSG));
  627. }
  628. }
  629. if(BusinessConstants.SUB_TYPE_TRANSFER.equals(depotHead.getSubType())) {
  630. if (StringUtil.isExist(rowObj.get("anotherDepotId"))) {
  631. if(rowObj.getLong("anotherDepotId").equals(rowObj.getLong("depotId"))) {
  632. throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_ANOTHER_DEPOT_EQUAL_FAILED_CODE,
  633. String.format(ExceptionConstants.DEPOT_HEAD_ANOTHER_DEPOT_EQUAL_FAILED_MSG));
  634. } else {
  635. depotItem.setAnotherDepotId(rowObj.getLong("anotherDepotId"));
  636. }
  637. } else {
  638. throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_ANOTHER_DEPOT_FAILED_CODE,
  639. String.format(ExceptionConstants.DEPOT_HEAD_ANOTHER_DEPOT_FAILED_MSG));
  640. }
  641. }
  642. if (StringUtil.isExist(rowObj.get("taxRate"))) {
  643. depotItem.setTaxRate(rowObj.getBigDecimal("taxRate"));
  644. }
  645. if (StringUtil.isExist(rowObj.get("taxMoney"))) {
  646. depotItem.setTaxMoney(rowObj.getBigDecimal("taxMoney"));
  647. }
  648. if (StringUtil.isExist(rowObj.get("taxLastMoney"))) {
  649. depotItem.setTaxLastMoney(rowObj.getBigDecimal("taxLastMoney"));
  650. }
  651. if (StringUtil.isExist(rowObj.get("mType"))) {
  652. depotItem.setMaterialType(rowObj.getString("mType"));
  653. }
  654. if (StringUtil.isExist(rowObj.get("remark"))) {
  655. depotItem.setRemark(rowObj.getString("remark"));
  656. }
  657. //出库时判断库存是否充足
  658. if(BusinessConstants.DEPOTHEAD_TYPE_OUT.equals(depotHead.getType())){
  659. String stockMsg = material.getName() + "-" + batchNumber;
  660. BigDecimal stock = getCurrentStockByParam(depotItem.getDepotId(),depotItem.getMaterialId());
  661. if(StringUtil.isNotEmpty(depotItem.getSku())) {
  662. //对于sku商品要换个方式计算库存
  663. stock = getSkuStockByParam(depotItem.getDepotId(),depotItem.getMaterialExtendId(),null,null);
  664. }
  665. if(StringUtil.isNotEmpty(depotItem.getBatchNumber())) {
  666. //对于批次商品要换个方式计算库存
  667. stock = getOneBatchNumberStock(depotItem.getDepotId(), batchNumber, depotItem.getBatchNumber());
  668. stockMsg += "-批号" + depotItem.getBatchNumber();
  669. }
  670. BigDecimal thisRealNumber = depotItem.getBasicNumber()==null?BigDecimal.ZERO:depotItem.getBasicNumber();
  671. if(StringUtil.isNotEmpty(depotItem.getBatchNumber())) {
  672. //对于批次商品,直接使用当前填写的数量
  673. thisRealNumber = depotItem.getOperNumber()==null?BigDecimal.ZERO:depotItem.getOperNumber();
  674. }
  675. if(!systemConfigService.getMinusStockFlag() && stock.compareTo(thisRealNumber)<0){
  676. throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_STOCK_NOT_ENOUGH_CODE,
  677. String.format(ExceptionConstants.MATERIAL_STOCK_NOT_ENOUGH_MSG, stockMsg));
  678. }
  679. //出库时处理序列号
  680. if(!BusinessConstants.SUB_TYPE_TRANSFER.equals(depotHead.getSubType())) {
  681. //判断商品是否开启序列号,开启的售出序列号,未开启的跳过
  682. if(BusinessConstants.ENABLE_SERIAL_NUMBER_ENABLED.equals(material.getEnableSerialNumber())) {
  683. //如果开启出入库管理,并且类型等于采购、采购退货、销售、销售退货,则跳过
  684. if(systemConfigService.getInOutManageFlag() &&
  685. (BusinessConstants.SUB_TYPE_PURCHASE.equals(depotHead.getSubType())
  686. ||BusinessConstants.SUB_TYPE_PURCHASE_RETURN.equals(depotHead.getSubType())
  687. ||BusinessConstants.SUB_TYPE_SALES.equals(depotHead.getSubType())
  688. ||BusinessConstants.SUB_TYPE_SALES_RETURN.equals(depotHead.getSubType()))) {
  689. //跳过
  690. } else {
  691. //售出序列号,获得当前操作人
  692. User userInfo = userService.getCurrentUser();
  693. serialNumberService.checkAndUpdateSerialNumber(depotItem, depotHead.getNumber(), userInfo, StringUtil.toNull(depotItem.getSnList()));
  694. }
  695. }
  696. }
  697. }
  698. this.insertDepotItemWithObj(depotItem);
  699. //更新当前库存
  700. updateCurrentStock(depotItem);
  701. //更新当前成本价
  702. updateCurrentUnitPrice(depotItem);
  703. //更新商品的价格
  704. updateMaterialExtendPrice(materialExtend.getId(), depotHead.getSubType(), depotHead.getBillType(), rowObj);
  705. }
  706. //如果关联单据号非空则更新订单的状态,单据类型:采购入库单、销售出库单、盘点复盘单、其它入库单、其它出库单
  707. if(BusinessConstants.SUB_TYPE_PURCHASE.equals(depotHead.getSubType())
  708. || BusinessConstants.SUB_TYPE_SALES.equals(depotHead.getSubType())
  709. || BusinessConstants.SUB_TYPE_REPLAY.equals(depotHead.getSubType())
  710. || BusinessConstants.SUB_TYPE_OTHER.equals(depotHead.getSubType())) {
  711. if(StringUtil.isNotEmpty(depotHead.getLinkNumber())) {
  712. //单据状态:是否全部完成 2-全部完成 3-部分完成(针对订单的分批出入库)
  713. String billStatus = getBillStatusByParam(depotHead, depotHead.getLinkNumber(), "normal");
  714. changeBillStatus(depotHead.getLinkNumber(), billStatus);
  715. }
  716. }
  717. //当前单据类型为采购订单的逻辑
  718. if(BusinessConstants.SUB_TYPE_PURCHASE_ORDER.equals(depotHead.getSubType())) {
  719. //如果关联单据号非空则更新订单的状态,此处针对销售订单转采购订单的场景
  720. if(StringUtil.isNotEmpty(depotHead.getLinkNumber())) {
  721. String billStatus = getBillStatusByParam(depotHead, depotHead.getLinkNumber(), "normal");
  722. changeBillPurchaseStatus(depotHead.getLinkNumber(), billStatus);
  723. }
  724. //如果关联单据号非空则更新订单的状态,此处针对请购单转采购订单的场景
  725. if(StringUtil.isNotEmpty(depotHead.getLinkApply())) {
  726. String billStatus = getBillStatusByParam(depotHead, depotHead.getLinkApply(), "apply");
  727. changeBillStatus(depotHead.getLinkApply(), billStatus);
  728. }
  729. }
  730. } else {
  731. throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_ROW_FAILED_CODE,
  732. String.format(ExceptionConstants.DEPOT_HEAD_ROW_FAILED_MSG));
  733. }
  734. }
  735. @Override
  736. @Transactional(value = "transactionManager", rollbackFor = Exception.class)
  737. public void saveOrderItem(DepotHeadXsddRequestVO order, List<DepotItemXsddRequestVO> itemList) throws Exception {
  738. // 查询单据主表信息
  739. DepotHead depotHead = depotHeadMapper.selectByPrimaryKey(order.getId());
  740. if (depotHead == null) {
  741. throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_NOT_EXIST_CODE, String.format(ExceptionConstants.DEPOT_HEAD_NOT_EXIST_MSG));
  742. }
  743. if (null != itemList && itemList.size() > 0) {
  744. for (DepotItemXsddRequestVO item : itemList) {
  745. DepotItem depotItem = new DepotItem();
  746. BeanUtils.copyProperties(item, depotItem);
  747. // 以下进行单位换算
  748. Unit unitInfo = materialService.findUnit(depotItem.getMaterialId()); // 查询多单位信息
  749. if (depotItem.getOperNumber() != null) {
  750. // 获取子表单商品单位
  751. String unit = depotItem.getMaterialUnit() == null ? "" : depotItem.getMaterialUnit();
  752. BigDecimal oNumber = depotItem.getOperNumber();
  753. if (StringUtil.isNotEmpty(unitInfo.getName())) {
  754. String basicUnit = unitInfo.getBasicUnit(); // 基本单位
  755. if (unit.equals(basicUnit)) { // 如果等于基本单位
  756. depotItem.setBasicNumber(oNumber); // 数量一致
  757. } else if (unit.equals(unitInfo.getOtherUnit())) { // 如果等于副单位
  758. depotItem.setBasicNumber(oNumber.multiply(unitInfo.getRatio())); // 数量乘以比例
  759. } else if (unit.equals(unitInfo.getOtherUnitTwo())) { // 如果等于副单位2
  760. depotItem.setBasicNumber(oNumber.multiply(unitInfo.getRatioTwo())); // 数量乘以比例
  761. } else if (unit.equals(unitInfo.getOtherUnitThree())) { // 如果等于副单位3
  762. depotItem.setBasicNumber(oNumber.multiply(unitInfo.getRatioThree())); // 数量乘以比例
  763. } else {
  764. depotItem.setBasicNumber(oNumber); // 数量一致
  765. }
  766. } else {
  767. depotItem.setBasicNumber(oNumber); // 其他情况
  768. }
  769. }
  770. this.insertDepotItemWithObj(depotItem);
  771. // 更新当前库存
  772. updateCurrentStock(depotItem);
  773. }
  774. } else {
  775. throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_ROW_FAILED_CODE, String.format(ExceptionConstants.DEPOT_HEAD_ROW_FAILED_MSG));
  776. }
  777. }
  778. /**
  779. * 判断单据的状态
  780. * 通过数组对比:原单据的商品和商品数量(汇总) 与 分批操作后单据的商品和商品数量(汇总)
  781. * @param depotHead
  782. * @param linkStr
  783. * @return
  784. */
  785. @Override
  786. @Transactional(value = "transactionManager", rollbackFor = Exception.class)
  787. public String getBillStatusByParam(DepotHead depotHead, String linkStr, String linkType) {
  788. String res = BusinessConstants.BILLS_STATUS_SKIPED;
  789. //获取原单据的商品和商品数量(汇总)
  790. List<DepotItemVo4MaterialAndSum> linkList = depotItemMapperEx.getLinkBillDetailMaterialSum(linkStr);
  791. //获取分批操作后单据的商品和商品数量(汇总)
  792. List<DepotItemVo4MaterialAndSum> batchList = depotItemMapperEx.getBatchBillDetailMaterialSum(linkStr, linkType, depotHead.getType());
  793. //将分批操作后的单据的商品和商品数据构造成Map
  794. Map<Long, BigDecimal> materialSumMap = new HashMap<>();
  795. for(DepotItemVo4MaterialAndSum materialAndSum : batchList) {
  796. materialSumMap.put(materialAndSum.getMaterialExtendId(), materialAndSum.getOperNumber());
  797. }
  798. for(DepotItemVo4MaterialAndSum materialAndSum : linkList) {
  799. //过滤掉原单里面有数量为0的商品
  800. if(materialAndSum.getOperNumber().compareTo(BigDecimal.ZERO) != 0) {
  801. BigDecimal materialSum = materialSumMap.get(materialAndSum.getMaterialExtendId());
  802. if (materialSum != null) {
  803. if (materialSum.compareTo(materialAndSum.getOperNumber()) < 0) {
  804. res = BusinessConstants.BILLS_STATUS_SKIPING;
  805. }
  806. } else {
  807. res = BusinessConstants.BILLS_STATUS_SKIPING;
  808. }
  809. }
  810. }
  811. return res;
  812. }
  813. /**
  814. * 更新单据状态
  815. * @param linkStr
  816. * @param billStatus
  817. */
  818. @Override
  819. @Transactional(value = "transactionManager", rollbackFor = Exception.class)
  820. public void changeBillStatus(String linkStr, String billStatus) {
  821. DepotHead depotHeadOrders = new DepotHead();
  822. depotHeadOrders.setStatus(billStatus);
  823. DepotHeadExample example = new DepotHeadExample();
  824. List<String> linkNoList = StringUtil.strToStringList(linkStr);
  825. example.createCriteria().andNumberIn(linkNoList);
  826. try{
  827. depotHeadMapper.updateByExampleSelective(depotHeadOrders, example);
  828. }catch(Exception e){
  829. logger.error("异常码[{}],异常提示[{}],异常[{}]",
  830. ExceptionConstants.DATA_WRITE_FAIL_CODE,ExceptionConstants.DATA_WRITE_FAIL_MSG,e);
  831. throw new BusinessRunTimeException(ExceptionConstants.DATA_WRITE_FAIL_CODE,
  832. ExceptionConstants.DATA_WRITE_FAIL_MSG);
  833. }
  834. }
  835. /**
  836. * 更新单据状态,此处针对销售订单转采购订单的场景
  837. * @param linkStr
  838. * @param billStatus
  839. */
  840. @Override
  841. @Transactional(value = "transactionManager", rollbackFor = Exception.class)
  842. public void changeBillPurchaseStatus(String linkStr, String billStatus) {
  843. DepotHead depotHeadOrders = new DepotHead();
  844. depotHeadOrders.setPurchaseStatus(billStatus);
  845. DepotHeadExample example = new DepotHeadExample();
  846. List<String> linkNoList = StringUtil.strToStringList(linkStr);
  847. example.createCriteria().andNumberIn(linkNoList);
  848. try{
  849. depotHeadMapper.updateByExampleSelective(depotHeadOrders, example);
  850. }catch(Exception e){
  851. logger.error("异常码[{}],异常提示[{}],异常[{}]",
  852. ExceptionConstants.DATA_WRITE_FAIL_CODE,ExceptionConstants.DATA_WRITE_FAIL_MSG,e);
  853. throw new BusinessRunTimeException(ExceptionConstants.DATA_WRITE_FAIL_CODE,
  854. ExceptionConstants.DATA_WRITE_FAIL_MSG);
  855. }
  856. }
  857. /**
  858. * 根据批号查询单据明细信息
  859. * @param materialExtendId
  860. * @param batchNumber
  861. * @return
  862. */
  863. @Override
  864. public DepotItem getDepotItemByBatchNumber(Long materialExtendId, String batchNumber) {
  865. List<DepotItem> depotItemList = depotItemMapperEx.getDepotItemByBatchNumber(materialExtendId, batchNumber);
  866. if(null != depotItemList && depotItemList.size() > 0){
  867. return depotItemList.get(0);
  868. } else {
  869. return new DepotItem();
  870. }
  871. }
  872. /**
  873. * 根据主表id删除单明细
  874. * @param headerId
  875. * @throws Exception
  876. */
  877. @Override
  878. @Transactional(value = "transactionManager", rollbackFor = Exception.class)
  879. public void deleteDepotItemHeadId(Long headerId)throws Exception {
  880. try{
  881. //1、查询删除前的单据明细
  882. List<DepotItem> depotItemList = getListByHeaderId(headerId);
  883. //2、删除单据明细
  884. DepotItemExample example = new DepotItemExample();
  885. example.createCriteria().andHeaderIdEqualTo(headerId);
  886. depotItemMapper.deleteByExample(example);
  887. //3、计算删除之后单据明细中商品的库存
  888. for(DepotItem depotItem : depotItemList){
  889. updateCurrentStock(depotItem);
  890. }
  891. }catch(Exception e){
  892. JshException.writeFail(logger, e);
  893. }
  894. }
  895. /**
  896. * 删除序列号和回收序列号
  897. * @param actionType
  898. * @throws Exception
  899. */
  900. @Override
  901. @Transactional(value = "transactionManager", rollbackFor = Exception.class)
  902. public void deleteOrCancelSerialNumber(String actionType, DepotHead depotHead, Long headerId) throws Exception {
  903. if(actionType.equals("update")) {
  904. User userInfo = userService.getCurrentUser();
  905. if(BusinessConstants.DEPOTHEAD_TYPE_IN.equals(depotHead.getType())){
  906. //入库逻辑
  907. String number = depotHead.getNumber();
  908. SerialNumberExample example = new SerialNumberExample();
  909. example.createCriteria().andInBillNoEqualTo(number);
  910. serialNumberService.deleteByExample(example);
  911. } else if(BusinessConstants.DEPOTHEAD_TYPE_OUT.equals(depotHead.getType())){
  912. //出库逻辑
  913. DepotItemExample example = new DepotItemExample();
  914. example.createCriteria().andHeaderIdEqualTo(headerId).andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
  915. List<DepotItem> depotItemList = depotItemMapper.selectByExample(example);
  916. if(null != depotItemList && depotItemList.size() > 0){
  917. for (DepotItem depotItem : depotItemList){
  918. if(StringUtil.isNotEmpty(depotItem.getSnList())){
  919. serialNumberService.cancelSerialNumber(depotItem.getMaterialId(), depotHead.getNumber(), (depotItem.getBasicNumber() == null ? 0 : depotItem.getBasicNumber()).intValue(), userInfo);
  920. }
  921. }
  922. }
  923. }
  924. }
  925. }
  926. /**
  927. * 针对组装单、拆卸单校验是否存在组合件和普通子件
  928. * @param rowArr
  929. * @param subType
  930. */
  931. @Override
  932. public void checkAssembleWithMaterialType(JSONArray rowArr, String subType) {
  933. if(BusinessConstants.SUB_TYPE_ASSEMBLE.equals(subType) ||
  934. BusinessConstants.SUB_TYPE_DISASSEMBLE.equals(subType)) {
  935. if(rowArr.size() > 1) {
  936. JSONObject firstRowObj = JSONObject.parseObject(rowArr.getString(0));
  937. JSONObject secondRowObj = JSONObject.parseObject(rowArr.getString(1));
  938. String firstMaterialType = firstRowObj.getString("mType");
  939. String secondMaterialType = secondRowObj.getString("mType");
  940. if(!"组合件".equals(firstMaterialType) || !"普通子件".equals(secondMaterialType)) {
  941. throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_CHECK_ASSEMBLE_EMPTY_CODE,
  942. String.format(ExceptionConstants.DEPOT_HEAD_CHECK_ASSEMBLE_EMPTY_MSG));
  943. }
  944. } else {
  945. throw new BusinessRunTimeException(ExceptionConstants.DEPOT_HEAD_CHECK_ASSEMBLE_EMPTY_CODE,
  946. String.format(ExceptionConstants.DEPOT_HEAD_CHECK_ASSEMBLE_EMPTY_MSG));
  947. }
  948. }
  949. }
  950. /**
  951. * 更新商品的价格
  952. * @param meId
  953. * @param subType
  954. * @param rowObj
  955. */
  956. @Override
  957. @Transactional(value = "transactionManager", rollbackFor = Exception.class)
  958. public void updateMaterialExtendPrice(Long meId, String subType, String billType, JSONObject rowObj) throws Exception {
  959. if(systemConfigService.getUpdateUnitPriceFlag()) {
  960. if (StringUtil.isExist(rowObj.get("unitPrice"))) {
  961. BigDecimal unitPrice = rowObj.getBigDecimal("unitPrice");
  962. MaterialExtend materialExtend = new MaterialExtend();
  963. materialExtend.setId(meId);
  964. if(BusinessConstants.SUB_TYPE_PURCHASE.equals(subType)) {
  965. materialExtend.setPurchaseDecimal(unitPrice);
  966. }
  967. if(BusinessConstants.SUB_TYPE_SALES.equals(subType)) {
  968. materialExtend.setWholesaleDecimal(unitPrice);
  969. }
  970. if(BusinessConstants.SUB_TYPE_RETAIL.equals(subType)) {
  971. materialExtend.setCommodityDecimal(unitPrice);
  972. }
  973. //其它入库-生产入库的情况更新采购单价
  974. if(BusinessConstants.SUB_TYPE_OTHER.equals(subType)) {
  975. if(BusinessConstants.BILL_TYPE_PRODUCE_IN.equals(billType)) {
  976. materialExtend.setPurchaseDecimal(unitPrice);
  977. }
  978. }
  979. materialExtendService.updateMaterialExtend(materialExtend);
  980. }
  981. }
  982. }
  983. @Override
  984. @Transactional(value = "transactionManager", rollbackFor = Exception.class)
  985. public List<DepotItemStockWarningCount> findStockWarningCount(Integer offset, Integer rows, String materialParam, List<Long> depotList, List<Long> categoryList) {
  986. List<DepotItemStockWarningCount> list = null;
  987. try{
  988. list =depotItemMapperEx.findStockWarningCount(offset, rows, materialParam, depotList, categoryList);
  989. }catch(Exception e){
  990. JshException.readFail(logger, e);
  991. }
  992. return list;
  993. }
  994. @Override
  995. @Transactional(value = "transactionManager", rollbackFor = Exception.class)
  996. public int findStockWarningCountTotal(String materialParam, List<Long> depotList, List<Long> categoryList) {
  997. int result = 0;
  998. try{
  999. result =depotItemMapperEx.findStockWarningCountTotal(materialParam, depotList, categoryList);
  1000. }catch(Exception e){
  1001. JshException.readFail(logger, e);
  1002. }
  1003. return result;
  1004. }
  1005. /**
  1006. * 库存统计-sku
  1007. * @param depotId
  1008. * @param meId
  1009. * @param beginTime
  1010. * @param endTime
  1011. * @return
  1012. */
  1013. @Override
  1014. public BigDecimal getSkuStockByParam(Long depotId, Long meId, String beginTime, String endTime) throws Exception {
  1015. Boolean forceFlag = systemConfigService.getForceApprovalFlag();
  1016. Boolean inOutManageFlag = systemConfigService.getInOutManageFlag();
  1017. List<Long> depotList = depotService.parseDepotList(depotId);
  1018. //盘点复盘后数量的变动
  1019. BigDecimal stockCheckSum = depotItemMapperEx.getSkuStockCheckSumByDepotList(depotList, meId, forceFlag, beginTime, endTime);
  1020. DepotItemVo4Stock stockObj = depotItemMapperEx.getSkuStockByParamWithDepotList(depotList, meId, forceFlag, inOutManageFlag, beginTime, endTime);
  1021. BigDecimal stockSum = BigDecimal.ZERO;
  1022. if(stockObj!=null) {
  1023. BigDecimal inTotal = stockObj.getInTotal();
  1024. BigDecimal transfInTotal = stockObj.getTransfInTotal();
  1025. BigDecimal assemInTotal = stockObj.getAssemInTotal();
  1026. BigDecimal disAssemInTotal = stockObj.getDisAssemInTotal();
  1027. BigDecimal outTotal = stockObj.getOutTotal();
  1028. BigDecimal transfOutTotal = stockObj.getTransfOutTotal();
  1029. BigDecimal assemOutTotal = stockObj.getAssemOutTotal();
  1030. BigDecimal disAssemOutTotal = stockObj.getDisAssemOutTotal();
  1031. stockSum = inTotal.add(transfInTotal).add(assemInTotal).add(disAssemInTotal)
  1032. .subtract(outTotal).subtract(transfOutTotal).subtract(assemOutTotal).subtract(disAssemOutTotal);
  1033. }
  1034. return stockCheckSum.add(stockSum);
  1035. }
  1036. /**
  1037. * 库存统计-单仓库
  1038. * @param depotId
  1039. * @param mId
  1040. * @param beginTime
  1041. * @param endTime
  1042. * @return
  1043. */
  1044. @Override
  1045. public BigDecimal getStockByParam(Long depotId, Long mId, String beginTime, String endTime) throws Exception {
  1046. List<Long> depotList = depotService.parseDepotList(depotId);
  1047. return getStockByParamWithDepotList(depotList, mId, beginTime, endTime);
  1048. }
  1049. /**
  1050. * 库存统计-多仓库
  1051. * @param depotList
  1052. * @param mId
  1053. * @param beginTime
  1054. * @param endTime
  1055. * @return
  1056. */
  1057. @Override
  1058. public BigDecimal getStockByParamWithDepotList(List<Long> depotList, Long mId, String beginTime, String endTime) throws Exception {
  1059. Boolean forceFlag = systemConfigService.getForceApprovalFlag();
  1060. Boolean inOutManageFlag = systemConfigService.getInOutManageFlag();
  1061. //初始库存
  1062. BigDecimal initStock = materialService.getInitStockByMidAndDepotList(depotList, mId);
  1063. //盘点复盘后数量的变动
  1064. BigDecimal stockCheckSum = depotItemMapperEx.getStockCheckSumByDepotList(depotList, mId, forceFlag, beginTime, endTime);
  1065. DepotItemVo4Stock stockObj = depotItemMapperEx.getStockByParamWithDepotList(depotList, mId, forceFlag, inOutManageFlag, beginTime, endTime);
  1066. BigDecimal stockSum = BigDecimal.ZERO;
  1067. //获取商品子表单的库存总数
  1068. BigDecimal inventory = materialExtendMapper.getInventorySumByDepotAndMid(depotList,mId);
  1069. if(stockObj!=null) {
  1070. BigDecimal inTotal = stockObj.getInTotal();
  1071. BigDecimal transfInTotal = stockObj.getTransfInTotal();
  1072. BigDecimal assemInTotal = stockObj.getAssemInTotal();
  1073. BigDecimal disAssemInTotal = stockObj.getDisAssemInTotal();
  1074. BigDecimal outTotal = stockObj.getOutTotal();
  1075. BigDecimal transfOutTotal = stockObj.getTransfOutTotal();
  1076. BigDecimal assemOutTotal = stockObj.getAssemOutTotal();
  1077. BigDecimal disAssemOutTotal = stockObj.getDisAssemOutTotal();
  1078. stockSum = inTotal.add(transfInTotal).add(assemInTotal).add(disAssemInTotal)
  1079. .subtract(outTotal).subtract(transfOutTotal).subtract(assemOutTotal).subtract(disAssemOutTotal);
  1080. }
  1081. return initStock.add(stockCheckSum).add(inventory).add(stockSum);
  1082. }
  1083. /**
  1084. * 统计时间段内的入库和出库数量-多仓库
  1085. * @param depotList
  1086. * @param mId
  1087. * @param beginTime
  1088. * @param endTime
  1089. * @return
  1090. */
  1091. @Override
  1092. public Map<String, BigDecimal> getIntervalMapByParamWithDepotList(List<Long> depotList, Long mId, String beginTime, String endTime) throws Exception {
  1093. Boolean forceFlag = systemConfigService.getForceApprovalFlag();
  1094. Boolean inOutManageFlag = systemConfigService.getInOutManageFlag();
  1095. Map<String,BigDecimal> intervalMap = new HashMap<>();
  1096. BigDecimal inSum = BigDecimal.ZERO;
  1097. BigDecimal outSum = BigDecimal.ZERO;
  1098. //盘点复盘后数量的变动
  1099. BigDecimal stockCheckSum = depotItemMapperEx.getStockCheckSumByDepotList(depotList, mId, forceFlag, beginTime, endTime);
  1100. DepotItemVo4Stock stockObj = depotItemMapperEx.getStockByParamWithDepotList(depotList, mId, forceFlag, inOutManageFlag, beginTime, endTime);
  1101. if(stockObj!=null) {
  1102. BigDecimal inTotal = stockObj.getInTotal();
  1103. BigDecimal transfInTotal = stockObj.getTransfInTotal();
  1104. BigDecimal assemInTotal = stockObj.getAssemInTotal();
  1105. BigDecimal disAssemInTotal = stockObj.getDisAssemInTotal();
  1106. inSum = inTotal.add(transfInTotal).add(assemInTotal).add(disAssemInTotal);
  1107. BigDecimal outTotal = stockObj.getOutTotal();
  1108. BigDecimal transfOutTotal = stockObj.getTransfOutTotal();
  1109. BigDecimal assemOutTotal = stockObj.getAssemOutTotal();
  1110. BigDecimal disAssemOutTotal = stockObj.getDisAssemOutTotal();
  1111. outSum = outTotal.add(transfOutTotal).add(assemOutTotal).add(disAssemOutTotal);
  1112. }
  1113. if(stockCheckSum.compareTo(BigDecimal.ZERO)>0) {
  1114. inSum = inSum.add(stockCheckSum);
  1115. } else {
  1116. //盘点复盘数量为负数代表出库
  1117. outSum = outSum.subtract(stockCheckSum);
  1118. }
  1119. intervalMap.put("inSum", inSum);
  1120. intervalMap.put("outSum", outSum);
  1121. return intervalMap;
  1122. }
  1123. /**
  1124. * 根据单据明细来批量更新当前库存
  1125. * @param depotItem 单据子表明细
  1126. */
  1127. @Override
  1128. @Transactional(value = "transactionManager", rollbackFor = Exception.class)
  1129. public void updateCurrentStock(DepotItem depotItem) throws Exception {
  1130. updateCurrentStockFun(depotItem.getMaterialId(), depotItem.getDepotId());
  1131. if(depotItem.getAnotherDepotId()!=null){
  1132. updateCurrentStockFun(depotItem.getMaterialId(), depotItem.getAnotherDepotId());
  1133. }
  1134. }
  1135. /**
  1136. * 根据单据明细来批量更新当前成本价
  1137. * @param depotItem
  1138. */
  1139. @Override
  1140. @Transactional(value = "transactionManager", rollbackFor = Exception.class)
  1141. public void updateCurrentUnitPrice(DepotItem depotItem) throws Exception {
  1142. Boolean forceFlag = systemConfigService.getForceApprovalFlag();
  1143. Boolean inOutManageFlag = systemConfigService.getInOutManageFlag();
  1144. //查询多单位信息
  1145. Unit unitInfo = materialService.findUnit(depotItem.getMaterialId());
  1146. List<DepotItemVo4DetailByTypeAndMId> itemList = findDetailByDepotIdsAndMaterialIdList(null, forceFlag, inOutManageFlag, depotItem.getSku(),
  1147. depotItem.getBatchNumber(), null, null, null, depotItem.getMaterialId(), null, null);
  1148. Collections.reverse(itemList); //倒序之后变成按时间从前往后排序
  1149. BigDecimal currentNumber = BigDecimal.ZERO;
  1150. BigDecimal currentUnitPrice = BigDecimal.ZERO;
  1151. BigDecimal currentAllPrice = BigDecimal.ZERO;
  1152. for(DepotItemVo4DetailByTypeAndMId item: itemList) {
  1153. BigDecimal basicNumber = item.getBnum()!=null?item.getBnum():BigDecimal.ZERO;
  1154. //数量*单价 另外计算新的成本价
  1155. BigDecimal allPrice = unitService.parseAllPriceByUnit(item.getAllPrice()!=null?item.getAllPrice():BigDecimal.ZERO, unitInfo, item.getMaterialUnit());
  1156. if(basicNumber.compareTo(BigDecimal.ZERO)!=0 && allPrice.compareTo(BigDecimal.ZERO)!=0) {
  1157. //入库
  1158. if (BusinessConstants.DEPOTHEAD_TYPE_IN.equals(item.getType())) {
  1159. //零售退货、销售退货
  1160. if (BusinessConstants.SUB_TYPE_RETAIL_RETURN.equals(item.getSubType()) || BusinessConstants.SUB_TYPE_SALES_RETURN.equals(item.getSubType())) {
  1161. //数量*当前的成本单价
  1162. currentNumber = currentNumber.add(basicNumber);
  1163. currentAllPrice = currentAllPrice.add(basicNumber.multiply(currentUnitPrice));
  1164. } else {
  1165. currentAllPrice = currentAllPrice.add(allPrice);
  1166. currentNumber = currentNumber.add(basicNumber);
  1167. //只有当前库存总金额和当前库存数量都大于0才计算移动平均价
  1168. if (currentAllPrice.compareTo(BigDecimal.ZERO) > 0 && currentNumber.compareTo(BigDecimal.ZERO) > 0) {
  1169. currentUnitPrice = currentAllPrice.divide(currentNumber, 2, BigDecimal.ROUND_HALF_UP);
  1170. } else {
  1171. currentUnitPrice = item.getUnitPrice();
  1172. }
  1173. }
  1174. }
  1175. //出库
  1176. if (BusinessConstants.DEPOTHEAD_TYPE_OUT.equals(item.getType())) {
  1177. //采购退货
  1178. if (BusinessConstants.SUB_TYPE_PURCHASE_RETURN.equals(item.getSubType())) {
  1179. currentAllPrice = currentAllPrice.add(allPrice);
  1180. currentNumber = currentNumber.add(basicNumber);
  1181. //只有当前库存总金额和当前库存数量都大于0才计算移动平均价
  1182. if (currentAllPrice.compareTo(BigDecimal.ZERO) > 0 && currentNumber.compareTo(BigDecimal.ZERO) > 0) {
  1183. currentUnitPrice = currentAllPrice.divide(currentNumber, 2, BigDecimal.ROUND_HALF_UP);
  1184. } else {
  1185. currentUnitPrice = item.getUnitPrice();
  1186. }
  1187. } else {
  1188. currentNumber = currentNumber.add(basicNumber);
  1189. //数量*当前的成本单价
  1190. currentAllPrice = currentAllPrice.add(basicNumber.multiply(currentUnitPrice));
  1191. }
  1192. }
  1193. //防止单价金额溢出
  1194. if(currentUnitPrice.compareTo(BigDecimal.valueOf(100000000))>0 || currentUnitPrice.compareTo(BigDecimal.valueOf(-100000000))<0) {
  1195. currentUnitPrice = BigDecimal.ZERO;
  1196. }
  1197. }
  1198. }
  1199. //更新实时库存中的当前单价
  1200. materialCurrentStockMapperEx.updateUnitPriceByMId(currentUnitPrice, depotItem.getMaterialId());
  1201. }
  1202. /**
  1203. * 根据商品和仓库来更新当前库存
  1204. * @param mId
  1205. * @param dId
  1206. */
  1207. @Override
  1208. public void updateCurrentStockFun(Long mId, Long dId) throws Exception {
  1209. if(mId!=null && dId!=null) {
  1210. MaterialCurrentStockExample example = new MaterialCurrentStockExample();
  1211. //条件 添加商品id,仓库id ,删除状态
  1212. example.createCriteria().andMaterialIdEqualTo(mId).andDepotIdEqualTo(dId)
  1213. .andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_EXISTS);
  1214. //获取商品当前库存信息
  1215. List<MaterialCurrentStock> list = materialCurrentStockMapper.selectByExample(example);
  1216. MaterialCurrentStock materialCurrentStock = new MaterialCurrentStock();
  1217. materialCurrentStock.setMaterialId(mId);
  1218. materialCurrentStock.setDepotId(dId);
  1219. //设置当前库存数量
  1220. materialCurrentStock.setCurrentNumber(getStockByParam(dId,mId,null,null));
  1221. if(list!=null && list.size()>0) {
  1222. //当前库存信息存在,修改当前库存信息
  1223. Long mcsId = list.get(0).getId();
  1224. materialCurrentStock.setId(mcsId);
  1225. materialCurrentStockMapper.updateByPrimaryKeySelective(materialCurrentStock);
  1226. } else {
  1227. //当前库存信息不存在,新增当前库存信息
  1228. materialCurrentStockMapper.insertSelective(materialCurrentStock);
  1229. }
  1230. }
  1231. }
  1232. @Override
  1233. @Transactional(value = "transactionManager", rollbackFor = Exception.class)
  1234. public BigDecimal getFinishNumber(Long meId, Long id, Long headerId, Unit unitInfo, String materialUnit, String linkType) {
  1235. Long linkId = id;
  1236. String goToType = "";
  1237. DepotHead depotHead =depotHeadMapper.selectByPrimaryKey(headerId);
  1238. String linkStr = depotHead.getNumber(); //订单号
  1239. if("purchase".equals(linkType)) {
  1240. //针对以销定购的情况
  1241. if(BusinessConstants.SUB_TYPE_SALES_ORDER.equals(depotHead.getSubType())) {
  1242. goToType = BusinessConstants.SUB_TYPE_PURCHASE_ORDER;
  1243. }
  1244. } else if("other".equals(linkType)) {
  1245. //采购入库、采购退货、销售出库、销售退货都转其它入库
  1246. if(BusinessConstants.SUB_TYPE_PURCHASE.equals(depotHead.getSubType())
  1247. || BusinessConstants.SUB_TYPE_PURCHASE_RETURN.equals(depotHead.getSubType())
  1248. || BusinessConstants.SUB_TYPE_SALES.equals(depotHead.getSubType())
  1249. || BusinessConstants.SUB_TYPE_SALES_RETURN.equals(depotHead.getSubType())) {
  1250. goToType = BusinessConstants.SUB_TYPE_OTHER;
  1251. }
  1252. } else if("basic".equals(linkType)) {
  1253. //采购订单转采购入库
  1254. if(BusinessConstants.SUB_TYPE_PURCHASE_ORDER.equals(depotHead.getSubType())) {
  1255. goToType = BusinessConstants.SUB_TYPE_PURCHASE;
  1256. }
  1257. //销售订单转销售出库
  1258. if(BusinessConstants.SUB_TYPE_SALES_ORDER.equals(depotHead.getSubType())) {
  1259. goToType = BusinessConstants.SUB_TYPE_SALES;
  1260. }
  1261. //采购入库转采购退货
  1262. if(BusinessConstants.SUB_TYPE_PURCHASE.equals(depotHead.getSubType())) {
  1263. goToType = BusinessConstants.SUB_TYPE_PURCHASE_RETURN;
  1264. }
  1265. //销售出库转销售退货
  1266. if(BusinessConstants.SUB_TYPE_SALES.equals(depotHead.getSubType())) {
  1267. goToType = BusinessConstants.SUB_TYPE_SALES_RETURN;
  1268. }
  1269. }
  1270. String noType = "normal";
  1271. if(BusinessConstants.SUB_TYPE_PURCHASE_APPLY.equals(depotHead.getSubType())) {
  1272. noType = "apply";
  1273. }
  1274. BigDecimal count = depotItemMapperEx.getFinishNumber(meId, linkId, linkStr, noType, goToType);
  1275. //根据多单位情况进行数量的转换
  1276. if(materialUnit.equals(unitInfo.getOtherUnit()) && unitInfo.getRatio()!=null && unitInfo.getRatio().compareTo(BigDecimal.ZERO)!=0) {
  1277. count = count.divide(unitInfo.getRatio(),2,BigDecimal.ROUND_HALF_UP);
  1278. }
  1279. if(materialUnit.equals(unitInfo.getOtherUnitTwo()) && unitInfo.getRatioTwo()!=null && unitInfo.getRatioTwo().compareTo(BigDecimal.ZERO)!=0) {
  1280. count = count.divide(unitInfo.getRatioTwo(),2,BigDecimal.ROUND_HALF_UP);
  1281. }
  1282. if(materialUnit.equals(unitInfo.getOtherUnitThree()) && unitInfo.getRatioThree()!=null && unitInfo.getRatioThree().compareTo(BigDecimal.ZERO)!=0) {
  1283. count = count.divide(unitInfo.getRatioThree(),2,BigDecimal.ROUND_HALF_UP);
  1284. }
  1285. return count;
  1286. }
  1287. /**
  1288. * 除去此单据之外的已入库|已出库|已转采购
  1289. * @param currentSubType
  1290. * @param meId
  1291. * @param linkId
  1292. * @param preHeaderId
  1293. * @param currentHeaderId
  1294. * @param unitInfo
  1295. * @param materialUnit
  1296. * @return
  1297. */
  1298. @Override
  1299. @Transactional(value = "transactionManager", rollbackFor = Exception.class)
  1300. public BigDecimal getRealFinishNumber(String currentSubType, Long meId, Long linkId, Long preHeaderId, Long currentHeaderId, Unit unitInfo, String materialUnit) {
  1301. String goToType = currentSubType;
  1302. DepotHead depotHead =depotHeadMapper.selectByPrimaryKey(preHeaderId);
  1303. String linkStr = depotHead.getNumber(); //订单号
  1304. String linkType = "normal";
  1305. if(BusinessConstants.SUB_TYPE_PURCHASE_APPLY.equals(depotHead.getSubType())) {
  1306. linkType = "apply";
  1307. }
  1308. BigDecimal count = depotItemMapperEx.getRealFinishNumber(meId, linkId, linkStr, linkType, currentHeaderId, goToType);
  1309. //根据多单位情况进行数量的转换
  1310. if(materialUnit.equals(unitInfo.getOtherUnit()) && unitInfo.getRatio()!=null && unitInfo.getRatio().compareTo(BigDecimal.ZERO)!=0) {
  1311. count = count.divide(unitInfo.getRatio(),2,BigDecimal.ROUND_HALF_UP);
  1312. }
  1313. if(materialUnit.equals(unitInfo.getOtherUnitTwo()) && unitInfo.getRatioTwo()!=null && unitInfo.getRatioTwo().compareTo(BigDecimal.ZERO)!=0) {
  1314. count = count.divide(unitInfo.getRatioTwo(),2,BigDecimal.ROUND_HALF_UP);
  1315. }
  1316. if(materialUnit.equals(unitInfo.getOtherUnitThree()) && unitInfo.getRatioThree()!=null && unitInfo.getRatioThree().compareTo(BigDecimal.ZERO)!=0) {
  1317. count = count.divide(unitInfo.getRatioThree(),2,BigDecimal.ROUND_HALF_UP);
  1318. }
  1319. return count;
  1320. }
  1321. @Override
  1322. public List<DepotItemVoBatchNumberList> getBatchNumberList(String number, String name, Long depotId, String barCode,
  1323. String batchNumber, Boolean forceFlag, Boolean inOutManageFlag) throws Exception {
  1324. List<DepotItemVoBatchNumberList> reslist = new ArrayList<>();
  1325. List<DepotItemVoBatchNumberList> list = depotItemMapperEx.getBatchNumberList(StringUtil.toNull(number), name,
  1326. depotId, barCode, batchNumber, forceFlag, inOutManageFlag);
  1327. for(DepotItemVoBatchNumberList bn: list) {
  1328. if(bn.getTotalNum()!=null && bn.getTotalNum().compareTo(BigDecimal.ZERO)>0) {
  1329. bn.setExpirationDateStr(Tools.parseDateToStr(bn.getExpirationDate()));
  1330. if(bn.getUnitId()!=null) {
  1331. Unit unit = unitService.getUnit(bn.getUnitId());
  1332. String commodityUnit = bn.getCommodityUnit();
  1333. bn.setTotalNum(unitService.parseStockByUnit(bn.getTotalNum(), unit, commodityUnit));
  1334. }
  1335. reslist.add(bn);
  1336. }
  1337. }
  1338. return reslist;
  1339. }
  1340. /**
  1341. * 查询某个批号的商品库存
  1342. * @param depotId
  1343. * @param barCode
  1344. * @param batchNumber
  1345. * @return
  1346. * @throws Exception
  1347. */
  1348. @Override
  1349. public BigDecimal getOneBatchNumberStock(Long depotId, String barCode, String batchNumber) throws Exception {
  1350. BigDecimal totalNum = BigDecimal.ZERO;
  1351. Boolean forceFlag = systemConfigService.getForceApprovalFlag();
  1352. Boolean inOutManageFlag = systemConfigService.getInOutManageFlag();
  1353. List<DepotItemVoBatchNumberList> list = depotItemMapperEx.getBatchNumberList(null, null,
  1354. depotId, barCode, batchNumber, forceFlag, inOutManageFlag);
  1355. if(list!=null && list.size()>0) {
  1356. DepotItemVoBatchNumberList bn = list.get(0);
  1357. totalNum = bn.getTotalNum();
  1358. if(bn.getTotalNum()!=null && bn.getTotalNum().compareTo(BigDecimal.ZERO)>0) {
  1359. if(bn.getUnitId()!=null) {
  1360. Unit unit = unitService.getUnit(bn.getUnitId());
  1361. String commodityUnit = bn.getCommodityUnit();
  1362. totalNum = unitService.parseStockByUnit(bn.getTotalNum(), unit, commodityUnit);
  1363. }
  1364. }
  1365. }
  1366. return totalNum;
  1367. }
  1368. @Override
  1369. public Long getCountByMaterialAndDepot(Long mId, Long depotId) {
  1370. return depotItemMapperEx.getCountByMaterialAndDepot(mId, depotId);
  1371. }
  1372. @Override
  1373. public JSONObject parseMapByExcelData(String barCodes, List<Map<String, String>> detailList, String prefixNo) throws Exception {
  1374. JSONObject map = new JSONObject();
  1375. JSONArray arr = new JSONArray();
  1376. List<MaterialVo4Unit> list = depotItemMapperEx.getBillItemByParam(barCodes);
  1377. Map<String, MaterialVo4Unit> materialMap = new HashMap<>();
  1378. Map<String, Long> depotMap = new HashMap<>();
  1379. for (MaterialVo4Unit material: list) {
  1380. materialMap.put(material.getmBarCode(), material);
  1381. }
  1382. JSONArray depotArr = depotService.findDepotByCurrentUser();
  1383. for (Object depotObj: depotArr) {
  1384. if(depotObj!=null) {
  1385. JSONObject depotObject = JSONObject.parseObject(depotObj.toString());
  1386. depotMap.put(depotObject.getString("depotName"), depotObject.getLong("id"));
  1387. }
  1388. }
  1389. for (Map<String, String> detailMap: detailList) {
  1390. JSONObject item = new JSONObject();
  1391. String barCode = detailMap.get("barCode");
  1392. if(StringUtil.isNotEmpty(barCode)) {
  1393. MaterialVo4Unit m = materialMap.get(barCode);
  1394. if(m!=null) {
  1395. //判断仓库是否存在
  1396. String depotName = detailMap.get("depotName");
  1397. if(StringUtil.isNotEmpty(depotName)) {
  1398. if(depotMap.get(depotName)!=null) {
  1399. item.put("depotName", depotName);
  1400. item.put("depotId", depotMap.get(depotName));
  1401. } else {
  1402. throw new BusinessRunTimeException(ExceptionConstants.DEPOT_ITEM_DEPOTNAME_IS_NOT_EXIST_CODE,
  1403. String.format(ExceptionConstants.DEPOT_ITEM_DEPOTNAME_IS_NOT_EXIST_MSG, depotName));
  1404. }
  1405. }
  1406. item.put("barCode", barCode);
  1407. item.put("name", m.getName());
  1408. item.put("standard", m.getStandard());
  1409. if(StringUtil.isNotEmpty(m.getModel())) {
  1410. item.put("model", m.getModel());
  1411. }
  1412. if(StringUtil.isNotEmpty(m.getColor())) {
  1413. item.put("color", m.getColor());
  1414. }
  1415. if(StringUtil.isNotEmpty(m.getSku())) {
  1416. item.put("sku", m.getSku());
  1417. }
  1418. BigDecimal stock = BigDecimal.ZERO;
  1419. if(StringUtil.isNotEmpty(m.getSku())){
  1420. stock = getSkuStockByParam(null, m.getMeId(),null,null);
  1421. } else {
  1422. stock = getCurrentStockByParam(null, m.getId());
  1423. }
  1424. item.put("stock", stock);
  1425. item.put("unit", m.getCommodityUnit());
  1426. BigDecimal operNumber = BigDecimal.ZERO;
  1427. BigDecimal unitPrice = BigDecimal.ZERO;
  1428. BigDecimal taxRate = BigDecimal.ZERO;
  1429. if(StringUtil.isNotEmpty(detailMap.get("num"))) {
  1430. operNumber = new BigDecimal(detailMap.get("num"));
  1431. }
  1432. if(StringUtil.isNotEmpty(detailMap.get("unitPrice"))) {
  1433. unitPrice = new BigDecimal(detailMap.get("unitPrice"));
  1434. } else {
  1435. if("CGDD".equals(prefixNo)) {
  1436. unitPrice = m.getPurchaseDecimal();
  1437. } else if("XSDD".equals(prefixNo)) {
  1438. unitPrice = m.getWholesaleDecimal();
  1439. }
  1440. }
  1441. if(StringUtil.isNotEmpty(detailMap.get("taxRate"))) {
  1442. taxRate = new BigDecimal(detailMap.get("taxRate"));
  1443. }
  1444. String remark = detailMap.get("remark");
  1445. item.put("operNumber", operNumber);
  1446. item.put("unitPrice", unitPrice);
  1447. BigDecimal allPrice = BigDecimal.ZERO;
  1448. if(unitPrice!=null && unitPrice.compareTo(BigDecimal.ZERO)!=0) {
  1449. allPrice = unitPrice.multiply(operNumber);
  1450. }
  1451. BigDecimal taxMoney = BigDecimal.ZERO;
  1452. if(taxRate.compareTo(BigDecimal.ZERO) != 0) {
  1453. taxMoney = taxRate.multiply(allPrice).divide(BigDecimal.valueOf(100), 2, BigDecimal.ROUND_HALF_UP);
  1454. }
  1455. BigDecimal taxLastMoney = allPrice.add(taxMoney);
  1456. item.put("allPrice", allPrice);
  1457. item.put("taxRate", taxRate);
  1458. item.put("taxMoney", taxMoney);
  1459. item.put("taxLastMoney", taxLastMoney);
  1460. item.put("remark", remark);
  1461. arr.add(item);
  1462. } else {
  1463. throw new BusinessRunTimeException(ExceptionConstants.DEPOT_ITEM_BARCODE_IS_NOT_EXIST_CODE,
  1464. String.format(ExceptionConstants.DEPOT_ITEM_BARCODE_IS_NOT_EXIST_MSG, barCode));
  1465. }
  1466. }
  1467. }
  1468. map.put("rows", arr);
  1469. return map;
  1470. }
  1471. @Override
  1472. public BigDecimal getLastUnitPriceByParam(Long organId, Long meId, String prefixNo) {
  1473. String type = "";
  1474. String subType = "";
  1475. if("XSDD".equals(prefixNo)) {
  1476. type = "其它";
  1477. subType = "销售订单";
  1478. } else if("XSCK".equals(prefixNo)) {
  1479. type = "出库";
  1480. subType = "销售";
  1481. } else if("XSTH".equals(prefixNo)) {
  1482. type = "入库";
  1483. subType = "销售退货";
  1484. } else if("QTCK".equals(prefixNo)) {
  1485. type = "出库";
  1486. subType = "其它";
  1487. }
  1488. return depotItemMapperEx.getLastUnitPriceByParam(organId, meId, type, subType);
  1489. }
  1490. @Override
  1491. public BigDecimal getCurrentStockByParam(Long depotId, Long mId) {
  1492. BigDecimal stock = depotItemMapperEx.getCurrentStockByParam(depotId, mId);
  1493. return stock!=null? stock: BigDecimal.ZERO;
  1494. }
  1495. /**
  1496. * 获取扩展信息
  1497. *
  1498. * @return
  1499. */
  1500. @Override
  1501. public String getOtherInfo(String[] mpArr, DepotItemVo4WithInfoEx diEx)throws Exception {
  1502. String materialOther = "";
  1503. for (int i = 0; i < mpArr.length; i++) {
  1504. if (mpArr[i].equals("自定义1")) {
  1505. materialOther = materialOther + ((diEx.getMOtherField1() == null || diEx.getMOtherField1().equals("")) ? "" : "(" + diEx.getMOtherField1() + ")");
  1506. }
  1507. if (mpArr[i].equals("自定义2")) {
  1508. materialOther = materialOther + ((diEx.getMOtherField2() == null || diEx.getMOtherField2().equals("")) ? "" : "(" + diEx.getMOtherField2() + ")");
  1509. }
  1510. if (mpArr[i].equals("自定义3")) {
  1511. materialOther = materialOther + ((diEx.getMOtherField3() == null || diEx.getMOtherField3().equals("")) ? "" : "(" + diEx.getMOtherField3() + ")");
  1512. }
  1513. }
  1514. return materialOther;
  1515. }
  1516. }