MaterialServiceImpl.java 104 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160
  1. package com.jsh.erp.service.impl;
  2. import cn.hutool.core.collection.CollectionUtil;
  3. import com.alibaba.fastjson.JSON;
  4. import com.alibaba.fastjson.JSONArray;
  5. import com.alibaba.fastjson.JSONObject;
  6. import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
  7. import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
  8. import com.jsh.erp.constants.BusinessConstants;
  9. import com.jsh.erp.constants.ExceptionConstants;
  10. import com.jsh.erp.datasource.dto.MaterialDto;
  11. import com.jsh.erp.datasource.entities.*;
  12. import com.jsh.erp.datasource.mappers.*;
  13. import com.jsh.erp.datasource.pda.dto.PDAInventoryDTO;
  14. import com.jsh.erp.datasource.pda.vo.PDADepotItemVO;
  15. import com.jsh.erp.datasource.vo.MaterialCurrentStock4SystemSku;
  16. import com.jsh.erp.datasource.pda.vo.PDATypeTree;
  17. import com.jsh.erp.datasource.vo.MaterialVoSearch;
  18. import com.jsh.erp.datasource.vo.MaterialWarnListVo;
  19. import com.jsh.erp.datasource.vo.TaskStocktakingItemVO;
  20. import com.jsh.erp.exception.BusinessRunTimeException;
  21. import com.jsh.erp.exception.JshException;
  22. import com.jsh.erp.query.LambdaQueryWrapperX;
  23. import com.jsh.erp.query.QueryWrapperX;
  24. import com.jsh.erp.service.*;
  25. import com.jsh.erp.utils.*;
  26. import jxl.Sheet;
  27. import jxl.Workbook;
  28. import org.slf4j.Logger;
  29. import org.slf4j.LoggerFactory;
  30. import org.springframework.beans.factory.annotation.Value;
  31. import org.springframework.stereotype.Service;
  32. import org.springframework.transaction.annotation.Transactional;
  33. import org.springframework.web.context.request.RequestContextHolder;
  34. import org.springframework.web.context.request.ServletRequestAttributes;
  35. import org.springframework.web.multipart.MultipartFile;
  36. import javax.annotation.Resource;
  37. import javax.servlet.http.HttpServletRequest;
  38. import javax.servlet.http.HttpServletResponse;
  39. import java.io.File;
  40. import java.math.BigDecimal;
  41. import java.text.SimpleDateFormat;
  42. import java.util.*;
  43. import java.util.stream.Collectors;
  44. @Service
  45. public class MaterialServiceImpl extends ServiceImpl<MaterialMapper, Material> implements MaterialService {
  46. private Logger logger = LoggerFactory.getLogger(MaterialServiceImpl.class);
  47. @Resource
  48. private MaterialMapper materialMapper;
  49. @Resource
  50. private MaterialExtendMapper materialExtendMapper;
  51. @Resource
  52. private MaterialMapperEx materialMapperEx;
  53. @Resource
  54. private MaterialCategoryMapperEx materialCategoryMapperEx;
  55. @Resource
  56. private MaterialExtendMapperEx materialExtendMapperEx;
  57. @Resource
  58. private LogService logService;
  59. @Resource
  60. private UserService userService;
  61. @Resource
  62. private DepotItemMapperEx depotItemMapperEx;
  63. @Resource
  64. private DepotItemService depotItemService;
  65. @Resource
  66. private MaterialCategoryService materialCategoryService;
  67. @Resource
  68. private UnitService unitService;
  69. @Resource
  70. private MaterialInitialStockMapper materialInitialStockMapper;
  71. @Resource
  72. private MaterialInitialStockMapperEx materialInitialStockMapperEx;
  73. @Resource
  74. private MaterialCurrentStockMapper materialCurrentStockMapper;
  75. @Resource
  76. private MaterialCurrentStockMapperEx materialCurrentStockMapperEx;
  77. @Resource
  78. private DepotService depotService;
  79. @Resource
  80. private MaterialExtendService materialExtendService;
  81. @Resource
  82. private SystemConfigService systemConfigService;
  83. @Resource
  84. private DepotHeadService depotHeadService;
  85. @Resource
  86. private SupplierService supplierService;
  87. @Resource
  88. private DepotMapperEx depotMapperEx;
  89. @Resource
  90. private MaterialBatchService materialBatchService;
  91. @Value(value="${file.uploadType}")
  92. private Long fileUploadType;
  93. @Override
  94. public Material getMaterial(long id)throws Exception {
  95. Material result=null;
  96. try{
  97. result=materialMapper.selectByPrimaryKey(id);
  98. }catch(Exception e){
  99. JshException.readFail(logger, e);
  100. }
  101. return result;
  102. }
  103. @Override
  104. public List<Material> getMaterialListByIds(String ids)throws Exception {
  105. List<Long> idList = StringUtil.strToLongList(ids);
  106. List<Material> list = new ArrayList<>();
  107. try{
  108. MaterialExample example = new MaterialExample();
  109. example.createCriteria().andIdIn(idList);
  110. list = materialMapper.selectByExample(example);
  111. }catch(Exception e){
  112. JshException.readFail(logger, e);
  113. }
  114. return list;
  115. }
  116. @Override
  117. public List<Material> getMaterial() throws Exception{
  118. MaterialExample example = new MaterialExample();
  119. example.createCriteria().andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
  120. List<Material> list=null;
  121. try{
  122. list=materialMapper.selectByExample(example);
  123. }catch(Exception e){
  124. JshException.readFail(logger, e);
  125. }
  126. return list;
  127. }
  128. /**
  129. * 查询商品管理-商品信息列表查询
  130. */
  131. @Override
  132. public List<MaterialVo4Unit> select(String materialParam, String standard, String model, String color, String brand, String mfrs,
  133. String materialOther, String weight, String expiryNum, String enableSerialNumber,
  134. String enableBatchNumber, String position, String enabled, String remark, String categoryId,
  135. String mpList,String reminder) {
  136. String[] mpArr = new String[]{};
  137. if(StringUtil.isNotEmpty(mpList)){
  138. mpArr= mpList.split(",");
  139. }
  140. List<MaterialVo4Unit> list = new ArrayList<>();
  141. try{
  142. List<Long> idList = new ArrayList<>();
  143. //类型不为空,获取类型id集合
  144. if(StringUtil.isNotEmpty(categoryId)){
  145. idList = getListByParentId(Long.parseLong(categoryId));
  146. }
  147. PageUtils.startPage();
  148. list= materialMapperEx.selectByConditionMaterial(materialParam, standard, model, color, brand, mfrs, materialOther, weight, expiryNum,
  149. enableSerialNumber, enableBatchNumber, position, enabled, remark, idList, mpList,reminder);
  150. if (null != list && list.size()>0) {
  151. Map<Long,BigDecimal> initialStockMap = getInitialStockMapByMaterialList(list);
  152. Map<Long,BigDecimal> currentStockMap = getCurrentStockMapByMaterialList(list);
  153. for (MaterialVo4Unit m : list) {
  154. if(fileUploadType == 2) {
  155. m.setImgSmall("small");
  156. m.setImgLarge("large");
  157. }
  158. m.setMaterialOther(getMaterialOtherByParam(mpArr, m));
  159. m.setInitialStock(initialStockMap.get(m.getId())!=null? initialStockMap.get(m.getId()): BigDecimal.ZERO);
  160. m.setBigUnitInitialStock(getBigUnitStock(m.getInitialStock(), m.getUnitId()));
  161. m.setStock(currentStockMap.get(m.getId())!=null? currentStockMap.get(m.getId()): BigDecimal.ZERO);
  162. m.setBigUnitStock(getBigUnitStock(m.getStock(), m.getUnitId()));
  163. }
  164. }
  165. } catch(Exception e){
  166. JshException.readFail(logger, e);
  167. }
  168. return list;
  169. }
  170. /**
  171. * 新增商品信息
  172. */
  173. @Override
  174. @Transactional(value = "transactionManager", rollbackFor = Exception.class)
  175. public int insertMaterial(MaterialDto material, HttpServletRequest request)throws Exception {
  176. //商品主表信息
  177. Material m = material;
  178. //设置状态
  179. m.setEnabled(true);
  180. //获取类型编码
  181. Long serial_no = materialCategoryService.getMaterialCategory(m.getCategoryId()).getSerialNo();
  182. String sku = serial_no + DateUtils.dateTimeNow() + RandomHelper.getRandomStr(6);
  183. //设置系统sku
  184. m.setSystemSku(sku);
  185. try{
  186. //添加商品
  187. materialMapperEx.insertSelectiveEx(m);
  188. Long mId = m.getId();
  189. //添加商品条码信息
  190. materialExtendService.saveDetails(material.getMbList(),material.getSortList().toJSONString(),mId,"insert");
  191. //设置初始库存
  192. if(material.getStock()!=null) {
  193. List<MaterialInitialStock> stockArr = material.getStock();
  194. for (int i = 0; i < stockArr.size(); i++) {
  195. MaterialInitialStock jsonObj = stockArr.get(i);
  196. //此时id为仓库id,仓库id、最低安全库存数量、库位不为空
  197. if(jsonObj.getId() != null && jsonObj.getLowSafeStock() != null || jsonObj.getPosition() != null || jsonObj.getHighSafeStock() != null) {
  198. Long depotId = jsonObj.getId();
  199. jsonObj.setDepotId(depotId);
  200. jsonObj.setMaterialId(mId);
  201. jsonObj.setId(null);
  202. //设置初始库
  203. materialInitialStockMapper.insertSelective(jsonObj);
  204. }
  205. }
  206. }
  207. logService.insertLog("商品",
  208. new StringBuffer(BusinessConstants.LOG_OPERATION_TYPE_ADD).append(m.getName()).toString(), request);
  209. return 1;
  210. }
  211. catch (BusinessRunTimeException ex) {
  212. throw new BusinessRunTimeException(ex.getCode(), ex.getMessage());
  213. }
  214. catch(Exception e){
  215. JshException.writeFail(logger, e);
  216. return 0;
  217. }
  218. }
  219. /**
  220. * 修改商品
  221. * @param obj
  222. * @param request
  223. */
  224. @Override
  225. @Transactional(value = "transactionManager", rollbackFor = Exception.class)
  226. public int updateMaterial(MaterialDto obj, HttpServletRequest request) throws Exception{
  227. Material material = obj;
  228. try{
  229. //修改商品属性
  230. materialMapper.updateByPrimaryKeySelective(material);
  231. if(material.getUnitId() == null) {
  232. materialMapperEx.setUnitIdToNull(material.getId());
  233. }
  234. materialExtendService.saveDetails(obj.getMbList(), obj.getSortList().toJSONString(),material.getId(), "update");
  235. if(obj.getStock()!=null) {
  236. List<MaterialInitialStock> stockArr = obj.getStock();
  237. for (int i = 0; i < stockArr.size(); i++) {
  238. MaterialInitialStock jsonObj = stockArr.get(i);
  239. if(jsonObj.getId() != null && jsonObj.getLowSafeStock() != null || jsonObj.getPosition() != null) {
  240. BigDecimal lowSafeStock = jsonObj.getLowSafeStock();
  241. BigDecimal highSafeStock = null;
  242. if(jsonObj.getHighSafeStock() != null) {
  243. highSafeStock = jsonObj.getHighSafeStock();
  244. }
  245. Long depotId = jsonObj.getId();
  246. jsonObj.setMaterialId(material.getId());
  247. jsonObj.setDepotId(depotId);
  248. jsonObj.setId(null);
  249. //初始库存-先清除再插入
  250. MaterialInitialStockExample example = new MaterialInitialStockExample();
  251. example.createCriteria().andMaterialIdEqualTo(material.getId()).andDepotIdEqualTo(depotId);
  252. materialInitialStockMapper.deleteByExample(example);
  253. if (lowSafeStock!=null || highSafeStock!=null || jsonObj.getPosition() != null) {
  254. //insertInitialStockByMaterialAndDepot(depotId, material.getId(), parseBigDecimalEx("0"), lowSafeStock, highSafeStock);
  255. materialInitialStockMapper.insertSelective(jsonObj);
  256. }
  257. //更新当前库存
  258. //depotItemService.updateCurrentStockFun(material.getId(), depotId);
  259. }
  260. }
  261. }
  262. logService.insertLog("商品",
  263. new StringBuffer(BusinessConstants.LOG_OPERATION_TYPE_EDIT).append(material.getName()).toString(), request);
  264. return 1;
  265. }
  266. catch (BusinessRunTimeException ex) {
  267. throw new BusinessRunTimeException(ex.getCode(), ex.getMessage());
  268. }
  269. catch(Exception e){
  270. JshException.writeFail(logger, e);
  271. return 0;
  272. }
  273. }
  274. @Override
  275. @Transactional(value = "transactionManager", rollbackFor = Exception.class)
  276. public int deleteMaterial(Long id, HttpServletRequest request)throws Exception {
  277. return batchDeleteMaterialByIds(id.toString());
  278. }
  279. @Override
  280. @Transactional(value = "transactionManager", rollbackFor = Exception.class)
  281. public int batchDeleteMaterial(String ids, HttpServletRequest request)throws Exception {
  282. return batchDeleteMaterialByIds(ids);
  283. }
  284. @Override
  285. @Transactional(value = "transactionManager", rollbackFor = Exception.class)
  286. public int batchDeleteMaterialByIds(String ids) throws Exception{
  287. String [] idArray = ids.split(",");
  288. //校验单据子表 jsh_depot_item
  289. List<DepotItem> depotItemList =null;
  290. try{
  291. depotItemList= depotItemMapperEx.getDepotItemListListByMaterialIds(idArray);
  292. }catch(Exception e){
  293. JshException.readFail(logger, e);
  294. }
  295. if(depotItemList!=null&&depotItemList.size()>0){
  296. logger.error("异常码[{}],异常提示[{}],参数,MaterialIds[{}]",
  297. ExceptionConstants.DELETE_FORCE_CONFIRM_CODE,ExceptionConstants.DELETE_FORCE_CONFIRM_MSG,ids);
  298. throw new BusinessRunTimeException(ExceptionConstants.DELETE_FORCE_CONFIRM_CODE,
  299. ExceptionConstants.DELETE_FORCE_CONFIRM_MSG);
  300. }
  301. //记录日志
  302. StringBuffer sb = new StringBuffer();
  303. sb.append(BusinessConstants.LOG_OPERATION_TYPE_DELETE);
  304. //路径列表
  305. List<String> pathList = new ArrayList<>();
  306. List<Material> list = getMaterialListByIds(ids);
  307. for(Material material: list){
  308. sb.append("[").append(material.getName()).append("]");
  309. if(StringUtil.isNotEmpty(material.getImgName())) {
  310. pathList.add(material.getImgName());
  311. }
  312. }
  313. logService.insertLog("商品", sb.toString(),
  314. ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest());
  315. User userInfo=userService.getCurrentUser();
  316. //校验通过执行删除操作
  317. try{
  318. //逻辑删除商品
  319. materialMapperEx.batchDeleteMaterialByIds(new Date(),userInfo==null?null:userInfo.getId(),idArray);
  320. //逻辑删除商品价格扩展
  321. materialExtendMapperEx.batchDeleteMaterialExtendByMIds(idArray);
  322. //逻辑删除文件
  323. systemConfigService.deleteFileByPathList(pathList);
  324. return 1;
  325. }catch(Exception e){
  326. JshException.writeFail(logger, e);
  327. return 0;
  328. }
  329. }
  330. @Override
  331. public int checkIsNameExist(Long id, String name)throws Exception {
  332. MaterialExample example = new MaterialExample();
  333. example.createCriteria().andIdNotEqualTo(id).andNameEqualTo(name).andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
  334. List<Material> list =null;
  335. try{
  336. list= materialMapper.selectByExample(example);
  337. }catch(Exception e){
  338. JshException.readFail(logger, e);
  339. }
  340. return list==null?0:list.size();
  341. }
  342. @Override
  343. public int checkIsExist(Long id, String name, String model, String color, String standard, String mfrs,
  344. String otherField1, String otherField2, String otherField3, String unit, Long unitId)throws Exception {
  345. return materialMapperEx.checkIsExist(id, name, model, color, standard, mfrs, otherField1,
  346. otherField2, otherField3, unit, unitId);
  347. }
  348. @Override
  349. @Transactional(value = "transactionManager", rollbackFor = Exception.class)
  350. public int batchSetStatus(Boolean status, String ids)throws Exception {
  351. logService.insertLog("商品",
  352. new StringBuffer(BusinessConstants.LOG_OPERATION_TYPE_EDIT).append(ids).toString(),
  353. ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest());
  354. List<Long> materialIds = StringUtil.strToLongList(ids);
  355. Material material = new Material();
  356. material.setEnabled(status);
  357. MaterialExample example = new MaterialExample();
  358. example.createCriteria().andIdIn(materialIds);
  359. int result =0;
  360. try{
  361. result= materialMapper.updateByExampleSelective(material, example);
  362. }catch(Exception e){
  363. JshException.readFail(logger, e);
  364. }
  365. return result;
  366. }
  367. @Override
  368. public Unit findUnit(Long mId)throws Exception{
  369. Unit unit = new Unit();
  370. try{
  371. List<Unit> list = materialMapperEx.findUnitList(mId);
  372. if(list!=null && list.size()>0) {
  373. unit = list.get(0);
  374. }
  375. }catch(Exception e){
  376. JshException.readFail(logger, e);
  377. }
  378. return unit;
  379. }
  380. @Override
  381. public List<MaterialVo4Unit> findById(Long id)throws Exception{
  382. List<MaterialVo4Unit> list =null;
  383. try{
  384. list= materialMapperEx.findById(id);
  385. }catch(Exception e){
  386. JshException.readFail(logger, e);
  387. }
  388. return list;
  389. }
  390. @Override
  391. public List<MaterialVo4Unit> findByIdWithBarCode(Long meId)throws Exception{
  392. List<MaterialVo4Unit> list =null;
  393. try{
  394. list= materialMapperEx.findByIdWithBarCode(meId);
  395. }catch(Exception e){
  396. JshException.readFail(logger, e);
  397. }
  398. return list;
  399. }
  400. /**
  401. * 根据商品类型id获取子类型id集合
  402. * @param parentId 商品类型父id
  403. * @return
  404. */
  405. @Override
  406. public List<Long> getListByParentId(Long parentId) {
  407. List<Long> idList = new ArrayList<>();
  408. List<MaterialCategory> list = materialCategoryMapperEx.getListByParentId(parentId);
  409. idList.add(parentId);
  410. if(list!=null && list.size()>0) {
  411. getIdListByParentId(idList, parentId);
  412. }
  413. return idList;
  414. }
  415. @Override
  416. public List<Long> getIdListByParentId(List<Long> idList, Long parentId){
  417. List<MaterialCategory> list = materialCategoryMapperEx.getListByParentId(parentId);
  418. if(list!=null && list.size()>0) {
  419. for(MaterialCategory mc : list){
  420. idList.add(mc.getId());
  421. getIdListByParentId(idList, mc.getId());
  422. }
  423. }
  424. return idList;
  425. }
  426. @Override
  427. public JSONArray getMaterialByParam(String materialParam) {
  428. JSONArray arr = new JSONArray();
  429. List<MaterialVoSearch> list = materialMapperEx.getMaterialByParam(materialParam);
  430. for(MaterialVoSearch item: list) {
  431. JSONObject obj = new JSONObject();
  432. StringBuilder sb = new StringBuilder();
  433. sb.append(item.getBatchNumber());
  434. sb.append("_").append(item.getName());
  435. if(StringUtil.isNotEmpty(item.getMnemonic())) {
  436. sb.append("(").append(item.getMnemonic()).append(")");
  437. }
  438. if(StringUtil.isNotEmpty(item.getStandard())) {
  439. sb.append("(").append(item.getStandard()).append(")");
  440. }
  441. if(StringUtil.isNotEmpty(item.getModel())) {
  442. sb.append("(").append(item.getModel()).append(")");
  443. }
  444. if(StringUtil.isNotEmpty(item.getColor())) {
  445. sb.append("(").append(item.getColor()).append(")");
  446. }
  447. if(StringUtil.isNotEmpty(item.getUnit())) {
  448. sb.append("(").append(item.getUnit()).append(")");
  449. }
  450. obj.put("batchNumber", item.getBatchNumber());
  451. obj.put("materialStr", sb.toString());
  452. arr.add(obj);
  453. }
  454. return arr;
  455. }
  456. @Override
  457. public List<MaterialVo4Unit> findBySelectWithBarCode(Long categoryId, String q, String standardOrModel, String color,
  458. String brand, String mfrs, String enableSerialNumber, String enableBatchNumber,
  459. Integer offset, Integer rows, Long depotId) throws Exception{
  460. List<MaterialVo4Unit> list =null;
  461. try{
  462. List<Long> idList = new ArrayList<>();
  463. if(categoryId!=null){
  464. Long parentId = categoryId;
  465. idList = getListByParentId(parentId);
  466. }
  467. if(StringUtil.isNotEmpty(q)) {
  468. q = q.replace("'", "");
  469. q = q.trim();
  470. }
  471. list= materialMapperEx.findBySelectWithBarCode(idList, q, standardOrModel, color, brand, mfrs,
  472. enableSerialNumber, enableBatchNumber, offset, rows,depotId);
  473. }catch(Exception e){
  474. JshException.readFail(logger, e);
  475. }
  476. return list;
  477. }
  478. @Override
  479. public int findBySelectWithBarCodeCount(Long categoryId, String q, String standardOrModel, String color,
  480. String brand, String mfrs, String enableSerialNumber, String enableBatchNumber, Long depotId) throws Exception{
  481. int result=0;
  482. try{
  483. List<Long> idList = new ArrayList<>();
  484. if(categoryId!=null){
  485. Long parentId = categoryId;
  486. idList = getListByParentId(parentId);
  487. }
  488. if(StringUtil.isNotEmpty(q)) {
  489. q = q.replace("'", "");
  490. }
  491. result = materialMapperEx.findBySelectWithBarCodeCount(idList, q, standardOrModel, color, brand, mfrs,
  492. enableSerialNumber, enableBatchNumber,depotId);
  493. }catch(Exception e){
  494. logger.error("异常码[{}],异常提示[{}],异常[{}]",
  495. ExceptionConstants.DATA_READ_FAIL_CODE,ExceptionConstants.DATA_READ_FAIL_MSG,e);
  496. throw new BusinessRunTimeException(ExceptionConstants.DATA_READ_FAIL_CODE,
  497. ExceptionConstants.DATA_READ_FAIL_MSG);
  498. }
  499. return result;
  500. }
  501. /**
  502. * 导出商品信息
  503. * @param categoryId
  504. * @param materialParam
  505. * @param color
  506. * @param materialOther
  507. * @param weight
  508. * @param expiryNum
  509. * @param enabled
  510. * @param enableSerialNumber
  511. * @param enableBatchNumber
  512. * @param remark
  513. * @param response
  514. * @throws Exception
  515. */
  516. @Override
  517. public void exportExcel(String categoryId, String materialParam, String color, String materialOther, String weight,
  518. String expiryNum, String enabled, String enableSerialNumber, String enableBatchNumber,
  519. String remark, HttpServletResponse response)throws Exception {
  520. //查询类型子集合id
  521. List<Long> idList = new ArrayList<>();
  522. if(StringUtil.isNotEmpty(categoryId)){
  523. idList = getListByParentId(Long.parseLong(categoryId));
  524. }
  525. //查询商品主条码相关列表
  526. List<MaterialVo4Unit> dataList = materialMapperEx.exportExcel(materialParam, color, materialOther, weight, expiryNum, enabled, enableSerialNumber,
  527. enableBatchNumber, remark, idList);
  528. //查询商品副条码相关列表
  529. Map<Long, MaterialExtend> otherMaterialMap = new HashMap<>();
  530. List<MaterialExtend> otherDataList = materialMapperEx.getOtherMaterialList();
  531. for(MaterialExtend me: otherDataList) {
  532. //遇到多个副条码的情况,只加第一个
  533. otherMaterialMap.putIfAbsent(me.getMaterialId(), me);
  534. }
  535. String nameStr = "名称*,规格,型号,颜色,品牌,类别,基础重量(kg),基本单位*,副单位,比例,多属性," +
  536. "状态*,序列号,系统sku,商品条码,默认采购价,默认销售价,自定义1,自定义2,自定义3,备注";
  537. List<String> nameList = StringUtil.strToStringList(nameStr);
  538. //仓库列表
  539. List<Depot> depotList = depotService.getAllList();
  540. // if (nameList != null) {
  541. // for(Depot depot: depotList) {
  542. // nameList.add(depot.getName());
  543. // }
  544. // }
  545. //期初库存缓存
  546. List<MaterialInitialStock> misList = materialInitialStockMapperEx.getListExceptZero();
  547. Map<String, BigDecimal> misMap = new HashMap<>();
  548. if (misList != null) {
  549. for (MaterialInitialStock mis : misList) {
  550. misMap.put(mis.getMaterialId() + "_" + mis.getDepotId(), mis.getNumber());
  551. }
  552. }
  553. String[] names = StringUtil.listToStringArray(nameList);
  554. String title = "商品信息";
  555. List<String[]> objects = new ArrayList<>();
  556. if (null != dataList) {
  557. for (MaterialVo4Unit m : dataList) {
  558. String[] objs = new String[names.length];
  559. objs[0] = m.getName();
  560. objs[1] = m.getStandard();
  561. objs[2] = m.getModel();
  562. objs[3] = m.getColor();
  563. objs[4] = m.getBrand();
  564. objs[5] = m.getCategoryName();
  565. objs[6] = m.getWeight() == null ? "" : m.getWeight().setScale(3, BigDecimal.ROUND_HALF_UP).toString();
  566. objs[7] = m.getCommodityUnit();
  567. objs[8] = otherMaterialMap.get(m.getId()) == null ? "" : otherMaterialMap.get(m.getId()).getCommodityUnit();
  568. objs[9] = m.getRatio() == null ? "" : m.getRatio().toString();
  569. objs[10] = m.getSku();
  570. objs[11] = m.getEnabled() ? "1" : "0";
  571. objs[12] = m.getEnableSerialNumber();
  572. objs[13] = m.getSystemSku();
  573. objs[14] = m.getBarCode();
  574. objs[15] = m.getDefaultPurchaseDecimal() == null ? "" : m.getDefaultPurchaseDecimal().toString();
  575. objs[16] = m.getDefaultWholesaleDecimal() == null ? "" : m.getDefaultWholesaleDecimal().toString();
  576. objs[17] = m.getOtherField1();
  577. objs[18] = m.getOtherField2();
  578. objs[19] = m.getOtherField3();
  579. objs[20] = m.getRemark();
  580. //仓库期初库存
  581. int i = 21;
  582. // for(Depot depot: depotList) {
  583. // BigDecimal number = misMap.get(m.getId() + "_" + depot.getId());
  584. // objs[i] = number == null ? "0" : number.setScale(2, BigDecimal.ROUND_HALF_UP).toString();
  585. // i++;
  586. // }
  587. objects.add(objs);
  588. }
  589. }
  590. File file = ExcelUtils.exportObjectsOneSheet(title, "*导入时本行内容请勿删除,切记!", names, title, objects);
  591. ExcelUtils.downloadExcel(file, file.getName(), response);
  592. }
  593. /**
  594. * 导入商品信息
  595. * @param file
  596. * @param request
  597. */
  598. @Override
  599. @Transactional(value = "transactionManager", rollbackFor = Exception.class)
  600. public BaseResponseInfo importExcel(MultipartFile file, HttpServletRequest request) throws Exception {
  601. BaseResponseInfo info = new BaseResponseInfo();
  602. try {
  603. Long beginTime = System.currentTimeMillis();
  604. //文件扩展名只能为xls
  605. String fileName = file.getOriginalFilename();
  606. if(StringUtil.isNotEmpty(fileName)) {
  607. String fileExt = fileName.substring(fileName.indexOf(".")+1);
  608. if(!"xls".equals(fileExt)) {
  609. throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_EXTENSION_ERROR_CODE,
  610. ExceptionConstants.MATERIAL_EXTENSION_ERROR_MSG);
  611. }
  612. }
  613. Workbook workbook = Workbook.getWorkbook(file.getInputStream());
  614. Sheet src = workbook.getSheet(0);
  615. //获取真实的行数,剔除掉空白行
  616. int rightRows = ExcelUtils.getRightRows(src);
  617. List<Depot> depotList= depotService.getDepot();
  618. int depotCount = depotList.size();
  619. Map<String, Long> depotMap = parseDepotToMap(depotList);
  620. User user = userService.getCurrentUser();
  621. List<MaterialWithInitStock> mList = new ArrayList<>();
  622. //单次导入超出1000条
  623. if(rightRows > 1002) {
  624. throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_IMPORT_OVER_LIMIT_CODE,
  625. String.format(ExceptionConstants.MATERIAL_IMPORT_OVER_LIMIT_MSG));
  626. }
  627. for (int i = 2; i < rightRows; i++) {
  628. String name = ExcelUtils.getContent(src, i, 0); //名称
  629. String standard = ExcelUtils.getContent(src, i, 1); //规格
  630. String model = ExcelUtils.getContent(src, i, 2); //型号
  631. String color = ExcelUtils.getContent(src, i, 3); //颜色
  632. String brand = ExcelUtils.getContent(src, i, 4); //品牌
  633. String categoryName = ExcelUtils.getContent(src, i, 5); //类别
  634. String weight = ExcelUtils.getContent(src, i, 6); //基础重量(kg)
  635. String expiryNum = ExcelUtils.getContent(src, i, 7); //保质期(天)
  636. String unit = ExcelUtils.getContent(src, i, 8); //基本单位
  637. //名称为空
  638. if(StringUtil.isEmpty(name)) {
  639. throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_NAME_EMPTY_CODE,
  640. String.format(ExceptionConstants.MATERIAL_NAME_EMPTY_MSG, i+1));
  641. }
  642. //名称长度超出
  643. if(name.length()>100) {
  644. throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_NAME_OVER_CODE,
  645. String.format(ExceptionConstants.MATERIAL_NAME_OVER_MSG, i+1));
  646. }
  647. //规格长度超出
  648. if(StringUtil.isNotEmpty(standard) && standard.length()>100) {
  649. throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_STANDARD_OVER_CODE,
  650. String.format(ExceptionConstants.MATERIAL_STANDARD_OVER_MSG, i+1));
  651. }
  652. //型号长度超出
  653. if(StringUtil.isNotEmpty(model) && model.length()>100) {
  654. throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_MODEL_OVER_CODE,
  655. String.format(ExceptionConstants.MATERIAL_MODEL_OVER_MSG, i+1));
  656. }
  657. //基本单位为空
  658. if(StringUtil.isEmpty(unit)) {
  659. throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_UNIT_EMPTY_CODE,
  660. String.format(ExceptionConstants.MATERIAL_UNIT_EMPTY_MSG, i+1));
  661. }
  662. //列别为空
  663. if(StringUtil.isEmpty(categoryName)) {
  664. throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_Category_Name_EMPTY_CODE,
  665. String.format(ExceptionConstants.MATERIAL_Category_Name_EMPTY_MSG, i+1));
  666. }
  667. MaterialWithInitStock m = new MaterialWithInitStock();
  668. m.setName(name);
  669. m.setStandard(standard);
  670. m.setModel(model);
  671. m.setColor(color);
  672. m.setBrand(brand);
  673. //通过名称生成助记码
  674. m.setMnemonic(PinYinUtil.getFirstLettersLo(name));
  675. Long categoryId = materialCategoryService.getCategoryIdByName(categoryName);
  676. //获取类型编码
  677. Long serial_no = categoryId == null ? null : materialCategoryService.getMaterialCategory(m.getCategoryId()).getSerialNo();
  678. //设置系统sku
  679. m.setSystemSku(serial_no + DateUtils.dateTimeNow());
  680. if(null!=categoryId){
  681. m.setCategoryId(categoryId);
  682. }
  683. if(StringUtil.isNotEmpty(weight)) {
  684. //校验基础重量是否是数字(含小数)
  685. if(!StringUtil.isPositiveBigDecimal(weight)) {
  686. throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_WEIGHT_NOT_DECIMAL_CODE,
  687. String.format(ExceptionConstants.MATERIAL_WEIGHT_NOT_DECIMAL_MSG, i+1));
  688. }
  689. m.setWeight(new BigDecimal(weight));
  690. }
  691. if(StringUtil.isNotEmpty(expiryNum)) {
  692. //校验保质期是否是正整数
  693. if(!StringUtil.isPositiveLong(expiryNum)) {
  694. throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_EXPIRY_NUM_NOT_INTEGER_CODE,
  695. String.format(ExceptionConstants.MATERIAL_EXPIRY_NUM_NOT_INTEGER_MSG, i+1));
  696. }
  697. //m.setExpiryNum(Integer.parseInt(expiryNum));
  698. }
  699. String manyUnit = ExcelUtils.getContent(src, i, 9); //副单位
  700. String barCode = ExcelUtils.getContent(src, i, 10); //基础条码
  701. String manyBarCode = ExcelUtils.getContent(src, i, 11); //副条码
  702. String ratio = ExcelUtils.getContent(src, i, 12); //比例
  703. String sku = ExcelUtils.getContent(src, i, 13); //多属性
  704. String purchaseDecimal = ExcelUtils.getContent(src, i, 14); //采购价
  705. String commodityDecimal = ExcelUtils.getContent(src, i, 15); //零售价
  706. String wholesaleDecimal = ExcelUtils.getContent(src, i, 16); //销售价
  707. String lowDecimal = ExcelUtils.getContent(src, i, 17); //最低售价
  708. String enabled = ExcelUtils.getContent(src, i, 18); //状态
  709. String enableSerialNumber = ExcelUtils.getContent(src, i, 19); //序列号
  710. String enableBatchNumber = ExcelUtils.getContent(src, i, 20); //批号
  711. String position = ExcelUtils.getContent(src, i, 21); //仓位货架
  712. String mfrs = ExcelUtils.getContent(src, i, 22); //制造商
  713. String otherField1 = ExcelUtils.getContent(src, i, 23); //自定义1
  714. String otherField2 = ExcelUtils.getContent(src, i, 24); //自定义2
  715. String otherField3 = ExcelUtils.getContent(src, i, 25); //自定义3
  716. String remark = ExcelUtils.getContent(src, i, 26); //备注
  717. // m.setPosition(StringUtil.isNotEmpty(position)?position:null);
  718. //m.setMfrs(StringUtil.isNotEmpty(mfrs)?mfrs:null);
  719. m.setOtherField1(StringUtil.isNotEmpty(otherField1)?otherField1:null);
  720. m.setOtherField2(StringUtil.isNotEmpty(otherField2)?otherField2:null);
  721. m.setOtherField3(StringUtil.isNotEmpty(otherField3)?otherField3:null);
  722. m.setRemark(remark);
  723. //状态格式错误
  724. if(!"1".equals(enabled) && !"0".equals(enabled)) {
  725. throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_ENABLED_ERROR_CODE,
  726. String.format(ExceptionConstants.MATERIAL_ENABLED_ERROR_MSG, i+1));
  727. }
  728. //基本条码为空
  729. if(StringUtil.isEmpty(barCode)) {
  730. throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_BARCODE_EMPTY_CODE,
  731. String.format(ExceptionConstants.MATERIAL_BARCODE_EMPTY_MSG, i+1));
  732. }
  733. //校验基本条码长度为4到40位
  734. if(!StringUtil.checkBarCodeLength(barCode)) {
  735. throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_BARCODE_LENGTH_ERROR_CODE,
  736. String.format(ExceptionConstants.MATERIAL_BARCODE_LENGTH_ERROR_MSG, barCode));
  737. }
  738. //校验副条码长度为4到40位
  739. if(StringUtil.isNotEmpty(manyBarCode) && !StringUtil.checkBarCodeLength(manyBarCode)) {
  740. throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_BARCODE_LENGTH_ERROR_CODE,
  741. String.format(ExceptionConstants.MATERIAL_BARCODE_LENGTH_ERROR_MSG, manyBarCode));
  742. }
  743. //批量校验excel中有无重复商品,是指名称、规格、型号、颜色、单位、多属性
  744. batchCheckExistMaterialListByParam(mList, name, standard, model, color, unit, sku);
  745. //批量校验excel中有无重复条码(1-文档自身校验,2-和数据库里面的商品校验)
  746. batchCheckExistBarCodeByParam(mList, barCode, manyBarCode);
  747. //设置商品拓展属性
  748. JSONObject materialExObj = new JSONObject();
  749. JSONObject basicObj = new JSONObject();
  750. basicObj.put("barCode", barCode);
  751. basicObj.put("commodityUnit", unit);
  752. basicObj.put("sku", sku);
  753. basicObj.put("purchaseDecimal", purchaseDecimal);
  754. basicObj.put("commodityDecimal", commodityDecimal);
  755. basicObj.put("wholesaleDecimal", wholesaleDecimal);
  756. basicObj.put("lowDecimal", lowDecimal);
  757. materialExObj.put("basic", basicObj);
  758. if(StringUtil.isNotEmpty(manyUnit) && StringUtil.isNotEmpty(ratio)){ //多单位
  759. //校验比例是否是数字(含小数)
  760. if(!StringUtil.isPositiveBigDecimal(ratio.trim())) {
  761. throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_RATIO_NOT_INTEGER_CODE,
  762. String.format(ExceptionConstants.MATERIAL_RATIO_NOT_INTEGER_MSG, i+1));
  763. }
  764. Long unitId = unitService.getUnitIdByParam(unit, manyUnit, new BigDecimal(ratio.trim()));
  765. if(unitId != null) {
  766. m.setUnitId(unitId);
  767. m.setUnit("");
  768. } else {
  769. throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_UNIT_MATE_CODE,
  770. String.format(ExceptionConstants.MATERIAL_UNIT_MATE_MSG, manyBarCode));
  771. }
  772. JSONObject otherObj = new JSONObject();
  773. otherObj.put("barCode", manyBarCode);
  774. otherObj.put("commodityUnit", manyUnit);
  775. otherObj.put("purchaseDecimal", parsePrice(purchaseDecimal,ratio));
  776. otherObj.put("commodityDecimal", parsePrice(commodityDecimal,ratio));
  777. otherObj.put("wholesaleDecimal", parsePrice(wholesaleDecimal,ratio));
  778. otherObj.put("lowDecimal", parsePrice(lowDecimal,ratio));
  779. materialExObj.put("other", otherObj);
  780. } else {
  781. m.setUnit(unit);
  782. m.setUnitId(null);
  783. }
  784. m.setMaterialExObj(materialExObj);
  785. m.setEnabled("1".equals(enabled));
  786. if(StringUtil.isNotEmpty(enableSerialNumber) && "1".equals(enableSerialNumber)) {
  787. m.setEnableSerialNumber("1");
  788. } else {
  789. m.setEnableSerialNumber("0");
  790. }
  791. if(StringUtil.isNotEmpty(enableBatchNumber) && "1".equals(enableBatchNumber)) {
  792. m.setEnableBatchNumber("1");
  793. } else {
  794. m.setEnableBatchNumber("0");
  795. }
  796. if("1".equals(enableSerialNumber) && "1".equals(enableBatchNumber)) {
  797. throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_ENABLE_MUST_ONE_CODE,
  798. String.format(ExceptionConstants.MATERIAL_ENABLE_MUST_ONE_MSG, barCode));
  799. }
  800. m.setStockMap(getStockMapCache(src, depotCount, depotMap, i));
  801. mList.add(m);
  802. }
  803. List<Long> deleteInitialStockMaterialIdList = new ArrayList<>();
  804. List<Long> deleteCurrentStockMaterialIdList = new ArrayList<>();
  805. List<MaterialInitialStock> insertInitialStockMaterialList = new ArrayList<>();
  806. List<MaterialCurrentStock> insertCurrentStockMaterialList = new ArrayList<>();
  807. //防止初始库存和当前库存出现重复
  808. Map<String, String> materialDepotInitialMap = new HashMap<>();
  809. Map<String, String> materialDepotCurrentMap = new HashMap<>();
  810. for(MaterialWithInitStock m: mList) {
  811. Long mId = 0L;
  812. //判断该商品是否存在,如果不存在就新增,如果存在就更新
  813. String basicBarCode = getBasicBarCode(m);
  814. //根据条件返回产品列表
  815. List<Material> materials = getMaterialListByParam(m.getName(),m.getStandard(),m.getModel(),m.getColor(),m.getUnit(),m.getUnitId(), basicBarCode);
  816. if(materials.size() == 0) { //产品列表为0,新增商品
  817. materialMapperEx.insertSelectiveEx(m);
  818. mId = m.getId();
  819. } else { //产品列表不为0,商品存在,修改商品属性
  820. mId = materials.get(0).getId();
  821. String materialJson = JSON.toJSONString(m);
  822. Material material = JSONObject.parseObject(materialJson, Material.class);
  823. material.setId(mId);
  824. materialMapper.updateByPrimaryKeySelective(material);
  825. //更新多单位
  826. if(material.getUnitId() == null) {
  827. materialMapperEx.setUnitIdToNull(material.getId());
  828. }
  829. //如果之前有保质期,则更新保质期
  830. // if(materials.get(0).getExpiryNum()!=null && material.getExpiryNum() == null) {
  831. // materialMapperEx.setExpiryNumToNull(material.getId());
  832. // }
  833. }
  834. //给商品新增或更新条码与价格相关信息
  835. JSONObject materialExObj = m.getMaterialExObj();
  836. insertOrUpdateMaterialExtend(materialExObj, "basic", "1", mId, user);
  837. insertOrUpdateMaterialExtend(materialExObj, "other", "0", mId, user);
  838. //给商品更新库存
  839. Map<Long, BigDecimal> stockMap = m.getStockMap();
  840. for(Depot depot: depotList){
  841. Long depotId = depot.getId();
  842. String materialDepotKey = mId + "_" + depotId;
  843. //获取初始库存
  844. BigDecimal initStock = getInitStock(mId, depotId);
  845. //excel里面的当前库存
  846. BigDecimal stock = stockMap.get(depot.getId());
  847. //新增或更新初始库存
  848. if(stock!=null && stock.compareTo(BigDecimal.ZERO)!=0) {
  849. String basicStr = materialExObj.getString("basic");
  850. MaterialExtend materialExtend = JSONObject.parseObject(basicStr, MaterialExtend.class);
  851. if(StringUtil.isNotEmpty(materialExtend.getSku())) {
  852. throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_SKU_BEGIN_STOCK_FAILED_CODE,
  853. String.format(ExceptionConstants.MATERIAL_SKU_BEGIN_STOCK_FAILED_MSG, materialExtend.getBarCode()));
  854. }
  855. buildChangeInitialStock(deleteInitialStockMaterialIdList, insertInitialStockMaterialList, materialDepotInitialMap, mId, depotId, materialDepotKey, stock);
  856. } else {
  857. if(initStock.compareTo(BigDecimal.ZERO)!=0) {
  858. buildChangeInitialStock(deleteInitialStockMaterialIdList, insertInitialStockMaterialList, materialDepotInitialMap, mId, depotId, materialDepotKey, stock);
  859. }
  860. }
  861. //新增或更新当前库存
  862. Long billCount = depotItemService.getCountByMaterialAndDepot(mId, depotId);
  863. if(billCount == 0) {
  864. if(stock!=null && stock.compareTo(BigDecimal.ZERO)!=0) {
  865. buildChangeCurrentStock(deleteCurrentStockMaterialIdList, insertCurrentStockMaterialList, materialDepotCurrentMap, mId, depotId, materialDepotKey, stock);
  866. } else {
  867. if(initStock.compareTo(BigDecimal.ZERO)!=0) {
  868. buildChangeCurrentStock(deleteCurrentStockMaterialIdList, insertCurrentStockMaterialList, materialDepotCurrentMap, mId, depotId, materialDepotKey, stock);
  869. }
  870. }
  871. } else {
  872. BigDecimal currentNumber = getCurrentStockByMaterialIdAndDepotId(mId, depotId);
  873. //当前库存的更新:减去初始库存,再加上导入的新初始库存
  874. if(currentNumber!=null && initStock!=null && stock!=null) {
  875. currentNumber = currentNumber.subtract(initStock).add(stock);
  876. }
  877. buildChangeCurrentStock(deleteCurrentStockMaterialIdList, insertCurrentStockMaterialList, materialDepotCurrentMap, mId, depotId, materialDepotKey, currentNumber);
  878. }
  879. }
  880. }
  881. //批量更新库存,先删除后新增
  882. if(insertInitialStockMaterialList.size()>0) {
  883. batchDeleteInitialStockByMaterialList(deleteInitialStockMaterialIdList);
  884. materialInitialStockMapperEx.batchInsert(insertInitialStockMaterialList);
  885. }
  886. if(insertCurrentStockMaterialList.size()>0) {
  887. batchDeleteCurrentStockByMaterialList(deleteCurrentStockMaterialIdList);
  888. materialCurrentStockMapperEx.batchInsert(insertCurrentStockMaterialList);
  889. }
  890. //添加日志
  891. logService.insertLog("商品",
  892. new StringBuffer(BusinessConstants.LOG_OPERATION_TYPE_IMPORT).append(mList.size()).append(BusinessConstants.LOG_DATA_UNIT).toString(),
  893. ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest());
  894. Long endTime = System.currentTimeMillis();
  895. logger.info("导入耗时:{}", endTime-beginTime);
  896. info.code = 200;
  897. info.data = "导入成功";
  898. } catch (BusinessRunTimeException e) {
  899. info.code = e.getCode();
  900. info.data = e.getData().get("message");
  901. } catch (Exception e) {
  902. logger.error(e.getMessage(), e);
  903. info.code = 500;
  904. info.data = "导入失败";
  905. }
  906. return info;
  907. }
  908. /**
  909. * 构造初始库存的变化
  910. */
  911. private void buildChangeInitialStock(List<Long> deleteInitialStockMaterialIdList, List<MaterialInitialStock> insertInitialStockMaterialList,
  912. Map<String, String> materialDepotInitialMap, Long mId, Long depotId, String materialDepotKey, BigDecimal stock) {
  913. if(materialDepotInitialMap.get(materialDepotKey)==null) {
  914. MaterialInitialStock materialInitialStock = new MaterialInitialStock();
  915. materialInitialStock.setMaterialId(mId);
  916. materialInitialStock.setDepotId(depotId);
  917. materialInitialStock.setNumber(stock);
  918. insertInitialStockMaterialList.add(materialInitialStock);
  919. deleteInitialStockMaterialIdList.add(mId);
  920. materialDepotInitialMap.put(materialDepotKey, materialDepotKey);
  921. }
  922. }
  923. /**
  924. * 构造当前库存的变化
  925. */
  926. private void buildChangeCurrentStock(List<Long> deleteCurrentStockMaterialIdList, List<MaterialCurrentStock> insertCurrentStockMaterialList,
  927. Map<String, String> materialDepotCurrentMap, Long mId, Long depotId, String materialDepotKey, BigDecimal stock) {
  928. if(materialDepotCurrentMap.get(materialDepotKey)==null) {
  929. MaterialCurrentStock materialCurrentStock = new MaterialCurrentStock();
  930. materialCurrentStock.setMaterialId(mId);
  931. materialCurrentStock.setDepotId(depotId);
  932. materialCurrentStock.setCurrentNumber(stock);
  933. insertCurrentStockMaterialList.add(materialCurrentStock);
  934. deleteCurrentStockMaterialIdList.add(mId);
  935. materialDepotCurrentMap.put(materialDepotKey, materialDepotKey);
  936. }
  937. }
  938. private Map<String, Long> parseDepotToMap(List<Depot> depotList) {
  939. Map<String, Long> map = new HashMap<>();
  940. for(Depot depot: depotList) {
  941. map.put(depot.getName(), depot.getId());
  942. }
  943. return map;
  944. }
  945. /**
  946. * 缓存各个仓库的库存信息
  947. * @param src 行数据
  948. * @param depotCount
  949. * @param depotMap
  950. * @param i 行数
  951. * @return
  952. * @throws Exception
  953. */
  954. private Map<Long, BigDecimal> getStockMapCache(Sheet src, int depotCount, Map<String, Long> depotMap, int i) throws Exception {
  955. Map<Long, BigDecimal> stockMap = new HashMap<>();
  956. for(int j = 1; j<= depotCount; j++) {
  957. int col = 26 + j;
  958. if(col < src.getColumns()){
  959. String depotName = ExcelUtils.getContent(src, 1, col); //获取仓库名称
  960. if(StringUtil.isNotEmpty(depotName)) {
  961. Long depotId = depotMap.get(depotName);
  962. if(depotId!=null && depotId!=0L){
  963. String stockStr = ExcelUtils.getContent(src, i, col);
  964. if(StringUtil.isNotEmpty(stockStr)) {
  965. stockMap.put(depotId, parseBigDecimalEx(stockStr));
  966. }
  967. }
  968. }
  969. }
  970. }
  971. return stockMap;
  972. }
  973. /**
  974. * 获取excel仓库库位信息
  975. * @param src 行数据
  976. * @param depotCount 仓库数量
  977. * @param depotMap 仓库集合
  978. * @param i
  979. * @return
  980. * @throws Exception
  981. */
  982. private Map<Long, String> getExcelDepot(Sheet src, int depotCount, Map<String, Long> depotMap, int i) throws Exception {
  983. Map<Long, String> stockMap = new HashMap<>();
  984. for(int j = 1; j<= depotCount; j++) {
  985. int col = 18 + j;
  986. if(col < src.getColumns()){
  987. String depotName = ExcelUtils.getContent(src, 1, col); //获取仓库名称
  988. if(StringUtil.isNotEmpty(depotName)) {
  989. Long depotId = depotMap.get(depotName);
  990. if(depotId!=null && depotId!=0L){
  991. String stockStr = ExcelUtils.getContent(src, i, col);
  992. if(StringUtil.isNotEmpty(stockStr)) {
  993. stockMap.put(depotId, stockStr);
  994. }
  995. }
  996. }
  997. }
  998. }
  999. return stockMap;
  1000. }
  1001. /**
  1002. * 批量校验excel中有无重复商品,是指名称、规格、型号、颜色、单位
  1003. * @param mList
  1004. */
  1005. @Override
  1006. public void batchCheckExistMaterialListByParam(List<MaterialWithInitStock> mList, String name, String standard,
  1007. String model, String color, String unit, String sku) {
  1008. for(MaterialWithInitStock material: mList){
  1009. String materialSku = "";
  1010. JSONObject materialExObj = material.getMaterialExObj();
  1011. if(materialExObj!=null && materialExObj.get("basic")!=null) {
  1012. JSONObject basicObj = materialExObj.getJSONObject("basic");
  1013. if(basicObj!=null && materialExObj.get("sku")!=null) {
  1014. materialSku = basicObj.getString("sku");
  1015. }
  1016. }
  1017. if(name.equals(material.getName()) &&
  1018. standard.equals(material.getStandard()) &&
  1019. model.equals(material.getModel()) &&
  1020. color.equals(material.getColor()) &&
  1021. unit.equals(material.getUnit()) &&
  1022. sku.equals(materialSku)) {
  1023. String info = name + "-" + standard + "-" + model + "-" + color + "-" + unit + "-" + sku;
  1024. throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_EXCEL_IMPORT_EXIST_CODE,
  1025. String.format(ExceptionConstants.MATERIAL_EXCEL_IMPORT_EXIST_MSG, info));
  1026. }
  1027. }
  1028. }
  1029. /**
  1030. * 批量校验excel中有无重复条码(1-文档自身校验,2-和数据库里面的商品校验)
  1031. * @param mList
  1032. */
  1033. @Override
  1034. public void batchCheckExistBarCodeByParam(List<MaterialWithInitStock> mList,
  1035. String barCode, String manyBarCode) throws Exception {
  1036. if(StringUtil.isNotEmpty(manyBarCode)) {
  1037. if(barCode.equals(manyBarCode)) {
  1038. //同一个商品的主副条码重复了,进行提醒
  1039. throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_EXCEL_IMPORT_BARCODE_EXIST_CODE,
  1040. String.format(ExceptionConstants.MATERIAL_EXCEL_IMPORT_BARCODE_EXIST_MSG, manyBarCode));
  1041. }
  1042. //EXCEL中有副条码在系统中已存在(除自身商品之外)
  1043. int count = materialExtendService.getCountByManyBarCodeWithoutUs(manyBarCode, barCode);
  1044. if (count>0) {
  1045. throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_EXCEL_IMPORT_MANY_BARCODE_EXIST_CODE,
  1046. String.format(ExceptionConstants.MATERIAL_EXCEL_IMPORT_MANY_BARCODE_EXIST_MSG, manyBarCode));
  1047. }
  1048. }
  1049. //EXCEL中有条码在系统中已存在
  1050. MaterialExtend materialExtend = materialExtendService.getInfoByBarCode(barCode);
  1051. if (materialExtend != null && !materialExtend.getBarCode().isEmpty()) {
  1052. throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_EXCEL_IMPORT_BARCODE_SYSTEM_EXIST_CODE,
  1053. String.format(ExceptionConstants.MATERIAL_EXCEL_IMPORT_BARCODE_SYSTEM_EXIST_MSG, barCode));
  1054. }
  1055. for(MaterialWithInitStock material: mList){
  1056. JSONObject materialExObj = material.getMaterialExObj();
  1057. String basicBarCode = "";
  1058. String otherBarCode = "";
  1059. if(materialExObj.get("basic")!=null) {
  1060. JSONObject basicObj = materialExObj.getJSONObject("basic");
  1061. basicBarCode = basicObj.getString("barCode");
  1062. }
  1063. if(materialExObj.get("other")!=null) {
  1064. JSONObject otherObj = materialExObj.getJSONObject("other");
  1065. otherBarCode = otherObj.getString("barCode");
  1066. }
  1067. if(barCode.equals(basicBarCode) || barCode.equals(otherBarCode)){
  1068. throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_EXCEL_IMPORT_BARCODE_EXIST_CODE,
  1069. String.format(ExceptionConstants.MATERIAL_EXCEL_IMPORT_BARCODE_EXIST_MSG, barCode));
  1070. }
  1071. if(StringUtil.isNotEmpty(manyBarCode)) {
  1072. if(manyBarCode.equals(basicBarCode) || manyBarCode.equals(otherBarCode)){
  1073. throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_EXCEL_IMPORT_BARCODE_EXIST_CODE,
  1074. String.format(ExceptionConstants.MATERIAL_EXCEL_IMPORT_BARCODE_EXIST_MSG, manyBarCode));
  1075. }
  1076. }
  1077. }
  1078. }
  1079. /**
  1080. * 给商品新增或更新条码与价格相关信息
  1081. * @param materialExObj
  1082. * @param type
  1083. * @param defaultFlag
  1084. * @param mId
  1085. * @param user
  1086. */
  1087. @Override
  1088. @Transactional(value = "transactionManager", rollbackFor = Exception.class)
  1089. public void insertOrUpdateMaterialExtend(JSONObject materialExObj, String type, String defaultFlag, Long mId, User user) throws Exception {
  1090. if(StringUtil.isExist(materialExObj.get(type))){
  1091. //获取对应的商品拓展字符
  1092. String basicStr = materialExObj.getString(type);
  1093. MaterialExtend materialExtend = JSONObject.parseObject(basicStr, MaterialExtend.class);
  1094. materialExtend.setMaterialId(mId);
  1095. materialExtend.setDefaultFlag(defaultFlag);
  1096. materialExtend.setCreateTime(new Date());
  1097. materialExtend.setUpdateTime(System.currentTimeMillis());
  1098. materialExtend.setCreateSerial(user.getLoginName());
  1099. materialExtend.setUpdateSerial(user.getLoginName());
  1100. Long meId = 0L;
  1101. if(StringUtil.isNotEmpty(materialExtend.getSku())){
  1102. //含sku的商品,特殊逻辑
  1103. meId = materialExtendService.selectIdByMaterialIdAndBarCode(mId, materialExtend.getBarCode());
  1104. List<MaterialExtend> meList = materialExtendService.getListByMaterialIdAndDefaultFlagAndBarCode(mId, "1", materialExtend.getBarCode());
  1105. if(meList.size() == 0) {
  1106. materialExtend.setDefaultFlag("1");
  1107. } else {
  1108. materialExtend.setDefaultFlag("0");
  1109. }
  1110. } else {
  1111. meId = materialExtendService.selectIdByMaterialIdAndDefaultFlag(mId, defaultFlag);
  1112. }
  1113. if(meId==0L){
  1114. materialExtendMapper.insertSelective(materialExtend);
  1115. } else {
  1116. materialExtend.setId(meId);
  1117. materialExtendMapper.updateByPrimaryKeySelective(materialExtend);
  1118. //如果金额为空,此处单独置空
  1119. materialExtendMapperEx.specialUpdatePrice(materialExtend);
  1120. }
  1121. }
  1122. }
  1123. @Override
  1124. public String getBasicBarCode(MaterialWithInitStock m) {
  1125. String barCode = "";
  1126. JSONObject materialExObj = m.getMaterialExObj();
  1127. if(StringUtil.isExist(materialExObj.get("basic"))) {
  1128. String basicStr = materialExObj.getString("basic");
  1129. MaterialExtend basicMaterialExtend = JSONObject.parseObject(basicStr, MaterialExtend.class);
  1130. barCode = basicMaterialExtend.getBarCode();
  1131. }
  1132. return barCode;
  1133. }
  1134. /**
  1135. * 根据条件返回产品列表
  1136. * @param name
  1137. * @param standard
  1138. * @param model
  1139. * @param color
  1140. * @param unit
  1141. * @param unitId
  1142. * @return
  1143. */
  1144. @Override
  1145. public List<Material> getMaterialListByParam(String name, String standard, String model, String color, String unit, Long unitId, String basicBarCode) throws Exception {
  1146. List<Material> list = new ArrayList<>();
  1147. MaterialExample example = new MaterialExample();
  1148. MaterialExample.Criteria criteria = example.createCriteria();
  1149. criteria.andNameEqualTo(name);
  1150. if (StringUtil.isNotEmpty(model)) {
  1151. criteria.andModelEqualTo(model);
  1152. }
  1153. if (StringUtil.isNotEmpty(color)) {
  1154. criteria.andColorEqualTo(color);
  1155. }
  1156. if (StringUtil.isNotEmpty(standard)) {
  1157. criteria.andStandardEqualTo(standard);
  1158. }
  1159. if (StringUtil.isNotEmpty(unit)) {
  1160. criteria.andUnitEqualTo(unit);
  1161. }
  1162. if (unitId !=null) {
  1163. criteria.andUnitIdEqualTo(unitId);
  1164. }
  1165. criteria.andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
  1166. list = materialMapper.selectByExample(example);
  1167. if(list.size()==0) {
  1168. //如果通过组合条件没有查到该商品,则通过条码再查一次
  1169. MaterialExtend materialExtend = materialExtendService.getInfoByBarCode(basicBarCode);
  1170. if(materialExtend != null && materialExtend.getMaterialId()!=null) {
  1171. Material material = new Material();
  1172. material.setId(materialExtend.getMaterialId());
  1173. list.add(material);
  1174. }
  1175. }
  1176. return list;
  1177. }
  1178. /**
  1179. * 写入当前库存
  1180. * @param depotId 仓库id
  1181. * @param mId 商品id
  1182. * @param stock 库存数量
  1183. */
  1184. @Override
  1185. @Transactional(value = "transactionManager", rollbackFor = Exception.class)
  1186. public void insertCurrentStockByMaterialAndDepot(Long depotId, Long mId, BigDecimal stock){
  1187. MaterialCurrentStock materialCurrentStock = new MaterialCurrentStock();
  1188. materialCurrentStock.setDepotId(depotId);
  1189. materialCurrentStock.setMaterialId(mId);
  1190. materialCurrentStock.setCurrentNumber(stock);
  1191. materialCurrentStockMapper.insertSelective(materialCurrentStock); //存入当前库存
  1192. }
  1193. /**
  1194. * 批量删除初始库存
  1195. * @param mIdList
  1196. */
  1197. @Override
  1198. @Transactional(value = "transactionManager", rollbackFor = Exception.class)
  1199. public void batchDeleteInitialStockByMaterialList(List<Long> mIdList){
  1200. MaterialInitialStockExample example = new MaterialInitialStockExample();
  1201. example.createCriteria().andMaterialIdIn(mIdList);
  1202. materialInitialStockMapper.deleteByExample(example);
  1203. }
  1204. /**
  1205. * 批量删除当前库存
  1206. * @param mIdList
  1207. */
  1208. @Override
  1209. @Transactional(value = "transactionManager", rollbackFor = Exception.class)
  1210. public void batchDeleteCurrentStockByMaterialList(List<Long> mIdList){
  1211. MaterialCurrentStockExample example = new MaterialCurrentStockExample();
  1212. example.createCriteria().andMaterialIdIn(mIdList);
  1213. materialCurrentStockMapper.deleteByExample(example);
  1214. }
  1215. @Override
  1216. public List<MaterialVo4Unit> getMaterialEnableSerialNumberList(String q, Integer offset, Integer rows)throws Exception {
  1217. List<MaterialVo4Unit> list =null;
  1218. try{
  1219. list= materialMapperEx.getMaterialEnableSerialNumberList(q, offset, rows);
  1220. }catch(Exception e){
  1221. JshException.readFail(logger, e);
  1222. }
  1223. return list;
  1224. }
  1225. @Override
  1226. public Long getMaterialEnableSerialNumberCount(String q)throws Exception {
  1227. Long count =null;
  1228. try{
  1229. count= materialMapperEx.getMaterialEnableSerialNumberCount(q);
  1230. }catch(Exception e){
  1231. JshException.readFail(logger, e);
  1232. }
  1233. return count;
  1234. }
  1235. @Override
  1236. public BigDecimal parseBigDecimalEx(String str) throws Exception{
  1237. if(!StringUtil.isEmpty(str)) {
  1238. return new BigDecimal(str);
  1239. } else {
  1240. return null;
  1241. }
  1242. }
  1243. @Override
  1244. public BigDecimal parsePrice(String price, String ratio) throws Exception{
  1245. if(StringUtil.isEmpty(price) || StringUtil.isEmpty(ratio)) {
  1246. return BigDecimal.ZERO;
  1247. } else {
  1248. BigDecimal pr=new BigDecimal(price);
  1249. BigDecimal r=new BigDecimal(ratio);
  1250. return pr.multiply(r);
  1251. }
  1252. }
  1253. /**
  1254. * 根据商品获取初始库存-多仓库
  1255. * @param depotList
  1256. * @param materialId
  1257. * @return
  1258. */
  1259. @Override
  1260. public BigDecimal getInitStockByMidAndDepotList(List<Long> depotList, Long materialId) {
  1261. BigDecimal stock = BigDecimal.ZERO;
  1262. MaterialInitialStockExample example = new MaterialInitialStockExample();
  1263. if(depotList!=null && depotList.size()>0) {
  1264. example.createCriteria().andMaterialIdEqualTo(materialId).andDepotIdIn(depotList)
  1265. .andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
  1266. } else {
  1267. example.createCriteria().andMaterialIdEqualTo(materialId)
  1268. .andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
  1269. }
  1270. List<MaterialInitialStock> list = materialInitialStockMapper.selectByExample(example);
  1271. if(list!=null && list.size()>0) {
  1272. for(MaterialInitialStock ms: list) {
  1273. stock = stock.add(ms.getNumber() == null ? BigDecimal.ZERO : ms.getNumber());
  1274. }
  1275. }
  1276. return stock;
  1277. }
  1278. /**
  1279. * 根据商品和仓库获取初始库存
  1280. * @param materialId
  1281. * @param depotId
  1282. * @return
  1283. */
  1284. @Override
  1285. public BigDecimal getInitStock(Long materialId, Long depotId) {
  1286. BigDecimal stock = BigDecimal.ZERO;
  1287. MaterialInitialStockExample example = new MaterialInitialStockExample();
  1288. example.createCriteria().andMaterialIdEqualTo(materialId).andDepotIdEqualTo(depotId)
  1289. .andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
  1290. List<MaterialInitialStock> list = materialInitialStockMapper.selectByExample(example);
  1291. if(list!=null && list.size()>0) {
  1292. stock = list.get(0).getNumber();
  1293. }
  1294. return stock;
  1295. }
  1296. /**
  1297. * 根据商品和仓库获取当前库存
  1298. * @param materialId
  1299. * @param depotId
  1300. * @return
  1301. */
  1302. @Override
  1303. public BigDecimal getCurrentStockByMaterialIdAndDepotId(Long materialId, Long depotId) {
  1304. BigDecimal stock = BigDecimal.ZERO;
  1305. MaterialCurrentStockExample example = new MaterialCurrentStockExample();
  1306. example.createCriteria().andMaterialIdEqualTo(materialId).andDepotIdEqualTo(depotId)
  1307. .andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
  1308. List<MaterialCurrentStock> list = materialCurrentStockMapper.selectByExample(example);
  1309. if(list!=null && list.size()>0) {
  1310. stock = list.get(0).getCurrentNumber();
  1311. } else {
  1312. stock = getInitStock(materialId,depotId);
  1313. }
  1314. return stock;
  1315. }
  1316. /**
  1317. * 根据商品列表获取初始库存Map
  1318. * @param list
  1319. * @return
  1320. */
  1321. @Override
  1322. public Map<Long,BigDecimal> getInitialStockMapByMaterialList(List<MaterialVo4Unit> list) {
  1323. Map<Long,BigDecimal> map = new HashMap<>();
  1324. List<Long> materialIdList = new ArrayList<>();
  1325. for(MaterialVo4Unit materialVo4Unit: list) {
  1326. materialIdList.add(materialVo4Unit.getId());
  1327. }
  1328. List<MaterialInitialStock> mcsList = materialInitialStockMapperEx.getInitialStockMapByIdList(materialIdList);
  1329. for(MaterialInitialStock materialInitialStock: mcsList) {
  1330. map.put(materialInitialStock.getMaterialId(), materialInitialStock.getNumber());
  1331. }
  1332. return map;
  1333. }
  1334. /**
  1335. * 根据商品列表获取当前库存Map
  1336. * @param list
  1337. * @return
  1338. */
  1339. @Override
  1340. public Map<Long,BigDecimal> getCurrentStockMapByMaterialList(List<MaterialVo4Unit> list) {
  1341. Map<Long,BigDecimal> map = new HashMap<>();
  1342. List<Long> materialIdList = new ArrayList<>();
  1343. for(MaterialVo4Unit materialVo4Unit: list) {
  1344. materialIdList.add(materialVo4Unit.getId());
  1345. }
  1346. List<MaterialCurrentStock> mcsList = materialCurrentStockMapperEx.getCurrentStockMapByIdList(materialIdList);
  1347. for(MaterialCurrentStock materialCurrentStock: mcsList) {
  1348. map.put(materialCurrentStock.getMaterialId(), materialCurrentStock.getCurrentNumber());
  1349. }
  1350. return map;
  1351. }
  1352. /**
  1353. * 根据商品和仓库获取安全库存信息
  1354. * @param materialId
  1355. * @param depotId
  1356. * @return
  1357. */
  1358. @Override
  1359. public MaterialInitialStock getSafeStock(Long materialId, Long depotId) {
  1360. MaterialInitialStock materialInitialStock = new MaterialInitialStock();
  1361. MaterialInitialStockExample example = new MaterialInitialStockExample();
  1362. example.createCriteria().andMaterialIdEqualTo(materialId).andDepotIdEqualTo(depotId)
  1363. .andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
  1364. List<MaterialInitialStock> list = materialInitialStockMapper.selectByExample(example);
  1365. if(list!=null && list.size()>0) {
  1366. materialInitialStock = list.get(0);
  1367. }
  1368. return materialInitialStock;
  1369. }
  1370. @Override
  1371. public List<MaterialVo4Unit> getMaterialByMeId(Long meId) {
  1372. List<MaterialVo4Unit> result = new ArrayList<MaterialVo4Unit>();
  1373. try{
  1374. if(meId!=null) {
  1375. result= materialMapperEx.getMaterialByMeId(meId);
  1376. }
  1377. }catch(Exception e){
  1378. JshException.readFail(logger, e);
  1379. }
  1380. return result;
  1381. }
  1382. @Override
  1383. public String getMaxBarCode() {
  1384. List<String> barCodeOldList = materialMapperEx.getBarCodeList();
  1385. // 使用 Stream API 处理条码列表
  1386. OptionalLong maxBarcode = barCodeOldList.stream()
  1387. .filter(StringUtil::isNumeric) // 过滤掉非数字条码
  1388. .mapToLong(Long::parseLong) // 将字符串转换为 Long 类型
  1389. .max(); // 获取最大值
  1390. // 如果存在最大值,返回它;否则返回 1000L
  1391. Long maxBarCodeOld = maxBarcode.orElse(1000L);
  1392. return maxBarCodeOld + "";
  1393. }
  1394. @Override
  1395. public List<String> getMaterialNameList() {
  1396. return materialMapperEx.getMaterialNameList();
  1397. }
  1398. /**
  1399. * 根据条码查询商品信息
  1400. * @param barCode 商品条码
  1401. */
  1402. @Override
  1403. public List<MaterialVo4Unit> getMaterialByBarCode(String barCode) {
  1404. String [] barCodeArray=barCode.split(",");
  1405. List<MaterialVo4Unit> list = materialMapperEx.getMaterialByBarCode(barCodeArray);
  1406. list.forEach(v -> {
  1407. v.setUnitList(v.getUnitId() == null ? null : unitService.getUnitListByID(v.getUnitId()));
  1408. });
  1409. return list;
  1410. }
  1411. @Override
  1412. public List<MaterialVo4Unit> getMaterialByBarCode(List<String> barCodeList) {
  1413. // 将 List<String> 转换为 String[]
  1414. String[] barCodeArray = barCodeList.toArray(new String[0]);
  1415. return materialMapperEx.getMaterialByBarCode(barCodeArray);
  1416. }
  1417. @Override
  1418. public List<MaterialVo4Unit> getMaterialByBarCodeAndWithOutMId(String barCode, Long mId) {
  1419. String [] barCodeArray=barCode.split(",");
  1420. return materialMapperEx.getMaterialByBarCodeAndWithOutMId(barCodeArray, mId);
  1421. }
  1422. @Override
  1423. public List<MaterialInitialStockWithMaterial> getInitialStockWithMaterial(List<Long> depotList) {
  1424. return materialMapperEx.getInitialStockWithMaterial(depotList);
  1425. }
  1426. @Override
  1427. public List<MaterialVo4Unit> getListWithStock(List<Long> depotList, List<Long> idList, String position, String materialParam,
  1428. Boolean moveAvgPriceFlag, Integer zeroStock, String column, String order,
  1429. Integer offset, Integer rows) throws Exception {
  1430. Map<Long, BigDecimal> initialStockMap = new HashMap<>();
  1431. List<MaterialInitialStockWithMaterial> initialStockList = getInitialStockWithMaterial(depotList);
  1432. for (MaterialInitialStockWithMaterial mism: initialStockList) {
  1433. initialStockMap.put(mism.getMaterialId(), mism.getNumber());
  1434. }
  1435. List<MaterialVo4Unit> dataList = materialMapperEx.getListWithStock(depotList, idList, position, materialParam, zeroStock, column, order, offset, rows);
  1436. for(MaterialVo4Unit item: dataList) {
  1437. if(moveAvgPriceFlag) {
  1438. item.setPurchaseDecimal(item.getCurrentUnitPrice());
  1439. item.setCurrentStockPrice(item.getCurrentStockMovePrice());
  1440. }
  1441. item.setUnitName(null!=item.getUnitId()?item.getUnitName() + "[多单位]":item.getUnitName());
  1442. item.setInitialStock(null!=initialStockMap.get(item.getId())?initialStockMap.get(item.getId()):BigDecimal.ZERO);
  1443. item.setBigUnitStock(getBigUnitStock(item.getCurrentStock(), item.getUnitId()));
  1444. if(fileUploadType == 2) {
  1445. item.setImgSmall("small");
  1446. item.setImgLarge("large");
  1447. }
  1448. }
  1449. return dataList;
  1450. }
  1451. @Override
  1452. public int getListWithStockCount(List<Long> depotList, List<Long> idList, String position, String materialParam, Integer zeroStock) {
  1453. return materialMapperEx.getListWithStockCount(depotList, idList, position, materialParam, zeroStock);
  1454. }
  1455. @Override
  1456. public MaterialVo4Unit getTotalStockAndPrice(List<Long> depotList, List<Long> idList, String position, String materialParam) {
  1457. return materialMapperEx.getTotalStockAndPrice(depotList, idList, position, materialParam);
  1458. }
  1459. /**
  1460. * 将小单位的库存换算为大单位的库存
  1461. * @param stock
  1462. * @param unitId
  1463. * @return
  1464. * @throws Exception
  1465. */
  1466. @Override
  1467. public String getBigUnitStock(BigDecimal stock, Long unitId) throws Exception {
  1468. String bigUnitStock = "";
  1469. if(null!= unitId) {
  1470. Unit unit = unitService.getUnit(unitId);
  1471. if(unit.getRatio()!=null && unit.getRatio().compareTo(BigDecimal.ZERO)!=0 && stock!=null) {
  1472. bigUnitStock = stock.divide(unit.getRatio(),2,BigDecimal.ROUND_HALF_UP) + unit.getOtherUnit();
  1473. }
  1474. }
  1475. return bigUnitStock;
  1476. }
  1477. /**
  1478. * 构造扩展信息
  1479. * @param mpArr
  1480. * @param m
  1481. * @return
  1482. */
  1483. @Override
  1484. public String getMaterialOtherByParam(String[] mpArr, MaterialVo4Unit m) {
  1485. String materialOther = "";
  1486. for (int i = 0; i < mpArr.length; i++) {
  1487. if (mpArr[i].equals("自定义1")) {
  1488. materialOther = materialOther + ((m.getOtherField1() == null || m.getOtherField1().equals("")) ? "" : "(" + m.getOtherField1() + ")");
  1489. }
  1490. if (mpArr[i].equals("自定义2")) {
  1491. materialOther = materialOther + ((m.getOtherField2() == null || m.getOtherField2().equals("")) ? "" : "(" + m.getOtherField2() + ")");
  1492. }
  1493. if (mpArr[i].equals("自定义3")) {
  1494. materialOther = materialOther + ((m.getOtherField3() == null || m.getOtherField3().equals("")) ? "" : "(" + m.getOtherField3() + ")");
  1495. }
  1496. }
  1497. return materialOther;
  1498. }
  1499. @Override
  1500. @Transactional(value = "transactionManager", rollbackFor = Exception.class)
  1501. public int batchSetMaterialCurrentStock(String ids) throws Exception {
  1502. int res = 0;
  1503. List<Long> idList = StringUtil.strToLongList(ids);
  1504. List<Depot> depotList = depotService.getAllList();
  1505. for(Long mId: idList) {
  1506. for(Depot depot: depotList) {
  1507. depotItemService.updateCurrentStockFun(mId, depot.getId());
  1508. res = 1;
  1509. }
  1510. }
  1511. return res;
  1512. }
  1513. @Override
  1514. @Transactional(value = "transactionManager", rollbackFor = Exception.class)
  1515. public int batchSetMaterialCurrentUnitPrice(String ids) throws Exception {
  1516. int res = 0;
  1517. List<Long> idList = StringUtil.strToLongList(ids);
  1518. for(Long mId: idList) {
  1519. DepotItem depotItem = new DepotItem();
  1520. depotItem.setMaterialId(mId);
  1521. depotItemService.updateCurrentUnitPrice(depotItem);
  1522. res = 1;
  1523. }
  1524. return res;
  1525. }
  1526. @Override
  1527. public int batchUpdate(JSONObject jsonObject) {
  1528. String ids = jsonObject.getString("ids");
  1529. String materialStr = jsonObject.getString("material");
  1530. List<Long> idList = StringUtil.strToLongList(ids);
  1531. Material material = JSONObject.parseObject(materialStr, Material.class);
  1532. MaterialExample example = new MaterialExample();
  1533. example.createCriteria().andIdIn(idList).andDeleteFlagNotEqualTo(BusinessConstants.DELETE_FLAG_DELETED);
  1534. return materialMapper.updateByExampleSelective(material, example);
  1535. }
  1536. @Override
  1537. public MaterialExtend getMaterialExtendBySerialNumber(String serialNumber) {
  1538. return materialMapperEx.getMaterialExtendBySerialNumber(serialNumber);
  1539. }
  1540. /**
  1541. * 根据商品id查询主表及子表信息
  1542. */
  1543. @Override
  1544. public Material getMaterialById(Long id){
  1545. Material material = materialMapper.selectByPrimaryKey(id);
  1546. // List<MaterialExtend> list = materialExtendMapper.selectByMId(id);
  1547. // material.setList(list);
  1548. return material;
  1549. }
  1550. @Override
  1551. public List<MaterialVo4Unit> getMaterialBySystemSku(List<String> systemSkuList) {
  1552. if (CollectionUtil.isEmpty(systemSkuList)){
  1553. return null;
  1554. }
  1555. String[] systemSkuArray = systemSkuList.toArray(new String[systemSkuList.size()]);
  1556. return materialMapperEx.getMaterialBySystemSku(systemSkuArray);
  1557. }
  1558. @Override
  1559. public List<MaterialCurrentStock4SystemSku> getMaterialCurrentPriceByIdList(List<Long> idList) {
  1560. if (CollectionUtil.isEmpty(idList)) {
  1561. return null;
  1562. }
  1563. return materialMapperEx.getMaterialCurrentPriceByIdList(idList);
  1564. }
  1565. /**
  1566. * 获取商品提醒
  1567. * @return
  1568. */
  1569. @Override
  1570. public MaterialWarnListVo getMaterialWarn() {
  1571. MaterialWarnListVo vo = new MaterialWarnListVo();
  1572. List<String> noMovingPinReminders = new ArrayList<>();
  1573. List<String> expirationReminders = new ArrayList<>();
  1574. List<String> inventoryReminders = new ArrayList<>();
  1575. //获取商品信息
  1576. List<Material> materials = list(new LambdaQueryWrapperX<Material>().isNotNull(Material::getMovingPinReminderCycle).eq(Material::getDeleteFlag,"0"));
  1577. //所有商品提醒信息赋值为空
  1578. this.update(new UpdateWrapper<Material>().set("reminder","").eq("delete_flag","0"));
  1579. //获取商品批次信息
  1580. List<MaterialBatch> extendList = materialBatchService.list(new LambdaQueryWrapperX<MaterialBatch>().gt(MaterialBatch::getInventory,"0").eq(MaterialBatch::getDeleteFlag,"0"));
  1581. Map<Long,Material> materialMap = new HashMap<>();
  1582. //过期提醒
  1583. SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
  1584. extendList.stream().filter(v -> v.getInventory() != null && v.getInventory().doubleValue() > 0 && v.getProductionDate() != null && v.getExpiryNum() != null)
  1585. .forEach(v ->{
  1586. if (DateUtils.differentDaysByMillisecond(v.getProductionDate(),new Date()) > (v.getExpiryNum() -30)){
  1587. String name = materialMapper.selectByPrimaryKey(v.getMaterialId()).getName();
  1588. String str = "商品名称:" + name
  1589. + ", 批次号:" + v.getBatchNumber()
  1590. + ", 条码:" + v.getBarCode()
  1591. + ", 生产日期:" + sdf.format(v.getProductionDate())
  1592. + ", 保质期:" + v.getExpiryNum() + "天"
  1593. + ", 库存:" + v.getInventory()
  1594. + ",即将要过期,请及时处理";
  1595. expirationReminders.add(str);
  1596. if (materialMap.get(v.getMaterialId()) == null){
  1597. materialMap.put(v.getMaterialId(),new Material().setId(v.getMaterialId()).setReminder("临期"));
  1598. }
  1599. }
  1600. });
  1601. vo.setExpirationReminder(expirationReminders);
  1602. //无动销提醒
  1603. materials.stream().filter( v -> v.getMovingPinReminderCycle() != null && !"".equals(v.getMovingPinReminderCycle()))
  1604. .forEach(v -> {
  1605. //获取商品最后一条动销订单数据
  1606. DepotHead depotHead = depotHeadService.getDepotLastByMaterialId(v.getId());
  1607. if (depotHead != null){
  1608. if (DateUtils.differentDaysByMillisecond(depotHead.getOperTime(),new Date()) > Integer.valueOf(v.getMovingPinReminderCycle())){
  1609. //当前时间对比订单时间是否大于动销提醒周期
  1610. String str = "商品名称:" + v.getName() + ",在[无动销提醒周期]内,无动销,请及时处理";
  1611. noMovingPinReminders.add(str);
  1612. if (materialMap.get(v.getId()) == null){
  1613. materialMap.put(v.getId(),new Material().setId(v.getId()).setReminder("无动销"));
  1614. }else {
  1615. materialMap.put(v.getId(),new Material().setId(v.getId()).setReminder(materialMap.get(v.getId()).getReminder() + ",无动销"));
  1616. }
  1617. }
  1618. }else{
  1619. //获取商品批次信息
  1620. MaterialExtend m = materialExtendMapper.selectByMId(v.getId()).get(0);
  1621. if (DateUtils.differentDaysByMillisecond(m.getCreateTime(),new Date()) > Integer.valueOf(v.getMovingPinReminderCycle())){
  1622. String str = "商品名称:" + v.getName() + ",在[无动销提醒周期]内,无动销,请及时处理";
  1623. noMovingPinReminders.add(str);
  1624. if (materialMap.get(v.getId()) == null){
  1625. materialMap.put(v.getId(),new Material().setId(v.getId()).setReminder("无动销"));
  1626. }else {
  1627. materialMap.get(v.getId()).setRemark(materialMap.get(v.getId()).getReminder() + ",无动销");
  1628. }
  1629. }
  1630. }
  1631. });
  1632. vo.setNoMovingPinReminder(noMovingPinReminders);
  1633. //库存提醒
  1634. MaterialInitialStockExample initialStockExample = new MaterialInitialStockExample();
  1635. initialStockExample.createCriteria().andDeleteFlagEqualTo("0");
  1636. List<MaterialInitialStock> initialStocks = materialInitialStockMapper.selectByExample(initialStockExample);
  1637. List<Depot> depotList = depotService.list();
  1638. Map<Long,String> depotMap = depotList.stream().collect(Collectors.toMap(Depot::getId,Depot::getName));
  1639. initialStocks.stream().filter(v -> v.getLowSafeStock() != null && v.getLowSafeStock().doubleValue() > 0)
  1640. .forEach(v -> {
  1641. //根据商品id和仓库id查询当前库存
  1642. BigDecimal currentNumber = getCurrentStockByMaterialIdAndDepotId(v.getMaterialId(),v.getDepotId());
  1643. if (currentNumber.doubleValue() <= v.getLowSafeStock().doubleValue()){
  1644. Material material = materialMapper.selectByPrimaryKey(v.getMaterialId());
  1645. String str = "商品名称:" + material.getName()
  1646. +depotMap.get(v.getDepotId()) + ",库存告警,请及时处理";
  1647. inventoryReminders.add(str);
  1648. if (materialMap.get(v.getMaterialId()) == null){
  1649. materialMap.put(v.getMaterialId(),new Material().setId(v.getMaterialId()).setReminder("库存危险"));
  1650. }else if (!materialMap.get(v.getMaterialId()).getReminder().contains("库存危险")){
  1651. materialMap.get(v.getMaterialId()).setReminder(materialMap.get(v.getMaterialId()).getReminder() + ",库存危险");
  1652. }
  1653. }
  1654. });
  1655. vo.setInventoryReminder(inventoryReminders);
  1656. List<Material> materialList = new ArrayList<>(materialMap.values());
  1657. this.updateBatchById(materialList);
  1658. return vo;
  1659. }
  1660. @Override
  1661. public BaseResponseInfo importExcelTwo(MultipartFile file, HttpServletRequest request) throws Exception {
  1662. BaseResponseInfo info = new BaseResponseInfo();
  1663. try {
  1664. Long beginTime = System.currentTimeMillis();
  1665. //文件扩展名只能为xls
  1666. String fileName = file.getOriginalFilename();
  1667. if(StringUtil.isNotEmpty(fileName)) {
  1668. String fileExt = fileName.substring(fileName.indexOf(".")+1);
  1669. if(!"xls".equals(fileExt) && !"xlsx".equals(fileExt)) {
  1670. throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_EXTENSION_ERROR_CODE,
  1671. ExceptionConstants.MATERIAL_EXTENSION_ERROR_MSG);
  1672. }
  1673. }
  1674. Workbook workbook = Workbook.getWorkbook(file.getInputStream());
  1675. Sheet src = workbook.getSheet(0);
  1676. //获取真实的行数,剔除掉空白行
  1677. int rightRows = ExcelUtils.getRightRows(src);
  1678. //获取所有仓库
  1679. List<Depot> depotList= depotService.getDepot();
  1680. int depotCount = depotList.size();
  1681. Map<String, Long> depotMap = parseDepotToMap(depotList);
  1682. User user = userService.getCurrentUser();
  1683. List<MaterialWithInitStock> mList = new ArrayList<>();
  1684. //单次导入超出1000条
  1685. if(rightRows > 1002) {
  1686. throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_IMPORT_OVER_LIMIT_CODE,
  1687. String.format(ExceptionConstants.MATERIAL_IMPORT_OVER_LIMIT_MSG));
  1688. }
  1689. for (int i = 2; i < rightRows; i++) {
  1690. String name = ExcelUtils.getContent(src, i, 0); //名称
  1691. String standard = ExcelUtils.getContent(src, i, 1); //规格
  1692. String model = ExcelUtils.getContent(src, i, 2); //型号
  1693. String color = ExcelUtils.getContent(src, i, 3); //颜色
  1694. String brand = ExcelUtils.getContent(src, i, 4); //品牌
  1695. String categoryName = ExcelUtils.getContent(src, i, 5); //类别
  1696. String weight = ExcelUtils.getContent(src, i, 6); //基础重量(kg)
  1697. String unit = ExcelUtils.getContent(src, i, 7); //基本单位
  1698. String manyUnit = ExcelUtils.getContent(src, i, 8); //副单位
  1699. String ratio = ExcelUtils.getContent(src, i, 9); //比例
  1700. String enabled = ExcelUtils.getContent(src, i, 10); //状态
  1701. String enableSerialNumber = ExcelUtils.getContent(src, i, 11); //序列号
  1702. String barCode = ExcelUtils.getContent(src, i, 12); //商品条码
  1703. String defaultPurchaseDecimal = ExcelUtils.getContent(src, i, 13); //默认销售价
  1704. String defaultWholesaleDecimal = ExcelUtils.getContent(src, i, 14); //默认采购价
  1705. String otherField1 = ExcelUtils.getContent(src, i, 15); //自定义1
  1706. String otherField2 = ExcelUtils.getContent(src, i, 16); //自定义2
  1707. String otherField3 = ExcelUtils.getContent(src, i, 17); //自定义3
  1708. String remark = ExcelUtils.getContent(src, i, 18); //备注
  1709. //校验字段
  1710. //名称为空
  1711. if(StringUtil.isEmpty(name)) {
  1712. throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_NAME_EMPTY_CODE,
  1713. String.format(ExceptionConstants.MATERIAL_NAME_EMPTY_MSG, i+1));
  1714. }
  1715. //名称长度超出
  1716. if(name.length()>100) {
  1717. throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_NAME_OVER_CODE,
  1718. String.format(ExceptionConstants.MATERIAL_NAME_OVER_MSG, i+1));
  1719. }
  1720. //规格长度超出
  1721. if(StringUtil.isNotEmpty(standard) && standard.length()>100) {
  1722. throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_STANDARD_OVER_CODE,
  1723. String.format(ExceptionConstants.MATERIAL_STANDARD_OVER_MSG, i+1));
  1724. }
  1725. //型号长度超出
  1726. if(StringUtil.isNotEmpty(model) && model.length()>100) {
  1727. throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_MODEL_OVER_CODE,
  1728. String.format(ExceptionConstants.MATERIAL_MODEL_OVER_MSG, i+1));
  1729. }
  1730. //类别为空
  1731. if(StringUtil.isEmpty(categoryName)) {
  1732. throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_Category_Name_EMPTY_CODE,
  1733. String.format(ExceptionConstants.MATERIAL_Category_Name_EMPTY_MSG, i+1));
  1734. }
  1735. //通过类型名查询类型编号
  1736. Long categoryId = materialCategoryService.getCategoryIdByName(categoryName);
  1737. if(null == categoryId){
  1738. //类别不存在
  1739. throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_TYPE_NOT_DECIMAL_CODE,
  1740. String.format(ExceptionConstants.MATERIAL_TYPE_NOT_DECIMAL_MSG, i+1));
  1741. }
  1742. if(StringUtil.isNotEmpty(weight)) {
  1743. //校验基础重量是否是数字(含小数)
  1744. if(!StringUtil.isPositiveBigDecimal(weight)) {
  1745. throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_WEIGHT_NOT_DECIMAL_CODE,
  1746. String.format(ExceptionConstants.MATERIAL_WEIGHT_NOT_DECIMAL_MSG, i+1));
  1747. }
  1748. }
  1749. //基本单位为空
  1750. if(StringUtil.isEmpty(unit)) {
  1751. throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_UNIT_EMPTY_CODE,
  1752. String.format(ExceptionConstants.MATERIAL_UNIT_EMPTY_MSG, i+1));
  1753. }
  1754. //状态格式错误
  1755. if(!"1".equals(enabled) && !"0".equals(enabled)) {
  1756. throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_ENABLED_ERROR_CODE,
  1757. String.format(ExceptionConstants.MATERIAL_ENABLED_ERROR_MSG, i+1));
  1758. }
  1759. //商品条码为空
  1760. if(StringUtil.isEmpty(barCode)) {
  1761. throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_BARCODE_EMPTY_CODE,
  1762. String.format(ExceptionConstants.MATERIAL_BARCODE_EMPTY_MSG, i+1));
  1763. }
  1764. //校验基本条码长度为4到40位
  1765. if(!StringUtil.checkBarCodeLength(barCode)) {
  1766. throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_BARCODE_LENGTH_ERROR_CODE,
  1767. String.format(ExceptionConstants.MATERIAL_BARCODE_LENGTH_ERROR_MSG, barCode));
  1768. }
  1769. //默认采购价为空
  1770. if(StringUtil.isEmpty(defaultPurchaseDecimal)) {
  1771. throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_DEFAULT_PURCHASE_DECIMAL_EMPTY_CODE,
  1772. String.format(ExceptionConstants.MATERIAL_DEFAULT_PURCHASE_DECIMAL_EMPTY_MSG, i+1));
  1773. }
  1774. //校验默认采购价是否是数字(含小数)
  1775. if(!StringUtil.isPositiveBigDecimal(defaultPurchaseDecimal)) {
  1776. throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_DEFAULT_PURCHASE_DECIMAL_NOT_DECIMAL_CODE,
  1777. String.format(ExceptionConstants.MATERIAL_DEFAULT_PURCHASE_DECIMAL_NOT_DECIMAL_MSG, i+1));
  1778. }
  1779. //默认销售价为空
  1780. if(StringUtil.isEmpty(defaultWholesaleDecimal)) {
  1781. throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_DEFAULT_WHOLESALE_DECIMAL_EMPTY_CODE,
  1782. String.format(ExceptionConstants.MATERIAL_DEFAULT_WHOLESALE_DECIMAL_EMPTY_MSG, i+1));
  1783. }
  1784. //校验默认销售价是否是数字(含小数)
  1785. if(!StringUtil.isPositiveBigDecimal(defaultWholesaleDecimal)) {
  1786. throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_DEFAULT_WHOLESALE_DECIMAL_NOT_DECIMAL_CODE,
  1787. String.format(ExceptionConstants.MATERIAL_DEFAULT_WHOLESALE_DECIMAL_NOT_DECIMAL_MSG, i+1));
  1788. }
  1789. //批量校验excel中有无重复条码(1-文档自身校验,2-和数据库里面的商品校验)
  1790. batchCheckExistBarCodeByParam(mList, barCode, null);
  1791. // Long depotId = null;
  1792. // if(StringUtil.isNotEmpty(depotName)) {
  1793. // //根据仓库名查询仓库id
  1794. // depotId = depotMapperEx.selectByConditionDepot(depotName,null,null).get(0).getId();
  1795. // if (depotId == null){
  1796. // //仓库不存在
  1797. // throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_DEPOT_NOT_DECIMAL_CODE,
  1798. // String.format(ExceptionConstants.MATERIAL_DEPOT_NOT_DECIMAL_MSG, i+1));
  1799. // }
  1800. // }
  1801. MaterialWithInitStock m = new MaterialWithInitStock();
  1802. //设置商品名字、规格、型号、颜色、品牌、类型id
  1803. m.setName(name);
  1804. m.setStandard(standard);
  1805. m.setModel(model);
  1806. m.setColor(color);
  1807. m.setBrand(brand);
  1808. m.setCategoryId(categoryId);
  1809. //通过名称生成助记码
  1810. m.setMnemonic(PinYinUtil.getFirstLettersLo(name));
  1811. //设置单位、备注、基础重量
  1812. m.setUnit(unit);
  1813. m.setRemark(remark);
  1814. m.setWeight(weight.isEmpty() ? null : new BigDecimal(weight));
  1815. //设置商品是否启用
  1816. m.setEnabled("1".equals(enabled));
  1817. //设置商品是否开启序列号
  1818. if(StringUtil.isNotEmpty(enableSerialNumber) && "1".equals(enableSerialNumber)) {
  1819. m.setEnableSerialNumber("1");
  1820. } else {
  1821. m.setEnableSerialNumber("0");
  1822. }
  1823. //获取类型编码
  1824. Long serial_no = categoryId == null ? null : materialCategoryService.getMaterialCategory(m.getCategoryId()).getSerialNo();
  1825. //设置系统sku
  1826. m.setSystemSku(serial_no + DateUtils.dateTimeNow() + RandomHelper.getRandomStr(6));
  1827. //设置默认采购价
  1828. m.setDefaultPurchaseDecimal(StringUtil.isNotEmpty(defaultPurchaseDecimal) ? new BigDecimal(defaultPurchaseDecimal) : null);
  1829. //设置默认销售价
  1830. m.setDefaultWholesaleDecimal(StringUtil.isNotEmpty(defaultWholesaleDecimal) ? new BigDecimal(defaultWholesaleDecimal) : null);
  1831. m.setOtherField1(StringUtil.isNotEmpty(otherField1)?otherField1:null);
  1832. m.setOtherField2(StringUtil.isNotEmpty(otherField2)?otherField2:null);
  1833. m.setOtherField3(StringUtil.isNotEmpty(otherField3)?otherField3:null);
  1834. m.setRemark(remark);
  1835. //设置商品拓展属性
  1836. JSONObject materialExObj = new JSONObject();
  1837. JSONObject basicObj = new JSONObject();
  1838. basicObj.put("commodityUnit", manyUnit.isEmpty() ? unit : manyUnit); //商品单位
  1839. basicObj.put("barCode", barCode); //商品条码
  1840. materialExObj.put("basic", basicObj);
  1841. if(StringUtil.isNotEmpty(manyUnit) && StringUtil.isNotEmpty(ratio)){ //多单位
  1842. //校验比例是否是数字(含小数)
  1843. if(!StringUtil.isPositiveBigDecimal(ratio.trim())) {
  1844. throw new BusinessRunTimeException(ExceptionConstants.MATERIAL_RATIO_NOT_INTEGER_CODE,
  1845. String.format(ExceptionConstants.MATERIAL_RATIO_NOT_INTEGER_MSG, i+1));
  1846. }
  1847. Long unitId = unitService.getUnitIdByParam(unit, manyUnit, new BigDecimal(ratio.trim()));
  1848. if(unitId != null) {
  1849. m.setUnitId(unitId);
  1850. m.setUnit("");
  1851. }
  1852. } else {
  1853. m.setUnit(unit);
  1854. m.setUnitId(null);
  1855. }
  1856. m.setMaterialExObj(materialExObj);
  1857. //设置仓库库位
  1858. m.setDepotMap(getExcelDepot(src, depotCount, depotMap, i));
  1859. mList.add(m);
  1860. }
  1861. //处理表单信息,转为对象集合
  1862. List<Material> materialList = parseMapByExcelData(mList);
  1863. for (Material material : materialList) {
  1864. //添加商品信息
  1865. materialMapperEx.insertSelectiveEx(material);
  1866. //获取excel商品添加库存
  1867. Map<Long, String> stockMap = material.getDepotMap();
  1868. for(Depot depot: depotList){
  1869. Long depotId = depot.getId();
  1870. //excel里面的当前库位
  1871. String position = stockMap.get(depot.getId());
  1872. //新增或更新初始库存
  1873. if(StringUtil.isNotEmpty(position)) {
  1874. MaterialInitialStock materialInitialStock = new MaterialInitialStock();
  1875. materialInitialStock.setDepotId(depotId);
  1876. materialInitialStock.setMaterialId(material.getId());
  1877. materialInitialStock.setPosition(position);
  1878. materialInitialStockMapper.insertSelective(materialInitialStock);
  1879. }
  1880. }
  1881. //添加商品子信息
  1882. for (MaterialExtend materialExtend : material.getList()) {
  1883. //设置商品id
  1884. materialExtend.setMaterialId( material.getId());
  1885. materialExtendService.insertMaterialExtend(materialExtend);
  1886. }
  1887. }
  1888. //添加日志
  1889. logService.insertLog("商品",
  1890. new StringBuffer(BusinessConstants.LOG_OPERATION_TYPE_IMPORT).append(mList.size()).append(BusinessConstants.LOG_DATA_UNIT).toString(),
  1891. ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest());
  1892. Long endTime = System.currentTimeMillis();
  1893. logger.info("导入耗时:{}", endTime-beginTime);
  1894. info.code = 200;
  1895. info.data = "导入成功";
  1896. } catch (BusinessRunTimeException e) {
  1897. info.code = e.getCode();
  1898. info.data = e.getData().get("message");
  1899. } catch (Exception e) {
  1900. logger.error(e.getMessage(), e);
  1901. info.code = 500;
  1902. info.data = "导入失败";
  1903. }
  1904. return info;
  1905. }
  1906. /**
  1907. * PDA库存查询
  1908. */
  1909. @Override
  1910. public List<PDADepotItemVO> inventoryInquiry(PDAInventoryDTO pdaInventoryDTO){
  1911. return materialMapper.inventoryInquiryList(pdaInventoryDTO);
  1912. }
  1913. /**
  1914. * 根据库位查询商品id集合
  1915. */
  1916. @Override
  1917. public List<Long> selectMaterialIdByPosition(String position) {
  1918. return materialInitialStockMapper.selectMaterialIdByPosition(position);
  1919. }
  1920. /**
  1921. * 根据类型id查询子类型集合
  1922. */
  1923. @Override
  1924. public List<Long> selectCategoryIds(Long id) {
  1925. List<Long> longs = new ArrayList<>();
  1926. longs.add(id);
  1927. List<MaterialCategory> list = materialCategoryService.list(new LambdaQueryWrapperX<MaterialCategory>().eq(MaterialCategory::getParentId,id).eq(MaterialCategory::getDeleteFlag,"0"));
  1928. for (MaterialCategory materialCategory : list) {
  1929. longs.addAll(selectCategoryIds(materialCategory.getId()));
  1930. }
  1931. return longs;
  1932. }
  1933. /**
  1934. * 查询库位树
  1935. */
  1936. @Override
  1937. public List<PDATypeTree> selectPosition(Long depotId) {
  1938. List<String> positions = materialInitialStockMapper.selectPosition(depotId);
  1939. Map<String,List<String>> map = new HashMap<>();
  1940. for (String s : positions) {
  1941. String [] str = s.split("-",2);
  1942. if (map.get(str[0]) == null){
  1943. List<String> list = new ArrayList<>();
  1944. map.put(str[0],list);
  1945. }
  1946. if (str.length > 1){
  1947. map.get(str[0]).add(str[1]);
  1948. }
  1949. }
  1950. List<PDATypeTree> typeTrees = new ArrayList<>();
  1951. map.forEach((key,value) -> {
  1952. PDATypeTree typeTree = new PDATypeTree();
  1953. typeTree.setLabel(key);
  1954. typeTree.setValue(key);
  1955. List<PDATypeTree> children = new ArrayList<>();
  1956. for (String s : value) {
  1957. PDATypeTree childrenTree = new PDATypeTree();
  1958. childrenTree.setLabel(key + "-" + s);
  1959. childrenTree.setValue(key + "-" + s);
  1960. children.add(childrenTree);
  1961. }
  1962. typeTree.setChildren(children);
  1963. typeTrees.add(typeTree);
  1964. });
  1965. return typeTrees;
  1966. }
  1967. /**
  1968. * 获取仓库id、商品id获取商品库位信息
  1969. * @param did 仓库id
  1970. * @param mid 商品id
  1971. * @return 库位
  1972. */
  1973. @Override
  1974. public String getPositionByDidAndMid(Long did, Long mid) {
  1975. MaterialInitialStock stock = materialInitialStockMapper.selectOne(new QueryWrapperX<MaterialInitialStock>().eq("depot_id",did).eq("material_id",mid));
  1976. return stock == null ? null : stock.getPosition();
  1977. }
  1978. /**
  1979. * 根据商品id查询商品库存
  1980. * @param mid 商品id
  1981. * @return 商品库存
  1982. */
  1983. @Override
  1984. public BigDecimal getMaterialStockByMid(Long mid){
  1985. List<Long> materialIdList = Arrays.asList(mid);
  1986. List<MaterialCurrentStock> mcsList = materialCurrentStockMapperEx.getCurrentStockMapByIdList(materialIdList);
  1987. return mcsList.size() == 0 ? BigDecimal.ZERO : mcsList.get(0).getCurrentNumber();
  1988. }
  1989. /**
  1990. * 根据商品id和仓库id查询商品当前库存
  1991. *
  1992. * @param mid 商品id
  1993. * @param did 仓库id
  1994. * @return 商品库存
  1995. */
  1996. @Override
  1997. public BigDecimal getMaterialStockByMidAndDid(Long mid, Long did) {
  1998. MaterialCurrentStock materialCurrentStock = materialCurrentStockMapper.selectOne(new LambdaQueryWrapperX<MaterialCurrentStock>().eq(MaterialCurrentStock::getMaterialId,mid).eq(MaterialCurrentStock::getDepotId,did).eq(MaterialCurrentStock::getDeleteFlag,"0"));
  1999. return materialCurrentStock == null ? BigDecimal.ZERO : materialCurrentStock.getCurrentNumber();
  2000. }
  2001. /**
  2002. * 解析excel表格数据为商品对象
  2003. */
  2004. private List<Material> parseMapByExcelData(List<MaterialWithInitStock> mList){
  2005. List<Material> materials = new ArrayList<>();
  2006. Map<String,Material> materialMap = new HashMap<>();
  2007. for (MaterialWithInitStock m : mList) {
  2008. String materialSku = "";
  2009. JSONObject materialExObj = m.getMaterialExObj();
  2010. JSONObject basicObj = materialExObj.getJSONObject("basic");
  2011. if(materialExObj!=null && materialExObj.get("basic")!=null) {
  2012. if(basicObj!=null && materialExObj.get("sku")!=null) {
  2013. materialSku = basicObj.getString("sku");
  2014. }
  2015. }
  2016. //名称,型号,品牌,规格,颜色,单位一样视为同一商品
  2017. String str = m.getName()
  2018. +"-" + m.getModel()
  2019. + "-" + m.getStandard()
  2020. + "-" + m.getBrand()
  2021. + "-" + m.getColor()
  2022. + "-" + m.getUnit();
  2023. if (materialMap.get(str) == null) {
  2024. //商品主表不存在,创建商品主表
  2025. Material material = m;
  2026. // //名称
  2027. // material.setName(m.getName());
  2028. // //型号
  2029. // material.setModel(m.getModel());
  2030. // //规格
  2031. // material.setStandard(m.getStandard());
  2032. // //品牌
  2033. // material.setBrand(m.getBrand());
  2034. // //助记码
  2035. // material.setMnemonic(m.getMnemonic());
  2036. // //颜色
  2037. // material.setColor(m.getColor());
  2038. // //商品类别
  2039. // material.setCategoryId(m.getCategoryId());
  2040. // //单位-单个
  2041. // material.setUnit(m.getUnit());
  2042. // //计量单位Id
  2043. // material.setUnitId(m.getUnitId());
  2044. // //备注
  2045. // material.setRemark(m.getRemark());
  2046. // //基础重量
  2047. // material.setWeight(m.getWeight());
  2048. // //启用 0-禁用 1-启用
  2049. // material.setEnabled(m.getEnabled());
  2050. // //自定义1
  2051. // material.setOtherField1(m.getOtherField1());
  2052. // //自定义2
  2053. // material.setOtherField2(m.getOtherField2());
  2054. // //自定义3
  2055. // material.setOtherField3(m.getOtherField3());
  2056. // //是否开启序列号
  2057. // material.setEnableSerialNumber(m.getEnableSerialNumber());
  2058. // //系统sku
  2059. // material.setSystemSku(m.getSystemSku());
  2060. List<MaterialExtend> list = new ArrayList<>();
  2061. material.setList(list);
  2062. material.setDepotMap(m.getDepotMap());
  2063. materialMap.put(str,material);
  2064. }
  2065. //添加子表信息
  2066. MaterialExtend materialExtend = new MaterialExtend();
  2067. //商品单位
  2068. materialExtend.setCommodityUnit(basicObj.getString("commodityUnit"));
  2069. //商品属性
  2070. materialExtend.setSku(materialSku);
  2071. //商品条码
  2072. materialExtend.setBarCode(basicObj.getString("barCode"));
  2073. materialMap.get(str).getList().add(materialExtend);
  2074. }
  2075. materialMap.values().forEach(v -> materials.add(v));
  2076. return materials;
  2077. }
  2078. }