DepotItemServiceImpl.java 85 KB

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