InquiryServiceImpl.java 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986
  1. package com.uas.ps.inquiry.service.impl;
  2. import com.alibaba.fastjson.JSONObject;
  3. import com.uas.ps.core.util.CollectionUtils;
  4. import com.uas.ps.core.util.ContextUtils;
  5. import com.uas.ps.entity.Product;
  6. import com.uas.ps.entity.Status;
  7. import com.uas.ps.inquiry.AccessConfiguration;
  8. import com.uas.ps.inquiry.dao.EnterpriseDao;
  9. import com.uas.ps.inquiry.dao.InquiryEnRemindDao;
  10. import com.uas.ps.inquiry.dao.InquiryRemindDao;
  11. import com.uas.ps.inquiry.dao.ProductDao;
  12. import com.uas.ps.inquiry.dao.PublicInquiryDao;
  13. import com.uas.ps.inquiry.dao.PublicInquiryItemDao;
  14. import com.uas.ps.inquiry.dao.PurcInquiryDao;
  15. import com.uas.ps.inquiry.dao.PurcInquiryItemDao;
  16. import com.uas.ps.inquiry.dao.PurcInquiryItemInfoDao;
  17. import com.uas.ps.inquiry.entity.Constant;
  18. import com.uas.ps.inquiry.entity.InquiryDetailInfo;
  19. import com.uas.ps.inquiry.entity.InquiryProductInfo;
  20. import com.uas.ps.inquiry.entity.InquirySource;
  21. import com.uas.ps.inquiry.entity.MessageModel;
  22. import com.uas.ps.inquiry.entity.OrderStatus;
  23. import com.uas.ps.inquiry.model.Enterprise;
  24. import com.uas.ps.inquiry.model.InquiryRemind;
  25. import com.uas.ps.inquiry.model.PublicInquiry;
  26. import com.uas.ps.inquiry.model.PublicInquiryItem;
  27. import com.uas.ps.inquiry.model.PurcInquiry;
  28. import com.uas.ps.inquiry.model.PurcInquiryItem;
  29. import com.uas.ps.inquiry.model.PurcInquiryItemInfo;
  30. import com.uas.ps.inquiry.page.PageInfo;
  31. import com.uas.ps.inquiry.page.SearchFilter;
  32. import com.uas.ps.inquiry.page.criteria.CriterionExpression;
  33. import com.uas.ps.inquiry.page.criteria.LogicalExpression;
  34. import com.uas.ps.inquiry.page.criteria.PredicateUtils;
  35. import com.uas.ps.inquiry.page.criteria.SimpleExpression;
  36. import com.uas.ps.inquiry.page.exception.IllegalOperatorException;
  37. import com.uas.ps.inquiry.service.InquiryService;
  38. import com.uas.ps.inquiry.service.PublicInquiryService;
  39. import com.uas.ps.inquiry.support.InquiryBufferedLogger;
  40. import com.uas.ps.inquiry.util.FlexJsonUtils;
  41. import com.uas.ps.inquiry.util.HttpUtil;
  42. import com.uas.ps.inquiry.util.ThreadUtils;
  43. import javassist.NotFoundException;
  44. import org.slf4j.Logger;
  45. import org.slf4j.LoggerFactory;
  46. import org.springframework.beans.factory.annotation.Autowired;
  47. import org.springframework.data.domain.Page;
  48. import org.springframework.data.domain.Sort;
  49. import org.springframework.data.jpa.domain.Specification;
  50. import org.springframework.jdbc.core.BeanPropertyRowMapper;
  51. import org.springframework.jdbc.core.JdbcTemplate;
  52. import org.springframework.stereotype.Service;
  53. import org.springframework.util.StringUtils;
  54. import javax.persistence.criteria.CriteriaBuilder;
  55. import javax.persistence.criteria.CriteriaQuery;
  56. import javax.persistence.criteria.Predicate;
  57. import javax.persistence.criteria.Root;
  58. import java.net.URLEncoder;
  59. import java.util.ArrayList;
  60. import java.util.Date;
  61. import java.util.HashSet;
  62. import java.util.List;
  63. import java.util.Map;
  64. import java.util.Set;
  65. /**
  66. * 针对转询价报价单的数据查询操作
  67. *
  68. * Created by hejq on 2018-01-17.
  69. */
  70. @Service
  71. public class InquiryServiceImpl implements InquiryService {
  72. /**
  73. * 消息类型 (在B2B消息中拼接跳转单据详情url请求时需要)
  74. */
  75. private final String INQUIRY_TYPE = "公共询价";
  76. /**
  77. * 消息推送短信模板id
  78. */
  79. private final String SMS_TEMP_ID = "e6320a3c-89ac-4c77-a75f-62a727bce654";
  80. /**
  81. * 消息推送方式:邮件、短信、im
  82. */
  83. private final String SMS_TYPE = "MAIL_AND_SM_AND_IM";
  84. /**
  85. * 消费类型: 多个,MULTI
  86. */
  87. private final String CUST_TYPE = "MULTI";
  88. /**
  89. * 应用来源,主要是为了平台公共询价做处理
  90. */
  91. private String SOURCEAPP_MALL = "MALL";
  92. /**
  93. * 接收应用
  94. */
  95. private final String CONSUMERAPP_HIDE = "HIDE";
  96. /**
  97. * 消息类型 (在MALL消息中拼接求购询价待报价)
  98. */
  99. private final String INQUIRY_TYPE_SELLER_MALL = "MALL跳转卖家待报价页面";
  100. /**
  101. * 公共消息访问地址
  102. */
  103. private final String PS_MESSAGE_URL = ContextUtils.getBean(AccessConfiguration.class).getPsMessageUrl();
  104. /**
  105. * 询价统计通知发送人UU
  106. */
  107. private final Long MESSAGE_SENDERUU = ContextUtils.getBean(AccessConfiguration.class).getSenderuu();
  108. /**
  109. * 询价统计通知发送企业UU
  110. */
  111. private final Long MESSAGE_SENDERENUU = ContextUtils.getBean(AccessConfiguration.class).getSenderEnuu();
  112. @Autowired
  113. private PublicInquiryItemDao itemDao;
  114. @Autowired
  115. private PurcInquiryItemInfoDao inquiryItemDao;
  116. @Autowired
  117. private PurcInquiryDao purcInquiryDao;
  118. @Autowired
  119. private PublicInquiryDao inquiryDao;
  120. @Autowired
  121. private ProductDao productDao;
  122. @Autowired
  123. private PurcInquiryItemDao purcInquiryItemDao;
  124. @Autowired
  125. private PublicInquiryService inquiryService;
  126. @Autowired
  127. private InquiryRemindDao inquiryRemindDao;
  128. @Autowired
  129. private JdbcTemplate jdbcTemplate;
  130. @Autowired
  131. private EnterpriseDao enterpriseDao;
  132. @Autowired
  133. private PublicInquiryServiceImpl service;
  134. @Autowired
  135. private InquiryEnRemindDao inquiryEnRemindDao;
  136. /**
  137. * 公共物料访问地址
  138. */
  139. private final String PS_PRODUCT_URL = ContextUtils.getBean(AccessConfiguration.class).getPsProductUrl();
  140. /**
  141. * 日志
  142. */
  143. private static final Logger log = LoggerFactory.getLogger(InquiryServiceImpl.class);
  144. /**
  145. * 查询公共询价列表信息
  146. *
  147. * @param info 分页新
  148. * @param filter 过滤条件
  149. * @param state 过滤状态
  150. * @param overdue 是否过期 1、已过期;0、未过期
  151. * @return
  152. */
  153. @Override
  154. public Page<PurcInquiryItemInfo> findTodoByPageInfo(final PageInfo info, SearchFilter filter, String state, Integer overdue) {
  155. Sort sort = new Sort(Sort.Direction.DESC, "date");
  156. if (info.getOffset() == 0) {
  157. info.setOffset(info.getPageSize() * (info.getPageNumber() - 1));
  158. }
  159. info.setSort(sort);
  160. if (null != filter.getUserUU()) {
  161. info.filter("userUU", filter.getUserUU());
  162. info.expression(PredicateUtils.isNull("inquiry.enUU"));
  163. } else if (null != filter.getEnUU()) {
  164. info.filter("inquiry.enUU", filter.getEnUU());
  165. } else {
  166. throw new IllegalAccessError("非法访问");
  167. }
  168. if (null != filter) {
  169. if (StringUtils.hasText(filter.getKeyword())) {
  170. SimpleExpression cmpCode = new SimpleExpression("cmpCode", filter.getKeyword(), CriterionExpression.Operator.LIKE);
  171. SimpleExpression brand = new SimpleExpression("inbrand", filter.getKeyword(), CriterionExpression.Operator.LIKE);
  172. SimpleExpression[] simpleExpressions = new SimpleExpression[]{cmpCode, brand};
  173. LogicalExpression logicalExpression = PredicateUtils.or(simpleExpressions);
  174. info.expression(logicalExpression);
  175. }
  176. if (filter.getFromDate() != null) {
  177. info.expression(PredicateUtils.gte("date", new Date(filter.getFromDate()), false));
  178. }
  179. if (filter.getEndDate() != null) {
  180. info.expression(PredicateUtils.lte("date", new Date(filter.getEndDate()), false));
  181. }
  182. }
  183. if (null != state) {
  184. // 待报价
  185. if (state.equals(OrderStatus.todo.name())) {
  186. SimpleExpression amount = new SimpleExpression("offerAmount", Constant.NO, CriterionExpression.Operator.EQ);
  187. SimpleExpression[] simpleExpressions = new SimpleExpression[]{amount};
  188. LogicalExpression logicalExpression = PredicateUtils.and(simpleExpressions);
  189. info.expression(logicalExpression);
  190. }
  191. // 已报价
  192. if (state.equals(OrderStatus.done.name())) {
  193. SimpleExpression amount = new SimpleExpression("offerAmount", Constant.YES, CriterionExpression.Operator.GTE);
  194. SimpleExpression[] simpleExpressions = new SimpleExpression[]{amount};
  195. LogicalExpression logicalExpression = PredicateUtils.and(simpleExpressions);
  196. info.expression(logicalExpression);
  197. }
  198. // 已超过截止日期
  199. if (state.equals(OrderStatus.end.name())) {
  200. SimpleExpression date = new SimpleExpression("endDate", new Date(System.currentTimeMillis()), CriterionExpression.Operator.LT);
  201. SimpleExpression[] simpleExpressions = new SimpleExpression[]{date};
  202. LogicalExpression logicalExpression = PredicateUtils.and(simpleExpressions);
  203. info.expression(logicalExpression);
  204. }
  205. }
  206. if (null != overdue) {
  207. // 已超过截止日期
  208. if (overdue.equals((int)Constant.YES)) {
  209. SimpleExpression date = new SimpleExpression("endDate", new Date(System.currentTimeMillis()), CriterionExpression.Operator.LT);
  210. SimpleExpression[] simpleExpressions = new SimpleExpression[]{date};
  211. LogicalExpression logicalExpression = PredicateUtils.and(simpleExpressions);
  212. info.expression(logicalExpression);
  213. } else if (overdue.equals((int)Constant.NO)) {
  214. info.expression(PredicateUtils.gte("endDate", new Date(System.currentTimeMillis()), false));
  215. }
  216. }
  217. return inquiryItemDao.findAll(new Specification<PurcInquiryItemInfo>() {
  218. @Override
  219. public Predicate toPredicate(Root<PurcInquiryItemInfo> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
  220. query.where(info.getPredicates(root, query, builder));
  221. return null;
  222. }
  223. }, info);
  224. }
  225. /**
  226. * 保存公共询价
  227. *
  228. * @param currentInquiry 询价信息
  229. */
  230. @Override
  231. public PurcInquiry saveInquiry(PurcInquiry currentInquiry) throws NotFoundException {
  232. //通过流水号和企业号找到公共询价单
  233. List<PurcInquiry> existInquiryList = purcInquiryDao.findByCodeAndEnUU(currentInquiry.getCode(), currentInquiry.getEnUU());
  234. if (!CollectionUtils.isEmpty(existInquiryList)) {
  235. throw new IllegalOperatorException("单号重复");
  236. } else {
  237. if (null != currentInquiry.getEnUU()) {
  238. Enterprise e = enterpriseDao.findOne(currentInquiry.getEnUU());
  239. if (null != e) {
  240. currentInquiry.setEnName(e.getEnName());
  241. } else {
  242. throw new NotFoundException("询价企业不存在");
  243. }
  244. }
  245. //保存询价单
  246. PurcInquiry inquiry = purcInquiryDao.save(currentInquiry);
  247. //判断询价明细单是否为空
  248. if (!CollectionUtils.isEmpty(currentInquiry.getInquiryItems())) {
  249. List<PurcInquiryItem> items = new ArrayList<PurcInquiryItem>();
  250. //给询价明细单属性设置初始值
  251. for (PurcInquiryItem item : currentInquiry.getInquiryItems()) {
  252. item.setInquiry(inquiry);
  253. item.setOfferAmount(0);
  254. item.setStatus((short) Status.NOT_REPLY.value());
  255. item.setIsOpen(Constant.YES);
  256. if (null == item.getDate()) {
  257. //设置提交时间
  258. item.setDate(new Date(System.currentTimeMillis()));
  259. }
  260. // 这里设置物料信息的冗余字段
  261. if (null != item.getProduct()) {
  262. item.setProdTitle(item.getProduct().getTitle());
  263. item.setProdCode(item.getProduct().getCode());
  264. item.setSpec(item.getProduct().getSpec());
  265. item.setInbrand(item.getProduct().getBrand());
  266. item.setCmpCode(item.getProduct().getCmpCode());
  267. }
  268. if (null == item.getCmpCode() || item.getCmpCode().equals("无")) {
  269. item.setCmpCode(item.getSpec());
  270. }
  271. if (null == item.getEndDate()) {
  272. item.setEndDate(inquiry.getEndDate());
  273. }
  274. items.add(item);
  275. }
  276. //保存询价单明细表
  277. items = purcInquiryItemDao.save(items);
  278. final List<PurcInquiryItem> purcInquiryItems = items;
  279. final String sourceapp = inquiry.getSourceapp();
  280. final Long enuu = inquiry.getEnUU();
  281. if (null != inquiry.getSourceapp()) {
  282. ThreadUtils.task(new Runnable() {
  283. @Override
  284. public void run() {
  285. try {
  286. //生成推荐询价表
  287. inquiryService.notifyMessage(purcInquiryItems, sourceapp);
  288. if (!StringUtils.isEmpty(enuu)) {
  289. saveProduct(purcInquiryItems, sourceapp);
  290. }
  291. } catch (Exception e) {
  292. e.printStackTrace();
  293. }
  294. }
  295. }).run();
  296. }
  297. }
  298. return inquiry;
  299. }
  300. }
  301. /**
  302. * 可配置的定时任务
  303. */
  304. @Override
  305. public List<InquiryRemind> testMessage(Date startTime, Date endTime, Long useruu, Long enuu){
  306. log.info("公共询价","9点定时统计询价单总数服务开启");
  307. List<InquiryRemind> list = inquiryRemindDao.findTestInfo(startTime,endTime,useruu,enuu);
  308. log.info("公共询价","9点定时统计询价单总数服务结束");
  309. return list;
  310. }
  311. /**
  312. * 发布询价成功后加入当前用户的个人物料库
  313. * @param inquiryItems
  314. * @param sourceApp
  315. */
  316. public void saveProduct(List<PurcInquiryItem> inquiryItems, String sourceApp) {
  317. List<Product> products = new ArrayList<>();
  318. for (PurcInquiryItem item : inquiryItems) {
  319. Product product = new Product();
  320. // 需要哪些字段
  321. product.setEnUU(item.getInquiry().getEnUU());
  322. product.setUserUU(item.getInquiry().getRecorderUU());
  323. product.setCmpCode(item.getCmpCode());
  324. product.setBrand(item.getInbrand());
  325. product.setpCmpCode(item.getCmpCode());
  326. product.setpBrandEn(item.getInbrand());
  327. product.setStandard((short) 0);
  328. product.setCreateTime(new Date());
  329. product.setSourceApp(sourceApp);
  330. product.setSpec(StringUtils.isEmpty(item.getSpec()) ? item.getCmpCode() : item.getSpec());
  331. product.setKind(item.getProdTitle());
  332. products.add(product);
  333. }
  334. // 调用公共物料服务的接口
  335. try {
  336. String url = PS_PRODUCT_URL + "/product/save/inquiry/batch";
  337. long start = System.currentTimeMillis();
  338. String res = HttpUtil.doPost(url, FlexJsonUtils.toJsonDeep(products));
  339. log.info("/product/save/inquiry/batch 耗时:" + (System.currentTimeMillis() - start) + "物料数:" + products.size());
  340. JSONObject result = JSONObject.parseObject(res);
  341. Boolean success = (Boolean) result.get("success");
  342. if (success) {
  343. log.info("保存询价单后,批量保存物料成功:" + products.size());
  344. } else {
  345. log.info("保存询价单后,批量保存物料失败,返回:" + result.get("message"));
  346. }
  347. } catch (Exception e) {
  348. e.printStackTrace();
  349. }
  350. }
  351. /**
  352. * 通过报价明细id对供应商报价进行相关审核操作
  353. *
  354. * @param id 报价明细id
  355. * @param status 状态
  356. */
  357. @Override
  358. public void decideQuote(Long id, Short status) {
  359. PublicInquiryItem item = itemDao.findOne(id);
  360. // 验证是否重复操作
  361. validateInquiry(item);
  362. item.setAgreed(status);
  363. item.setDecideDownStatus((short) Status.NOT_UPLOAD.value());
  364. itemDao.save(item);
  365. // 更新询价推荐表相关信息
  366. if (status.equals(Constant.YES)) {
  367. inquiryRemindDao.updateStatus(item.getSourceId(), Status.ALLOW.value(), item.getVendUU());
  368. inquiryEnRemindDao.updateStatus(item.getSourceId(), Status.ALLOW.value(), item.getVendUU());
  369. updatePurcInquiryItemAgreed(item.getSourceId(), status);
  370. } else if (status.equals(Constant.NO)) {
  371. inquiryRemindDao.updateStatus(item.getSourceId(), Status.NOTALLOW.value(), item.getVendUU());
  372. inquiryEnRemindDao.updateStatus(item.getSourceId(), Status.NOTALLOW.value(), item.getVendUU());
  373. }
  374. // 更新原公共询价单该条明细,设置为不可报价
  375. String sql = "update purc$puinquiryitems set id_overdue = 1 where id_id = " + item.getSourceId();
  376. jdbcTemplate.update(sql);
  377. inquiryService.notifyDecide(item, InquirySource.B2B.name());
  378. }
  379. /**
  380. * 商城通过报价明细id采纳对供应商报价
  381. *
  382. * @param id 报价明细id
  383. * @param status 状态
  384. */
  385. @Override
  386. public void adpotQuote(Long id, Short status) {
  387. PublicInquiryItem item = itemDao.findOne(id);
  388. // 验证是否重复操作
  389. validateInquiry(item);
  390. item.setAgreed(status);
  391. item.setDecideDownStatus((short) Status.NOT_UPLOAD.value());
  392. itemDao.save(item);
  393. // 更新询价推荐表相关信息
  394. if (status.equals(Constant.YES)) {
  395. inquiryRemindDao.updateStatus(item.getSourceId(), Status.ALLOW.value(), item.getVendUU());
  396. inquiryEnRemindDao.updateStatus(item.getSourceId(), Status.ALLOW.value(), item.getVendUU());
  397. // 修改询价明细agreed字段为1,表示存在已采纳报价明细
  398. updatePurcInquiryItemAgreed(item.getSourceId(), status);
  399. } else if (status.equals(Constant.NO)) {
  400. inquiryRemindDao.updateStatus(item.getSourceId(), Status.NOTALLOW.value(), item.getVendUU());
  401. inquiryEnRemindDao.updateStatus(item.getSourceId(), Status.NOTALLOW.value(), item.getVendUU());
  402. }
  403. // 更新原公共询价单该条明细,设置为不可报价
  404. String sql = "update purc$puinquiryitems set id_overdue = 1 where id_id = " + item.getSourceId();
  405. jdbcTemplate.update(sql);
  406. // 如果是替代料报价的采纳,添加替代料到询价方对应物料
  407. if (status.equals(Constant.YES)) {
  408. addProductReplace(item);
  409. }
  410. inquiryService.adoptMessage(item, InquirySource.MALL.name());
  411. }
  412. /**
  413. * 更新询价单明细采纳状态
  414. * @param id 询价单明细id
  415. * @param agreed 采纳参数 1 或 0
  416. */
  417. private void updatePurcInquiryItemAgreed(Long id, short agreed) {
  418. PurcInquiryItem inquiryItem = purcInquiryItemDao.findOne(id);
  419. inquiryItem.setAgreed(agreed);
  420. purcInquiryItemDao.save(inquiryItem);
  421. }
  422. /**
  423. * 替代料报价采纳之后,添加替代料到询价企业对应物料
  424. * @param item 报价明细
  425. */
  426. private void addProductReplace(PublicInquiryItem item) {
  427. if (null != item.getIsReplace() && Constant.YES == item.getIsReplace() && !StringUtils.isEmpty(item.getReplaceCmpCode())
  428. && !StringUtils.isEmpty(item.getReplaceBrand())) {
  429. try {
  430. String url = PS_PRODUCT_URL + "/product/save/inquiry?replaceCmpCode=" + URLEncoder.encode(item.getReplaceCmpCode(), "UTF-8")
  431. + "&replaceBrand=" + URLEncoder.encode(item.getReplaceBrand(), "UTF-8");
  432. Product product;
  433. if (null != item.getProductId()) {
  434. product = productDao.findOne(item.getProductId());
  435. product.setUserUU(item.getInquiry().getRecorderUU());
  436. } else {
  437. product = new Product();
  438. // 需要哪些字段
  439. product.setEnUU(item.getInquiry().getEnUU());
  440. product.setUserUU(item.getInquiry().getRecorderUU());
  441. product.setCmpCode(item.getCmpCode());
  442. product.setBrand(item.getInbrand());
  443. product.setpCmpCode(item.getCmpCode());
  444. product.setpBrandEn(item.getInbrand());
  445. product.setStandard((short) 0);
  446. product.setCreateTime(new Date());
  447. product.setSourceApp(item.getInquiry().getSourceApp());
  448. product.setSpec(StringUtils.isEmpty(item.getSpec()) ? item.getCmpCode() : item.getSpec());
  449. product.setKind(item.getProdTitle());
  450. }
  451. long start = System.currentTimeMillis();
  452. String res = HttpUtil.doPost(url, FlexJsonUtils.toJsonDeep(product));
  453. log.info("/product/save/inquiry 耗时:" + (System.currentTimeMillis() - start));
  454. log.info("采纳替代物料报价,添加替代物料返回" + res);
  455. } catch (Exception e) {
  456. log.info("/product/save/inquiry 替代料报价采纳之后保存到个人物料库中 出错:" + e.getMessage());
  457. e.printStackTrace();
  458. }
  459. }
  460. }
  461. /**
  462. * 验证是否已采纳或拒绝
  463. * @param item 报价单
  464. */
  465. private void validateInquiry(PublicInquiryItem item) {
  466. if (null != item.getAgreed()) {
  467. if (item.getAgreed().equals(Constant.YES)) {
  468. throw new IllegalOperatorException("该报价已被采纳,请勿重复处理");
  469. } else if (item.getAgreed().equals(Constant.NO)) {
  470. throw new IllegalOperatorException("该报价已被拒绝,请勿重复处理");
  471. }
  472. }
  473. }
  474. /**
  475. * 商城通过报价明细id拒绝对供应商报价
  476. *
  477. * @param id 报价明细id
  478. * @param status 状态
  479. */
  480. @Override
  481. public void refuseQuote(Long id, Short status,String refusereason) {
  482. PublicInquiryItem item = itemDao.findOne(id);
  483. // 验证是否重复操作
  484. validateInquiry(item);
  485. item.setAgreed(status);
  486. item.setRefusereason(refusereason);
  487. item.setDecideDownStatus((short) Status.NOT_UPLOAD.value());
  488. itemDao.save(item);
  489. if (status.equals(Constant.YES)) {
  490. inquiryRemindDao.updateStatus(item.getSourceId(), Status.ALLOW.value(), item.getVendUU());
  491. inquiryEnRemindDao.updateStatus(item.getSourceId(), Status.ALLOW.value(), item.getVendUU());
  492. updatePurcInquiryItemAgreed(item.getSourceId(), status);
  493. } else if (status.equals(Constant.NO)) {
  494. inquiryRemindDao.updateStatus(item.getSourceId(), Status.NOTALLOW.value(), item.getVendUU());
  495. inquiryEnRemindDao.updateStatus(item.getSourceId(), Status.NOTALLOW.value(), item.getVendUU());
  496. }
  497. inquiryService.refuseMessage(item,InquirySource.MALL.name());
  498. }
  499. /**
  500. * 针对客户,查询供应商报价详情
  501. *
  502. * @param id 主表id
  503. * @param enuu 企业UU
  504. * @return
  505. */
  506. @Override
  507. public InquiryDetailInfo findById(Long id, Long enuu) {
  508. PublicInquiry inquiry = inquiryDao.findOne(id);
  509. InquiryDetailInfo inquiryInfo = new InquiryDetailInfo();
  510. if (inquiry != null) {
  511. inquiryInfo.setAttachs(inquiry.getAttachs());
  512. inquiryInfo.setAuditor(inquiry.getAuditor());
  513. inquiryInfo.setCheck(inquiry.getCheck());
  514. inquiryInfo.setCode(inquiry.getCode());
  515. inquiryInfo.setDate(inquiry.getDate());
  516. inquiryInfo.setEndDate(inquiry.getEndDate());
  517. inquiryInfo.setEnterprise(inquiry.getEnterprise());
  518. inquiryInfo.setEnUU(inquiry.getEnUU());
  519. inquiryInfo.setEnvironment(inquiry.getEnvironment());
  520. inquiryInfo.setId(inquiry.getId());
  521. inquiryInfo.setIsOpen(inquiry.getIsOpen());
  522. inquiryInfo.setOverdue(inquiry.getOverdue());
  523. inquiryInfo.setPriceType(inquiry.getPriceType());
  524. inquiryInfo.setRecorder(inquiry.getRecorder());
  525. inquiryInfo.setRecorderUU(inquiry.getRecorderUU());
  526. inquiryInfo.setRemark(inquiry.getRemark());
  527. inquiryInfo.setSourceApp(inquiry.getSourceApp());
  528. inquiryInfo.setSourceId(inquiry.getSourceId());
  529. inquiryInfo.setShip(inquiry.getShip());
  530. inquiryInfo.setInvoice(inquiry.getInvoice());
  531. inquiryInfo.setInquirytype(inquiry.getInquirytype());
  532. Set<Long> ids = new HashSet<Long>();
  533. List<Long> idList = new ArrayList<>();
  534. Set<InquiryProductInfo> products = new HashSet<InquiryProductInfo>();
  535. if (!CollectionUtils.isEmpty(inquiry.getInquiryItems())) {
  536. for (PublicInquiryItem item : inquiry.getInquiryItems()) {
  537. if (item.getProductId() != null) {
  538. idList.add(item.getProductId());
  539. ids.addAll(idList);
  540. } else {
  541. InquiryProductInfo productInfo = new InquiryProductInfo();
  542. Set<PublicInquiryItem> items = new HashSet<PublicInquiryItem>();
  543. productInfo.setBrand(item.getBrand());
  544. productInfo.setSpec(item.getSpec());
  545. productInfo.setCode(item.getProdCode());
  546. productInfo.setTitle(item.getProdTitle());
  547. productInfo.setUnit(item.getUnit());
  548. productInfo.setCmpCode(item.getCmpCode());
  549. products.add(productInfo);
  550. for (PublicInquiryItem item1 : inquiry.getInquiryItems()) {
  551. if (item1.getCmpCode() != null && item1.getCmpCode().equals(productInfo.getCmpCode())) {
  552. String sql = "select at_path,at_name from attachs a left join public$inquiryitems$attach p on a.at_id = p.at_id " +
  553. "left join public$inquiryitems i on p.id_id = i.id_id where i.id_id = " + item1.getId();
  554. List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql);
  555. if (!org.springframework.util.CollectionUtils.isEmpty(maps)) {
  556. Map<String, Object> map = maps.get(0);
  557. item1.setAttachUrl(map.get("at_path").toString());
  558. item1.setAttachName(map.get("at_name").toString());
  559. }
  560. items.add(item1);
  561. }
  562. }
  563. productInfo.setInquiryItems(items);
  564. inquiryInfo.setProducts(products);
  565. }
  566. }
  567. }
  568. if (!CollectionUtils.isEmpty(ids)) {
  569. for (Long idInfo : ids) {
  570. InquiryProductInfo productInfo = new InquiryProductInfo();
  571. Set<PublicInquiryItem> items = new HashSet<PublicInquiryItem>();
  572. Product product = productDao.findOne(idInfo);
  573. productInfo.setBrand(product.getBrand());
  574. productInfo.setId(product.getId());
  575. productInfo.setSpec(product.getSpec());
  576. productInfo.setCode(product.getCode());
  577. productInfo.setTitle(product.getTitle());
  578. productInfo.setUnit(product.getUnit());
  579. productInfo.setCmpCode(product.getCmpCode());
  580. for (PublicInquiryItem item : inquiry.getInquiryItems()) {
  581. if (item.getProductId().equals(idInfo)) {
  582. String sql = "select at_path,at_name from attachs a left join public$inquiryitems$attach p on a.at_id = p.at_id " +
  583. "left join public$inquiryitems i on p.id_id = i.id_id where i.id_id = " + item.getId();
  584. List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql);
  585. if (!org.springframework.util.CollectionUtils.isEmpty(maps)) {
  586. Map<String, Object> map = maps.get(0);
  587. item.setAttachUrl(map.get("at_path").toString());
  588. item.setAttachName(map.get("at_name").toString());
  589. }
  590. items.add(item);
  591. }
  592. }
  593. productInfo.setInquiryItems(items);
  594. products.add(productInfo);
  595. inquiryInfo.setProducts(products);
  596. }
  597. }
  598. }
  599. return inquiryInfo;
  600. }
  601. /**
  602. * 通过企业UU和分页信息等查询已发布信息
  603. *
  604. * @param info 分页信息
  605. * @param filter 过滤条件
  606. * @return
  607. */
  608. @Override
  609. public Page<PurcInquiry> findByPageInfo(final PageInfo info, SearchFilter filter) {
  610. if (info.getOffset() == 0) {
  611. info.setOffset(info.getPageSize() * (info.getPageNumber() - 1));
  612. }
  613. Sort sort = new Sort(Sort.Direction.DESC, "date");
  614. if (info.getPageNumber() == 0) {
  615. info.setPageNumber(1);
  616. }
  617. if (info.getPageSize() == 0) {
  618. info.setPageSize(5);
  619. }
  620. info.setSort(sort);
  621. if (null != filter.getUserUU()) {
  622. info.filter("recorderUU", filter.getUserUU());
  623. } else if (null != filter.getEnUU()) {
  624. info.filter("enUU", filter.getEnUU());
  625. } else {
  626. throw new IllegalAccessError("非法访问");
  627. }
  628. if (null != filter) {
  629. if (!StringUtils.isEmpty(filter.getKeyword())) {
  630. SimpleExpression code = new SimpleExpression("remark", filter.getKeyword(), CriterionExpression.Operator.LIKE);
  631. SimpleExpression[] simpleExpressions = new SimpleExpression[]{code};
  632. LogicalExpression logicalExpression = PredicateUtils.or(simpleExpressions);
  633. info.expression(logicalExpression);
  634. }
  635. if (filter.getFromDate() != null) {
  636. info.expression(PredicateUtils.gte("date", new Date(filter.getFromDate()), false));
  637. }
  638. if (filter.getEndDate() != null) {
  639. info.expression(PredicateUtils.lte("date", new Date(filter.getEndDate()), false));
  640. }
  641. }
  642. SimpleExpression amount = new SimpleExpression("amount", Constant.YES, CriterionExpression.Operator.GT);
  643. SimpleExpression[] simpleExpressions = new SimpleExpression[]{amount};
  644. LogicalExpression logicalExpression = PredicateUtils.and(simpleExpressions);
  645. info.expression(logicalExpression);
  646. return purcInquiryDao.findAll(new Specification<PurcInquiry>() {
  647. @Override
  648. public Predicate toPredicate(Root<PurcInquiry> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
  649. query.where(info.getPredicates(root, query, builder));
  650. return null;
  651. }
  652. }, info);
  653. }
  654. /**
  655. * 针对客户,查询单个物料的报价情况
  656. *
  657. * @param id 明细id
  658. * @param enuu 当前企业UU
  659. * @return
  660. */
  661. @Override
  662. public InquiryProductInfo findInquiryDetailById(Long id, Long enuu) {
  663. List<PublicInquiryItem> items = itemDao.findBySourceId(id);
  664. InquiryProductInfo productInfo = new InquiryProductInfo();
  665. if (!CollectionUtils.isEmpty(items)) {
  666. Long prId = items.get(0).getProductId();
  667. if (null != prId) {
  668. Product product = productDao.findOne(prId);
  669. productInfo.setBrand(product.getBrand());
  670. productInfo.setCode(product.getCode());
  671. productInfo.setTitle(product.getTitle());
  672. productInfo.setSpec(product.getSpec());
  673. productInfo.setUnit(product.getUnit());
  674. productInfo.setCmpCode(product.getCmpCode());
  675. } else {
  676. productInfo.setCmpCode(items.get(0).getCmpCode());
  677. productInfo.setBrand(items.get(0).getInbrand());
  678. }
  679. productInfo.setInquiryItems(new HashSet<PublicInquiryItem>(items));
  680. }
  681. return productInfo;
  682. }
  683. /**
  684. * 针对客户查询供应商报价信息
  685. *
  686. * @param pageInfo 分页信息
  687. * @param filter 过滤条件
  688. * @return
  689. */
  690. @Override
  691. public Page<PurcInquiryItemInfo> findQuotationsByPage(final PageInfo pageInfo, final SearchFilter filter, Long enUU, Long userUU, Short overdue) {
  692. if (enUU == null && userUU == null) {
  693. throw new IllegalAccessError("非法访问");
  694. }
  695. Sort sort = new Sort(Sort.Direction.DESC, "date");
  696. if (pageInfo.getOffset() == 0) {
  697. pageInfo.setOffset(pageInfo.getPageSize() * (pageInfo.getPageNumber() - 1));
  698. }
  699. pageInfo.setSort(sort);
  700. if (enUU != null) {
  701. pageInfo.filter("inquiry.enUU", enUU);
  702. } else {
  703. if (userUU != null) {
  704. pageInfo.filter("inquiry.recorderUU", userUU);
  705. pageInfo.expression(PredicateUtils.isNull("inquiry.enUU"));
  706. }
  707. }
  708. if (StringUtils.hasText(filter.getKeyword())) {
  709. SimpleExpression cmpCode = new SimpleExpression("cmpCode", filter.getKeyword(), CriterionExpression.Operator.LIKE);
  710. SimpleExpression inbrand = new SimpleExpression("inbrand", filter.getKeyword(), CriterionExpression.Operator.LIKE);
  711. SimpleExpression[] simpleExpressions = new SimpleExpression[]{inbrand, cmpCode};
  712. LogicalExpression logicalExpression = PredicateUtils.or(simpleExpressions);
  713. pageInfo.expression(logicalExpression);
  714. }
  715. if (filter.getFromDate() != null) {
  716. pageInfo.expression(PredicateUtils.gte("date", new Date(filter.getFromDate()), false));
  717. }
  718. if (filter.getEndDate() != null) {
  719. pageInfo.expression(PredicateUtils.lte("date", new Date(filter.getEndDate()), false));
  720. }
  721. if (null != overdue) {
  722. // 已超过截止日期
  723. if (overdue.equals(Constant.YES)) {
  724. pageInfo.expression(PredicateUtils.lt("endDate", new Date(System.currentTimeMillis()), false));
  725. } else if (overdue.equals(Constant.NO)) {
  726. pageInfo.expression(PredicateUtils.gte("endDate", new Date(System.currentTimeMillis()), false));
  727. }
  728. }
  729. pageInfo.expression(PredicateUtils.gt("offerAmount", Constant.NO, false));
  730. Page<PurcInquiryItemInfo> items = inquiryItemDao.findAll(new Specification<PurcInquiryItemInfo>() {
  731. @Override
  732. public Predicate toPredicate(Root<PurcInquiryItemInfo> root, CriteriaQuery<?> query, CriteriaBuilder builder) {
  733. query.where(pageInfo.getPredicates(root, query, builder));
  734. return null;
  735. }
  736. }, pageInfo);
  737. if (!CollectionUtils.isEmpty(items.getContent())) {
  738. for (PurcInquiryItemInfo itemInfo : items.getContent()) {
  739. List<PublicInquiryItem> itemList = itemDao.findBySourceIdOrderByOfferTimeDesc(itemInfo.getId());
  740. itemInfo.setQutations(itemList);
  741. itemInfo.setQuotation(itemList.get(0));
  742. itemInfo.setAgreed(Constant.NO);
  743. if (!CollectionUtils.isEmpty(itemList)) {
  744. for (PublicInquiryItem i : itemList) {
  745. if (i.getAgreed() != null && i.getAgreed().equals(Constant.YES)) {
  746. itemInfo.setAgreed(Constant.YES);
  747. break;
  748. }
  749. }
  750. }
  751. if (null != itemInfo.getInquiry().getEndDate()) {
  752. itemInfo.setRemainingTime(itemInfo.getInquiry().getEndDate().getTime() - System.currentTimeMillis());
  753. }
  754. if (null == itemInfo.getProductId()) {
  755. Product product = new Product();
  756. product.setTitle(itemInfo.getProdTitle());
  757. product.setCmpCode(itemInfo.getCmpCode());
  758. product.setBrand(itemInfo.getInbrand());
  759. product.setSpec(itemInfo.getSpec());
  760. itemInfo.setProduct(product);
  761. }
  762. }
  763. }
  764. return items;
  765. }
  766. /**
  767. * 针对客户单个公共询价,查询供应商报价信息
  768. *
  769. * @param id
  770. * @return
  771. */
  772. @Override
  773. public PurcInquiryItemInfo findQuotationById(Long id) {
  774. PurcInquiryItemInfo itemInfo = inquiryItemDao.findOne(id);
  775. List<PublicInquiryItem> itemList = itemDao.findBySourceId(itemInfo.getId());
  776. itemInfo.setQutations(itemList);
  777. itemInfo.setAgreed(Constant.NO);
  778. if (!CollectionUtils.isEmpty(itemList)) {
  779. for (PublicInquiryItem i : itemList) {
  780. if (i.getAgreed() != null && i.getAgreed().equals(Constant.YES)) {
  781. itemInfo.setAgreed(Constant.YES);
  782. break;
  783. }
  784. }
  785. }
  786. if (null != itemInfo.getInquiry().getEndDate()) {
  787. itemInfo.setRemainingTime(itemInfo.getInquiry().getEndDate().getTime() - System.currentTimeMillis());
  788. }
  789. if (null == itemInfo.getProductId()) {
  790. Product product = new Product();
  791. product.setTitle(itemInfo.getProdTitle());
  792. product.setCmpCode(itemInfo.getCmpCode());
  793. product.setBrand(itemInfo.getInbrand());
  794. product.setSpec(itemInfo.getSpec());
  795. itemInfo.setProduct(product);
  796. }
  797. return itemInfo;
  798. }
  799. /**
  800. * 发送消息推送
  801. *
  802. */
  803. public void sendMessage(final Integer count, final List<InquiryRemind> reminds) {
  804. ThreadUtils.task(new Runnable() {
  805. @Override
  806. public void run() {
  807. try {
  808. List<MessageModel> models = new ArrayList<>();
  809. MessageModel model = new MessageModel();
  810. model.setType(INQUIRY_TYPE);
  811. model.setType(INQUIRY_TYPE_SELLER_MALL);
  812. model.setProducerApp("MALl");
  813. model.setConsumerType(CUST_TYPE);
  814. model.setConsumerApp(CONSUMERAPP_HIDE);
  815. model.setRemark(String.valueOf(count));
  816. for(InquiryRemind remind : reminds){
  817. model.setReceiverEnuu(remind.getVendUU());
  818. model.setReceiverUu(remind.getVendUserUU());
  819. model.setSenderEnuu(MESSAGE_SENDERENUU);
  820. model.setSenderUu(MESSAGE_SENDERUU);
  821. }
  822. String company = "";
  823. Enterprise enterprise = enterpriseDao.findOne(reminds.get(0).getVendUU());
  824. if(null != enterprise){
  825. company = enterprise.getEnName();
  826. }
  827. String content = company + "新增了"+ count +"张公共询价单,快登录优软商城查看详情吧!https://www.usoftmall.com/vendor#/seekPurchase";
  828. model.setContent(content);
  829. model.setSmsType(SMS_TYPE);
  830. model.setSmTemplate(SMS_TEMP_ID);
  831. models.add(model);
  832. long start = System.currentTimeMillis();
  833. String res = HttpUtil.doPost(PS_MESSAGE_URL + "/messages", FlexJsonUtils.toJsonDeep(models));
  834. log.info("/message 耗时:" + (System.currentTimeMillis() - start) + "消息数:" + models.size());
  835. System.out.println(FlexJsonUtils.toJsonDeep(models));
  836. System.out.println(res);
  837. log.info("公共询价", "此次"+company+"公司新增"+count+"张公共询价");
  838. } catch (Exception e) {
  839. e.printStackTrace();
  840. }
  841. }
  842. }).run();
  843. }
  844. /**
  845. * 发送消息推送 (定时任务使用)
  846. *
  847. */
  848. @Override
  849. public void sendMessage(final List<InquiryRemind> reminds) {
  850. ThreadUtils.task(new Runnable() {
  851. @Override
  852. public void run() {
  853. try {
  854. log.info("发送消息开始");
  855. List<MessageModel> models = new ArrayList<>();
  856. for (InquiryRemind remind : reminds) {
  857. if (null != remind.getVendUU() && null != remind.getVendUserUU()) {
  858. Integer count = remind.getCounts();
  859. MessageModel model = new MessageModel();
  860. model.setType(INQUIRY_TYPE);
  861. model.setType(INQUIRY_TYPE_SELLER_MALL);
  862. model.setProducerApp(SOURCEAPP_MALL);
  863. model.setConsumerType(CUST_TYPE);
  864. model.setConsumerApp(CONSUMERAPP_HIDE);
  865. model.setRemark(String.valueOf(count));
  866. model.setReceiverEnuu(remind.getVendUU());
  867. model.setReceiverUu(remind.getVendUserUU());
  868. model.setSenderEnuu(MESSAGE_SENDERENUU);
  869. model.setSenderUu(MESSAGE_SENDERUU);
  870. String company = "";
  871. Enterprise enterprise = enterpriseDao.findOne(remind.getVendUU());
  872. if(null != enterprise){
  873. company = enterprise.getEnName();
  874. }
  875. String content = company + "新增了"+ count +"张公共询价单,快登录优软商城查看详情吧!https://www.usoftmall.com/vendor#/seekPurchase";
  876. model.setContent(content);
  877. model.setSmsType(SMS_TYPE);
  878. model.setSmTemplate(SMS_TEMP_ID);
  879. models.add(model);
  880. log.info("此次" + company + "公司新增" + remind.getCounts() + "张公共询价(发送信息前),接收人UU:" + model.getReceiverUu());
  881. }
  882. if (models.size() >= 500) {
  883. long start = System.currentTimeMillis();
  884. String res = HttpUtil.doPost(PS_MESSAGE_URL + "/messages", FlexJsonUtils.toJsonDeep(models));
  885. log.info("消息中心生成消息接口返回日志" + res);
  886. log.info("发送消息" + models.size() + ",耗时:" + (System.currentTimeMillis() - start));
  887. models = new ArrayList<>();
  888. }
  889. }
  890. if (!CollectionUtils.isEmpty(models)) {
  891. long start = System.currentTimeMillis();
  892. String res = HttpUtil.doPost(PS_MESSAGE_URL + "/messages", FlexJsonUtils.toJsonDeep(models));
  893. log.info("消息中心生成消息接口返回日志" + res);
  894. log.info("发送消息" + models.size() + ",耗时:" + (System.currentTimeMillis() - start));
  895. }
  896. log.info("发送消息全部完成");
  897. } catch (Exception e) {
  898. e.printStackTrace();
  899. }
  900. }
  901. }).run();
  902. }
  903. /**
  904. * 以供应商企业UU和用户UU分组查询商机
  905. * @param hours 查之前多少小时内的单据
  906. * @return 商机List
  907. */
  908. @Override
  909. public List<InquiryRemind> findInquiryRemindGroupByVendUUAndVendUserUU(int hours) {
  910. String sql = "select ir_venduu vendUU,ir_venduseruu vendUserUU, count(1) counts from purc$inquiry$remind where ir_date between date_sub(now(), interval "
  911. + hours + " hour) and now() group by ir_venduu,ir_venduseruu";
  912. return jdbcTemplate.query(sql, new BeanPropertyRowMapper<InquiryRemind>(InquiryRemind.class));
  913. }
  914. /**
  915. * 讲报价产品数设置进page
  916. *
  917. * @param page 询价单page
  918. * @return 询价单pege
  919. */
  920. @Override
  921. public Page<PurcInquiry> setQuotedAmount(Page<PurcInquiry> page) {
  922. for (PurcInquiry inquiry : page.getContent()) {
  923. List<Long> itemIds = new ArrayList<>();
  924. Long[] itemIdArray = new Long[inquiry.getInquiryItems().size()];
  925. for (PurcInquiryItem item : inquiry.getInquiryItems()) {
  926. itemIds.add(item.getId());
  927. }
  928. Integer size = itemDao.getQuotedAmountBySourceId(itemIds.toArray(itemIdArray));
  929. inquiry.setQuotedAmount(size);
  930. }
  931. return page;
  932. }
  933. }