DepotItemServiceImpl.java 86 KB

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