DepotItemServiceImpl.java 85 KB

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