DepotItemServiceImpl.java 86 KB

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