DepotItemServiceImpl.java 84 KB

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