ApiOrderValuationServiceImpl.java 40 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722
  1. package com.ydd.app.service.impl;
  2. import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
  3. import com.ydd.api.DeliveryService;
  4. import com.ydd.app.OrderEntityUtils;
  5. import com.ydd.app.QueryAmountEntityUtils;
  6. import com.ydd.app.dto.AddressReq;
  7. import com.ydd.app.dto.OrderReq;
  8. import com.ydd.app.dto.ValuationRes;
  9. import com.ydd.app.dto.ValuationResultData;
  10. import com.ydd.app.service.ApiDadaValuationService;
  11. import com.ydd.app.service.ApiOrderValuationService;
  12. import com.ydd.app.service.ApiProductService;
  13. import com.ydd.common.constant.BillingConstant;
  14. import com.ydd.common.enums.DeliveryTypeEnums;
  15. import com.ydd.common.utils.DateUtils;
  16. import com.ydd.common.utils.SnCodeUtils;
  17. import com.ydd.common.utils.StringUtils;
  18. import com.ydd.ecloud.core.utils.BigDecimalUtils;
  19. import com.ydd.ecloud.core.utils.JsonMapper;
  20. import com.ydd.module.domain.*;
  21. import com.ydd.module.dto.*;
  22. import com.ydd.module.enums.*;
  23. import com.ydd.module.expection.CustomAppException;
  24. import com.ydd.module.service.*;
  25. import com.ydd.module.utils.CommonUtils;
  26. import com.ydd.system.domain.SysConfig;
  27. import com.ydd.system.service.ISysConfigService;
  28. import com.ydd.third.common.config.DeliveryConfig;
  29. import com.ydd.third.common.utils.CoordinateUtils;
  30. import com.ydd.third.common.vo.ResObject;
  31. import com.ydd.third.common.vo.shop.AmountResultVo;
  32. import com.ydd.third.common.vo.shop.QueryAmount;
  33. import com.ydd.third.common.vo.vo.order.OrderResultVo;
  34. import com.ydd.third.common.vo.vo.order.OrderVo;
  35. import lombok.RequiredArgsConstructor;
  36. import lombok.extern.slf4j.Slf4j;
  37. import org.apache.commons.collections4.CollectionUtils;
  38. import org.apache.commons.compress.utils.Lists;
  39. import org.springframework.beans.factory.annotation.Autowired;
  40. import org.springframework.stereotype.Service;
  41. import java.math.BigDecimal;
  42. import java.util.*;
  43. import java.util.stream.Collectors;
  44. /**
  45. * @author 叶君翔
  46. * @date 2021/11/12 11:20
  47. */
  48. @Slf4j
  49. @Service
  50. @RequiredArgsConstructor(onConstructor_ = @Autowired)
  51. public class ApiOrderValuationServiceImpl implements ApiOrderValuationService {
  52. private final ApiProductService apiProductService;
  53. private final IOrderService iOrderService;
  54. private final IMemberService iMemberService;
  55. private final IMerchantService iMerchantService;
  56. private final IDadaDspService iDadaDspService;
  57. private final DeliveryService client;
  58. private final IDspDeliveryService iDspDeliveryService;
  59. private final IWaimaiOrderDetailService iWaimaiOrderDetailService;
  60. private final IWaimaiOrderService iWaimaiOrderService;
  61. private final IDspWaimaiService iDspWaimaiService;
  62. private final DeliveryConfig deliveryConfig;
  63. private final IMemberConfigService iMemberConfigService;
  64. private final ISysConfigService iSysConfigService;
  65. private final IShopDeliveryService iShopDeliveryService;
  66. private final IShopDeliveryBindService iShopDeliveryBindService;
  67. private final IShopService iShopService;
  68. private final IShopWaimaiService iShopWaimaiService;
  69. private final IPackageDiscountDetailService iPackageDiscountDetailService;
  70. private final IPackageCommissionDetailService iPackageCommissionDetailService;
  71. private final IPackageDeliveryService iPackageDeliveryService;
  72. private final IPackageCityConfigService iPackageCityConfigService;
  73. private final ApiDadaValuationService dadaValuationService;
  74. @Override
  75. public ValuationResultData orderValuation(Member member, OrderReq orderReq, Integer type) {
  76. log.info("<===========>订单计价参数: loginId:{}, type: {}, orderReq: {} ", member.getId(), type, JsonMapper.nonEmptyMapper().toJson(orderReq));
  77. try {
  78. Member loginMember = member;
  79. if (member.getMemberType().equals(MemberTypeEnum.SHOP.type)) {
  80. member = iMemberService.getOne(new QueryWrapper<Member>().eq("member_type", MemberTypeEnum.MERCHANT.type).eq("merchant_id", member.getMerchantId()));
  81. }
  82. AddressReq sendAddress = orderReq.getSendAddress();
  83. AddressReq receiveAddress = orderReq.getReceiptAddress();
  84. if (sendAddress == null || receiveAddress == null) {
  85. throw new CustomAppException(ExceptionEnum.ADDRESS_NOT_EXISTS);
  86. }
  87. Product product = apiProductService.findById(orderReq.getProductId());
  88. if (product == null) {
  89. throw new CustomAppException(ExceptionEnum.PRODUCT_NOT_EXISTS);
  90. }
  91. Long shopId = orderReq.getShopId();
  92. // 计价类型 0-普通计价 1-达达收付配送商计价 2-达达非收付配送商计价
  93. int valuationType = 0;
  94. Long dadaDspId = null;
  95. if (member.getMerchantId() != null) {
  96. Merchant merchant = iMerchantService.getById(member.getMerchantId());
  97. if (merchant != null && merchant.getDadaDspId() != null) {
  98. DadaDsp dadaDsp = iDadaDspService.getById(merchant.getDadaDspId());
  99. if (dadaDsp != null) {
  100. dadaDspId = dadaDsp.getId();
  101. if (DadaDspRoleEnum.SELF_DELIVERY.type.equals(dadaDsp.getDspRole())) {
  102. valuationType = 2;
  103. } else {
  104. valuationType = 1;
  105. }
  106. }
  107. }
  108. }
  109. orderReq.setOrderNo(SnCodeUtils.createSn());
  110. String takeRemark = "";
  111. if (orderReq.getOrderId() != null) {
  112. orderReq.setShopId(null);
  113. Order order = iOrderService.getById(orderReq.getOrderId());
  114. orderReq.setWaimaiOrderId(order.getWaimaiOrderId());
  115. if (order.getDeliveryStatus() >= DeliveryStatusEnum.ORDERS_TO_BE_RECEIVED.status && !DeliveryStatusEnum.FINISH.status.equals(order.getDeliveryStatus())) {
  116. log.info("该配送状态的订单不支持计价操作, orderId: {}, deliveryStatus: {}", order.getId(), order.getDeliveryStatus());
  117. return null;
  118. }
  119. // 非再来一单
  120. if (!DeliveryStatusEnum.CANCEL.status.equals(order.getDeliveryStatus())
  121. && !DeliveryStatusEnum.FINISH.status.equals(order.getDeliveryStatus())
  122. && !DeliveryStatusEnum.ABNORMAL.status.equals(order.getDeliveryStatus())) {
  123. orderReq.setOrderNo(order.getOrderSn());
  124. }
  125. shopId = order.getShopId();
  126. takeRemark = order.getTakeRemark();
  127. }
  128. // 0-门店发单 1-非门店发单 在商户所属门店附近100米使用个人地址发单,也按照门店发单处理
  129. int defaultShop = 0;
  130. if (loginMember.getShopId() != null && orderReq.getShopId() == null) {
  131. List<Shop> shops = Lists.newArrayList();
  132. if (member.getMemberType().equals(MemberTypeEnum.SHOP.type)) {
  133. Shop shop = iShopService.getById(loginMember.getShopId());
  134. shops.add(shop);
  135. } else {
  136. shops = iShopService.list(new QueryWrapper<Shop>()
  137. .eq("merchant_id", loginMember.getMerchantId())
  138. .eq("deleted", 0)
  139. .eq("status", 1));
  140. }
  141. int num = 0;
  142. for (Shop shop : shops) {
  143. double distance = CoordinateUtils.getDistance(Double.parseDouble(sendAddress.getLng()), Double.parseDouble(sendAddress.getLat()), Double.parseDouble(shop.getLng()), Double.parseDouble(shop.getLat()));
  144. if (distance > BillingConstant.SHOP_BILLING_DISTANCE) { //暂定小于一百米 是门店发单
  145. num ++;
  146. } else {
  147. // 个人发单,发件地址附近100米内的门店作为发单门店
  148. shopId = shop.getId();
  149. }
  150. }
  151. if (num == shops.size()) {
  152. defaultShop = 1;
  153. }
  154. }
  155. if (StringUtils.isNotBlank(orderReq.getTakeTime()) && DateUtils.addHours(new Date(), 2).compareTo(DateUtils.dateTime(DateUtils.YYYY_MM_DD_HH_MM_SS, orderReq.getTakeTime())) > 0) {
  156. orderReq.setTakeTime("");
  157. orderReq.setTakeType(0);
  158. }
  159. List<WaimaiOrderDetail> waiMaiOrderDetails = new ArrayList<>();
  160. orderReq.setWaimaiOrderDetails(waiMaiOrderDetails);
  161. if (orderReq.getWaimaiOrderId() != null) {
  162. // 设置外卖单相关信息
  163. shopId = this.setWaimaiOrderInfo(orderReq, takeRemark, shopId);
  164. } else {
  165. // 普通单设置订单来源以及流水号
  166. this.setOrderSource(orderReq);
  167. }
  168. orderReq.setProduct(product);
  169. ValuationRes res;
  170. if (valuationType == 0) {
  171. res = this.normalValuation(shopId, loginMember, member, defaultShop, orderReq, type);
  172. return ValuationResultData.success(res);
  173. } else {
  174. return dadaValuationService.dadaValuation(shopId, loginMember, member, orderReq, valuationType, dadaDspId);
  175. }
  176. } catch (Exception e) {
  177. log.error("发起计价异常", e);
  178. return null;
  179. }
  180. }
  181. private void setOrderSource(OrderReq orderReq) {
  182. Integer platformType = orderReq.getPlatformType();
  183. if (platformType != null && platformType > 0) {
  184. orderReq.setPoiSeq(orderReq.getDaySeq());
  185. // 美团、美团闪购
  186. if (platformType == 1 || platformType == 5) {
  187. orderReq.setOrderSource("101");
  188. } else if (platformType == 2) {
  189. // 饿了么
  190. orderReq.setOrderSource("102");
  191. } else if (platformType == 3) {
  192. // 饿百零售
  193. orderReq.setOrderSource("103");
  194. }else if (platformType == 6) {
  195. // 京东到家
  196. orderReq.setOrderSource("104");
  197. }
  198. }
  199. }
  200. // 普通计价模式
  201. private ValuationRes normalValuation(Long shopId, Member loginMember, Member member, Integer defaultShop, OrderReq orderReq, Integer type) {
  202. ValuationRes res = new ValuationRes();
  203. List<ValuationRes> list = new ArrayList<>();
  204. List<ValuationRes> supports = new ArrayList<>();
  205. // 门店用户使用首页个人发单, 则使用用户默认的shopId进行包查询
  206. Long packageShopId = shopId == null ? loginMember.getShopId() : shopId;
  207. // 获取最匹配的运力包(门店 > 城市 > 全国)
  208. Long deliveryPackageId = iPackageCityConfigService.getPackageId(packageShopId, loginMember, orderReq.getSendAddress().getCityCode(), PackageCityConfigPackageTypeEnum.DELIVERY.type);
  209. List<Integer> types = Lists.newArrayList();
  210. PackageDeliveryDto packageDeliveryDto = null;
  211. if (deliveryPackageId != null) {
  212. packageDeliveryDto = iPackageDeliveryService.getDeliveryDtoByPackageIdAndDeliveryType(deliveryPackageId);
  213. List<PackageDeliveryDetailDto> deliveryDetailDtoList = packageDeliveryDto.getPackageDeliveryDetailDtoList();
  214. if (CollectionUtils.isNotEmpty(deliveryDetailDtoList)) {
  215. types = deliveryDetailDtoList.stream().map(PackageDeliveryDetailDto::getDeliveryType).collect(Collectors.toList());
  216. }
  217. }
  218. List<DeliveryInfo> deliveryInfos = iDspDeliveryService.findList(loginMember, shopId, orderReq.getTransport(), types, defaultShop);
  219. if (CollectionUtils.isEmpty(deliveryInfos)) {
  220. log.warn("无可用发单运力!");
  221. return res;
  222. }
  223. if (shopId != null) {
  224. Shop shop = iShopService.getById(shopId);
  225. orderReq.setShopName(shop.getName());
  226. }
  227. List<Integer> deliveryTypes = deliveryInfos.stream().map(DspDelivery::getType).collect(Collectors.toList());
  228. // 获取最匹配的优惠包(门店 > 代理商 > 全国)
  229. Long discountPackageId = iPackageCityConfigService.getPackageId(packageShopId, loginMember, orderReq.getSendAddress().getCityCode(), PackageCityConfigPackageTypeEnum.DISCOUNT.type);
  230. Map<Integer, List<PackageDiscountDetailDto>> packageDiscountMap = new HashMap<>();
  231. if (discountPackageId != null) {
  232. List<PackageDiscountDetailDto> discountDetailDtoList = iPackageDiscountDetailService.getDiscountListByPackageIdAndDeliveryType(discountPackageId, deliveryTypes);
  233. packageDiscountMap = discountDetailDtoList.stream().collect(Collectors.groupingBy(PackageDiscountDetailDto::getDeliveryType));
  234. }
  235. // 获取最匹配的佣金包(门店 > 代理商 > 全国)
  236. Long commissionPackageId = iPackageCityConfigService.getPackageId(packageShopId, loginMember, orderReq.getSendAddress().getCityCode(), PackageCityConfigPackageTypeEnum.COMMISSION.type);
  237. Map<Integer, List<PackageCommissionDetailDto>> packageCommissionMap = new HashMap<>();
  238. if (commissionPackageId != null) {
  239. List<PackageCommissionDetailDto> commissionDetailDtoList = iPackageCommissionDetailService.getCommissionListByPackageIdAndDeliveryType(commissionPackageId, deliveryTypes);
  240. packageCommissionMap = commissionDetailDtoList.stream().collect(Collectors.groupingBy(PackageCommissionDetailDto::getDeliveryType));
  241. }
  242. // type = 2为自动配送, 等APP改版后可以拿掉
  243. if (type == 2 && orderReq.getPreDeliveryIds()!=null) {
  244. List<String> deliveryIds = Arrays.asList(orderReq.getPreDeliveryIds().split(","));
  245. deliveryInfos = deliveryInfos.stream().filter(a -> deliveryIds.contains(a.getId().toString())).collect(Collectors.toList());
  246. log.info("<===========>计价运力" + JsonMapper.nonEmptyMapper().toJson(deliveryInfos));
  247. }
  248. log.info("运力包: {}, 优惠包:{}, 佣金包: {}", deliveryPackageId, discountPackageId, commissionPackageId);
  249. for (DeliveryInfo info : deliveryInfos) {
  250. // 计价
  251. ValuationRes valuationRes = this.queryOrderDeliverFee(orderReq, info, member.getMerchantId(), shopId, defaultShop);
  252. if (valuationRes == null) {
  253. continue;
  254. }
  255. valuationRes.setPreferredDelivery(info.getPreferredDelivery());
  256. valuationRes.setOriginalMoney(valuationRes.getDeliveryAmount());
  257. // 设置排序
  258. if (packageDeliveryDto != null && PackageDeliveryTypeEnum.CUSTOM.type.equals(packageDeliveryDto.getType())) {
  259. this.setBillingSort(packageDeliveryDto, valuationRes);
  260. }
  261. // 设置优惠
  262. if (packageDiscountMap.size() > 0) {
  263. this.setDiscountInfo(packageDiscountMap.get(info.getType()), valuationRes);
  264. }
  265. // 设置佣金
  266. if (packageCommissionMap.size() > 0) {
  267. this.setCommissionInfo(packageCommissionMap.get(info.getType()), valuationRes);
  268. }
  269. valuationRes.setIsMerchant(info.getIsMerchant());
  270. if (valuationRes.getIsMine() == 0) {
  271. // 校验余额是否充足
  272. if (member.getAmount().compareTo(valuationRes.getDeliveryAmount()) >= 0) {
  273. valuationRes.setIsEnough(StatusEnum.SHOW.status);
  274. }
  275. }
  276. list.add(valuationRes);
  277. }
  278. // 默认价格优先
  279. list.sort(Comparator.comparing(ValuationRes::getDeliveryAmount));
  280. // Res数据组装
  281. this.setValuationRes(list, res, loginMember, orderReq.getTransport());
  282. // 运力包发单类型为自定义, 则先按照sort排,再按价格排
  283. if (packageDeliveryDto != null && PackageDeliveryTypeEnum.CUSTOM.type.equals(packageDeliveryDto.getType())) {
  284. Collections.sort(list);
  285. }
  286. // 处理发单运力
  287. List<ValuationRes> billList = this.handleBillList(loginMember.getId(), list);
  288. // 设置发单时长
  289. if (packageDeliveryDto != null) {
  290. billList = this.setBillingDuration(packageDeliveryDto, billList);
  291. }
  292. res.setOptionals(billList);
  293. res.setSupports(supports);
  294. return res;
  295. }
  296. private List<ValuationRes> handleBillList(Long loginId, List<ValuationRes> list) {
  297. // 查询下单设置推荐屏蔽运力
  298. List<ValuationRes> billList = new ArrayList<>();
  299. MemberConfig config = iMemberConfigService.getOne(new QueryWrapper<MemberConfig>().eq("member_id",loginId));
  300. if (config != null) {
  301. if (StringUtils.isNotEmpty(config.getBillDeliveryIds())) {
  302. List<String> billDeliveryIds = Arrays.asList(config.getBillDeliveryIds().split(","));
  303. // 过滤出商家设置的推荐运力, 计价页面靠前显示
  304. billList = list.stream().filter(a -> billDeliveryIds.contains(a.getDeliveryId().toString())).collect(Collectors.toList());
  305. }
  306. if (StringUtils.isNotEmpty(config.getShieldDeliveryIds())) {
  307. List<String> shieldDeliveryIds = Arrays.asList(config.getShieldDeliveryIds().split(","));
  308. // 过滤掉商家设置的屏蔽运力
  309. list = list.stream().filter(a -> !shieldDeliveryIds.contains(a.getDeliveryId().toString())).collect(Collectors.toList());
  310. }
  311. }
  312. list.removeAll(billList);
  313. billList.addAll(list);
  314. // 闪送距离替换
  315. Optional<ValuationRes> optional = billList.stream().filter(item -> !item.getDeliveryType().equals(DeliveryTypeEnums.SHAN_SONG.getType())).findFirst();
  316. if (optional.isPresent()) {
  317. String desc = optional.get().getDesc();
  318. for (ValuationRes res1 : billList) {
  319. if (DeliveryTypeEnums.SHAN_SONG.getType().equals(res1.getDeliveryType())) {
  320. res1.setDesc(desc);
  321. break;
  322. }
  323. }
  324. }
  325. return billList;
  326. }
  327. private void setValuationRes(List<ValuationRes> list, ValuationRes res, Member loginMember, Integer transport) {
  328. // 获取聚合配送的预估价,选最低价格展示
  329. if (CollectionUtils.isNotEmpty(list)) {
  330. res.setDeliveryId(list.get(0).getDeliveryId());
  331. res.setDesc("全网运力推单");
  332. res.setDeliveryAmount(list.get(0).getDeliveryAmount());
  333. res.setName("聚合配送");
  334. res.setIsEnough(list.get(0).getIsEnough());
  335. res.setLogo("https://ecloud-cdn.51sssd.com/20210317/e24a425797f54f64b808b95beae37285.png");
  336. }
  337. // 新用户只要没有产生支付成功的订单数据 算首单 取消新人首单立减
  338. // int successOrderCount;
  339. // if (loginMember.getShopId() != null) {
  340. // successOrderCount = iOrderService.count(new QueryWrapper<Order>().eq("shop_id", loginMember.getShopId()).eq("status", PayStatusEnum.PAYED.status));
  341. // } else {
  342. // successOrderCount = iOrderService.count(new QueryWrapper<Order>().eq("member_id", loginMember.getId()).eq("status", PayStatusEnum.PAYED.status));
  343. // }
  344. // if (successOrderCount == 0 && transport == 0) {
  345. // String configValue = iSysConfigService.selectConfigByKey("NEW_COMERS");
  346. // res.setFirstCoupon(configValue);
  347. // }
  348. }
  349. private void setBillingSort(PackageDeliveryDto packageDeliveryDto, ValuationRes valuationRes) {
  350. List<PackageDeliveryDetailDto> deliveryDetailDtoList = packageDeliveryDto.getPackageDeliveryDetailDtoList();
  351. if (CollectionUtils.isNotEmpty(deliveryDetailDtoList)) {
  352. Optional<PackageDeliveryDetailDto> optional = deliveryDetailDtoList.stream().filter(item -> valuationRes.getDeliveryType().equals(item.getDeliveryType())).findFirst();
  353. if (optional.isPresent()) {
  354. PackageDeliveryDetailDto packageDeliveryDetailDto = optional.get();
  355. valuationRes.setSort((packageDeliveryDetailDto.getSort() == null || packageDeliveryDetailDto.getSort() == 0) ? BillingConstant.DEFAULT_BILL_SORT : packageDeliveryDetailDto.getSort());
  356. }
  357. }
  358. }
  359. private List<ValuationRes> setBillingDuration(PackageDeliveryDto packageDeliveryDto, List<ValuationRes> billList) {
  360. String billDurationStr = packageDeliveryDto.getBillDurationStr();
  361. List<PackageDeliveryDetailDto> deliveryDetailList = packageDeliveryDto.getPackageDeliveryDetailDtoList();
  362. if (StringUtils.isNotEmpty(billDurationStr) && CollectionUtils.isNotEmpty(deliveryDetailList)) {
  363. String[] split = billDurationStr.split(",");
  364. if (PackageDeliveryTypeEnum.CUSTOM.type.equals(packageDeliveryDto.getType())) {
  365. deliveryDetailList = deliveryDetailList.stream().filter(item -> item.getSort() != null && item.getSort() > 0).collect(Collectors.toList());
  366. deliveryDetailList.sort(Comparator.comparing(PackageDeliveryDetailDto::getSort));
  367. for (int i = 0; i < deliveryDetailList.size(); i++) {
  368. PackageDeliveryDetailDto packageDeliveryDetailDto = deliveryDetailList.get(i);
  369. if (i < split.length) {
  370. packageDeliveryDetailDto.setBillDuration(Integer.parseInt(split[i]));
  371. }
  372. }
  373. for (ValuationRes valuationRes : billList) {
  374. int billDuration = BillingConstant.DEFAULT_BILL_DURATION;
  375. Optional<PackageDeliveryDetailDto> optional = deliveryDetailList.stream().filter(item -> item.getDeliveryType().equals(valuationRes.getDeliveryType())).findAny();
  376. if (optional.isPresent()) {
  377. PackageDeliveryDetailDto packageDeliveryDetailDto = optional.get();
  378. billDuration = packageDeliveryDetailDto.getBillDuration();
  379. }
  380. valuationRes.setBillDuration(billDuration == 0 ? BillingConstant.DEFAULT_BILL_DURATION : billDuration);
  381. }
  382. } else {
  383. for (int i = 0; i < billList.size(); i++) {
  384. ValuationRes valuationRes = billList.get(i);
  385. int billDuration = BillingConstant.DEFAULT_BILL_DURATION;
  386. if (i < split.length) {
  387. billDuration = Integer.parseInt(split[i]);
  388. }
  389. valuationRes.setBillDuration(billDuration);
  390. }
  391. }
  392. } else {
  393. billList = billList.stream().map(valuationRes -> valuationRes.setBillDuration(BillingConstant.DEFAULT_BILL_DURATION)).collect(Collectors.toList());
  394. }
  395. return billList;
  396. }
  397. private void setCommissionInfo(List<PackageCommissionDetailDto> packageCommissionDetailDtoList, ValuationRes valuationRes) {
  398. BigDecimal commission = BigDecimal.ZERO;
  399. if (valuationRes.getIsMine() == 1 || DeliveryTypeEnums.HUO_LA_LA.getType().equals(valuationRes.getDeliveryType())) {
  400. valuationRes.setCommission(commission);
  401. return;
  402. }
  403. if (CollectionUtils.isNotEmpty(packageCommissionDetailDtoList) && packageCommissionDetailDtoList.size() > 0) {
  404. PackageCommissionDetailDto packageCommissionDetailDto = packageCommissionDetailDtoList.get(0);
  405. if (PackageCommissionTypeEnum.RATE.type.equals(packageCommissionDetailDto.getCommissionType())) {
  406. if (packageCommissionDetailDto.getValue() != null) {
  407. commission = packageCommissionDetailDto.getValue().multiply(valuationRes.getDeliveryAmount())
  408. .divide(new BigDecimal("100"), BigDecimal.ROUND_HALF_UP).setScale(6, BigDecimal.ROUND_HALF_UP);
  409. }
  410. } else if (PackageDiscountDetailTypeEnum.GRADIENT.type.equals(packageCommissionDetailDto.getCommissionType())) {
  411. for (PackageCommissionDetailDto item : packageCommissionDetailDtoList) {
  412. boolean inRange = BigDecimalUtils.inRange(item.getLeftValue(), item.getRightValue(), valuationRes.getDeliveryAmount());
  413. if (inRange) {
  414. if (item.getValue() != null) {
  415. commission = item.getValue();
  416. }
  417. break;
  418. }
  419. }
  420. }
  421. }
  422. valuationRes.setCommission(commission);
  423. valuationRes.setDeliveryAmount(commission.add(valuationRes.getDeliveryAmount()));
  424. }
  425. private void setDiscountInfo(List<PackageDiscountDetailDto> discountDetailDtoList, ValuationRes valuationRes) {
  426. if (valuationRes.getIsMine() == 1) {
  427. return;
  428. }
  429. if (CollectionUtils.isNotEmpty(discountDetailDtoList) && discountDetailDtoList.size() > 0) {
  430. PackageDiscountDetailDto discountDetailDto = discountDetailDtoList.get(0);
  431. if (PackageDiscountDetailTypeEnum.ZHE_KOU.type.equals(discountDetailDto.getType())) {
  432. if (discountDetailDto.getValue() != null) {
  433. BigDecimal discountValue = discountDetailDto.getValue().multiply(valuationRes.getDeliveryAmount())
  434. .divide(BigDecimal.TEN, BigDecimal.ROUND_HALF_UP).setScale(6, BigDecimal.ROUND_HALF_UP);
  435. double abs = Math.abs(valuationRes.getDeliveryAmount().subtract(discountValue).doubleValue());
  436. if (discountDetailDto.getMaxValue() != null) {
  437. abs = Math.min(abs, discountDetailDto.getMaxValue().doubleValue());
  438. }
  439. // 判断是优惠还是提价
  440. boolean positiveNum = discountValue.subtract(valuationRes.getDeliveryAmount()).compareTo(BigDecimal.ZERO) >= 0;
  441. if (positiveNum) {
  442. valuationRes.setDeliveryAmount(valuationRes.getDeliveryAmount().add(new BigDecimal(abs)));
  443. } else {
  444. valuationRes.setDeliveryAmount(valuationRes.getDeliveryAmount().subtract(new BigDecimal(abs)));
  445. }
  446. valuationRes.setZk(discountDetailDto.getValue());
  447. }
  448. } else if (PackageDiscountDetailTypeEnum.GRADIENT.type.equals(discountDetailDto.getType())) {
  449. for (PackageDiscountDetailDto item : discountDetailDtoList) {
  450. boolean inRange = BigDecimalUtils.inRange(item.getLeftValue(), item.getRightValue(), valuationRes.getDeliveryAmount());
  451. if (inRange) {
  452. if (item.getValue() != null) {
  453. BigDecimal discountAmount = valuationRes.getDeliveryAmount().subtract(item.getValue());
  454. valuationRes.setDeliveryAmount(discountAmount.compareTo(BigDecimal.ZERO) > 0 ? discountAmount : BigDecimal.ZERO);
  455. valuationRes.setMj(item.getValue());
  456. }
  457. break;
  458. }
  459. }
  460. }
  461. }
  462. }
  463. private Long setWaimaiOrderInfo(OrderReq orderReq, String takeRemark, Long shopId) {
  464. WaimaiOrder waimaiOrder = iWaimaiOrderService.findById(orderReq.getWaimaiOrderId());
  465. if (waimaiOrder.getOrderType().equals(WaimaiOrderTypeEnum.MEI_TUAN.getType())) {
  466. orderReq.setOrderSource("101");
  467. orderReq.setOrderingSourceNo(waimaiOrder.getOutOrderId());
  468. orderReq.setZbOrderingSourceNo(waimaiOrder.getOutOrderId());
  469. // 查询美团跑腿的token
  470. // DspWaimai waiMai = iDspWaimaiService.findOne(WaimaiTypeEnums.MEI_TUAN.getType());
  471. List<WaimaiDto> waiMai = iDspWaimaiService.findList();
  472. if (CollectionUtils.isNotEmpty(waiMai)){
  473. for(WaimaiDto dto:waiMai){
  474. if(WaimaiOrderTypeEnum.MEI_TUAN.getType().equals(dto.getType())){
  475. ShopWaimai shopWaimai = iShopWaimaiService.findByThirdShopId(shopId, dto.getWaimaiId(),waimaiOrder.getThirdShopId());
  476. if (shopWaimai != null){
  477. orderReq.setZbToken(shopWaimai.getAuthToken());
  478. }
  479. }else if(WaimaiOrderTypeEnum.MEI_TUAN_SG.getType().equals(dto.getType())){
  480. ShopWaimai shopWaimai = iShopWaimaiService.findByThirdShopId(shopId, dto.getWaimaiId(),waimaiOrder.getThirdShopId());
  481. if (shopWaimai != null){
  482. orderReq.setZbToken(shopWaimai.getAuthToken());
  483. }
  484. }
  485. }
  486. }
  487. } else if (waimaiOrder.getOrderType().equals(WaimaiOrderTypeEnum.E_LE_ME.getType())) {
  488. orderReq.setOrderSource("102");
  489. }else if (waimaiOrder.getOrderType().equals(WaimaiOrderTypeEnum.E_LE_ME_RETAIL.getType())) {
  490. orderReq.setOrderSource("103");
  491. }else if (waimaiOrder.getOrderType().equals(WaimaiOrderTypeEnum.MEI_TUAN_SG.getType())) {
  492. orderReq.setOrderSource("101");
  493. }else if (waimaiOrder.getOrderType().equals(WaimaiOrderTypeEnum.JD_HOME.getType())) {
  494. orderReq.setOrderSource("104");
  495. }
  496. orderReq.setTakeRemark(takeRemark);
  497. orderReq.setWaiMaiRemark(waimaiOrder.getCaution());
  498. orderReq.setMtMoney(waimaiOrder.getTotalPrice());
  499. orderReq.setPoiSeq(waimaiOrder.getDaySeq());
  500. orderReq.setWaimaiOrderDetails(iWaimaiOrderDetailService.findList(orderReq.getWaimaiOrderId()));
  501. return waimaiOrder.getShopId();
  502. }
  503. private ValuationRes queryOrderDeliverFee(OrderReq orderReq, DeliveryInfo delivery, Long merchantId, Long shopId, Integer defaultShop) {
  504. if (DeliveryTypeEnums.SHUN_FENG.getType().equals(delivery.getType()) && "0".equals(orderReq.getProduct().getSfProductType())) {
  505. return null;
  506. }
  507. // 顺丰个人地址发单(发单地址距离门店100米内,算门店发单)且是自运力, 走猎豹平台计价
  508. if (DeliveryTypeEnums.SHUN_FENG.getType().equals(delivery.getType()) && DefaultShopEnum.SHOW.status.equals(defaultShop) && delivery.getIsMine() == 1) {
  509. delivery.setIsMine(0);
  510. delivery.setThirdShopId(null);
  511. }
  512. orderReq.setOrderSn(SnCodeUtils.createSn());
  513. orderReq.setAmount(orderReq.getProductAmount());
  514. OrderVo orderVo = OrderEntityUtils.createOrderVo(orderReq, delivery, deliveryConfig.isTest());
  515. orderVo.setIsMine(delivery.getIsMine());
  516. if (DeliveryTypeEnums.FENG_NIAO.getType().equals(delivery.getType()) || DeliveryTypeEnums.MEI_TUAN.getType().equals(delivery.getType())
  517. || DeliveryTypeEnums.FENG_NIAO_PT.getType().equals(delivery.getType())) {
  518. ShopDelivery shopDelivery = iShopDeliveryService.findOne(shopId, delivery.getId());
  519. if (shopDelivery == null || !BindStatusEnum.BIND.status.equals(shopDelivery.getBindStatus())) {
  520. return null;
  521. }
  522. }
  523. if ((DeliveryTypeEnums.FENG_NIAO.getType().equals(delivery.getType())
  524. || DeliveryTypeEnums.MEI_TUAN.getType().equals(delivery.getType())
  525. ||DeliveryTypeEnums.FENG_NIAO_PT.getType().equals(delivery.getType()))
  526. && DefaultShopEnum.SHOW.status.equals(defaultShop)) {
  527. return null;
  528. }
  529. if ((DeliveryTypeEnums.FENG_NIAO.getType().equals(delivery.getType())||DeliveryTypeEnums.FENG_NIAO_PT.getType().equals(delivery.getType())) && shopId == null) {
  530. return null;
  531. }
  532. // 美团跑腿未绑定不参与计价
  533. if ((DeliveryTypeEnums.MEI_TUAN_ZB.getType().equals(delivery.getType()) ||DeliveryTypeEnums.MEI_TUAN_SG_ZB.getType().equals(delivery.getType()))&& delivery.getIsMine() == 0){
  534. return null;
  535. }
  536. if ((DeliveryTypeEnums.MEI_TUAN_ZB.getType().equals(delivery.getType()) ||DeliveryTypeEnums.MEI_TUAN_SG_ZB.getType().equals(delivery.getType()))){
  537. SysConfig sysConfig = iSysConfigService.selectSysConfigByKey("MT_PT");
  538. if (sysConfig.getConfigValue().equals("yes") && shopId != 1626){
  539. return null;
  540. }
  541. }
  542. ResObject<OrderResultVo> resObject = client.queryOrderDeliverFee(orderVo);
  543. if (resObject.getCode() == 0) {
  544. ValuationRes res = new ValuationRes();
  545. transResObject(res, delivery, resObject, orderReq, orderVo);
  546. // 判断是否是自己平台,查询金额是否充足
  547. if (delivery.getIsMine() == 1 && !delivery.getType().equals(DeliveryTypeEnums.KUAI_FU.getType())
  548. && !delivery.getType().equals(DeliveryTypeEnums.MEI_TUAN_ZB.getType())
  549. && !DeliveryTypeEnums.MEI_TUAN_ZB.getType().equals(delivery.getType())) {
  550. QueryAmount queryAmount = QueryAmountEntityUtils.queryAmount(delivery, merchantId, delivery.getIsMine());
  551. ResObject<AmountResultVo> amountRes = client.queryAmount(queryAmount);
  552. if (amountRes.getCode() == 0) {
  553. // 更新余额
  554. AmountResultVo vo = amountRes.getData();
  555. this.updateAmount(delivery, merchantId, shopId, vo.getBalanceAmount());
  556. if (vo.getBalanceAmount().compareTo(res.getDeliveryAmount()) >= 0) {
  557. res.setIsEnough(StatusEnum.SHOW.status);
  558. res.setIsMine(1);
  559. } else {
  560. //uupt需重新计价
  561. res.setIsMine(0);
  562. orderVo.setIsMine(0);
  563. if (DeliveryTypeEnums.UUPT.getName().equals(orderVo.getLbClient())||DeliveryTypeEnums.SHAN_SONG.getName().equals(orderVo.getLbClient())) {
  564. orderVo.setOpenId("");
  565. resObject = client.queryOrderDeliverFee(orderVo);
  566. if (resObject.getCode() == 0) {
  567. transResObject(res, delivery, resObject, orderReq, orderVo);
  568. }else{
  569. res = null;
  570. }
  571. }
  572. if (DeliveryTypeEnums.DADA.getType().equals(delivery.getType()) || DeliveryTypeEnums.DADA_YZ.getType().equals(delivery.getType())){
  573. // 达达/优质余额不足,重新计价
  574. log.info("余额不足----" + DeliveryTypeEnums.getNameByType(delivery.getType()) + "余额不足,重新计价");
  575. ShopDelivery sd = iShopDeliveryService.getOne(new QueryWrapper<ShopDelivery>().eq("merchant_id", merchantId).eq("delivery_id", delivery.getId())
  576. .eq("deleted", IsDeleteEnum.NORMAL.status).eq("shop_id", shopId).eq("bind_status",1));
  577. if (sd != null && sd.getThirdShopId() != null) {
  578. orderVo.setShopNo(sd.getThirdShopId());
  579. delivery.setShopId(sd.getThirdShopId());
  580. } else {
  581. // 如果默认店铺被删了,则取列表第一个
  582. List<ShopDelivery> deliveries = iShopDeliveryService.list(new QueryWrapper<ShopDelivery>().eq("merchant_id", merchantId).eq("delivery_id", delivery.getId())
  583. .eq("deleted", IsDeleteEnum.NORMAL.status).isNotNull("third_shop_id"));
  584. if (CollectionUtils.isNotEmpty(deliveries)){
  585. orderVo.setShopNo(deliveries.get(0).getThirdShopId());
  586. delivery.setShopId(deliveries.get(0).getThirdShopId());
  587. }
  588. }
  589. orderVo.setMerchantId(null);
  590. resObject = client.queryOrderDeliverFee(orderVo);
  591. if (resObject.getCode() == 0) {
  592. transResObject(res, delivery, resObject, orderReq, orderVo);
  593. }else{
  594. res = null;
  595. }
  596. }
  597. // 顺丰自运力余额不足,转猎豹平台重写计价
  598. if (DeliveryTypeEnums.SHUN_FENG.getName().equals(orderVo.getLbClient())) {
  599. delivery.setIsMine(0);
  600. delivery.setThirdShopId(null);
  601. OrderVo reOrderVo = OrderEntityUtils.createOrderVo(orderReq, delivery, deliveryConfig.isTest());
  602. reOrderVo.setIsMine(delivery.getIsMine());
  603. resObject = client.queryOrderDeliverFee(reOrderVo);
  604. if (resObject.getCode() == 0) {
  605. transResObject(res, delivery, resObject, orderReq, orderVo);
  606. }else{
  607. res = null;
  608. }
  609. }
  610. }
  611. }
  612. } else if (delivery.getIsMine() == 1 && delivery.getType().equals(DeliveryTypeEnums.KUAI_FU.getType())) {
  613. if (!resObject.getData().getFeStatus().equals("1")) {
  614. res.setIsMine(0);
  615. orderVo.setIsMine(0);
  616. orderVo.setAccessToken(null);
  617. orderVo.setOpenId(null);
  618. resObject = client.queryOrderDeliverFee(orderVo);
  619. if (resObject.getCode() == 0) {
  620. transResObject(res, delivery, resObject, orderReq, orderVo);
  621. }else{
  622. res = null;
  623. }
  624. }
  625. }
  626. return res;
  627. }
  628. return null;
  629. }
  630. private void updateAmount(DeliveryInfo delivery, Long merchantId, Long shopId, BigDecimal balanceAmount) {
  631. if (DeliveryTypeEnums.DADA.getType().equals(delivery.getType())
  632. || DeliveryTypeEnums.DADA_YZ.getType().equals(delivery.getType())
  633. || DeliveryTypeEnums.FENG_NIAO.getType().equals(delivery.getType())
  634. || DeliveryTypeEnums.SHUN_FENG.getType().equals(delivery.getType())
  635. || DeliveryTypeEnums.MEI_TUAN_ZB.getType().equals(delivery.getType())) {
  636. ShopDeliveryBind shopDeliveryBind = iShopDeliveryBindService.getOne(new QueryWrapper<ShopDeliveryBind>()
  637. .eq("merchant_id", merchantId).eq("shop_id", shopId).eq("delivery_id", delivery.getId())
  638. .eq("deleted", IsDeleteEnum.NORMAL.status).eq("bind_status", 1));
  639. // 门店模式变更余额
  640. if (shopDeliveryBind != null) {
  641. iShopDeliveryBindService.updateShopAmount(shopDeliveryBind.getMerchantId(), shopDeliveryBind.getDeliveryId(), shopDeliveryBind.getThirdShopId(), balanceAmount);
  642. }
  643. } else {
  644. ShopDeliveryBind shopDeliveryBind = iShopDeliveryBindService.getOne(new QueryWrapper<ShopDeliveryBind>()
  645. .eq("merchant_id", merchantId).eq("delivery_id", delivery.getId())
  646. .eq("deleted", IsDeleteEnum.NORMAL.status).isNull("shop_id")
  647. .eq("bind_status", 1));
  648. // 商户模式变更余额
  649. if (shopDeliveryBind != null) {
  650. iShopDeliveryBindService.updateMerchantAmount(shopDeliveryBind.getId(), balanceAmount);
  651. }
  652. }
  653. }
  654. private void transResObject(ValuationRes res, DeliveryInfo delivery, ResObject<OrderResultVo> resObject, OrderReq orderReq, OrderVo orderVo) {
  655. res.setDeliveryId(delivery.getId());
  656. res.setName(delivery.getName());
  657. res.setLogo(delivery.getLogo());
  658. res.setDesc(CommonUtils.change2Km((int) resObject.getData().getDistance()));
  659. res.setDeliveryAmount(resObject.getData().getDeliverFee());
  660. res.setIsEnough(StatusEnum.STOP.status);
  661. res.setTotalMoney(resObject.getData().getTotalMoney());
  662. res.setNeedPaymoney(resObject.getData().getNeedPaymoney());
  663. res.setPriceToken(resObject.getData().getPriceToken());
  664. // res.setDeliveryInfo(delivery);
  665. res.setOrderSn(orderReq.getOrderSn());
  666. res.setIsMine(orderVo.getIsMine());
  667. res.setOrderNo(orderReq.getOrderNo());
  668. res.setCityId(resObject.getData().getCityId());
  669. res.setCityInfoRevision(resObject.getData().getCityInfoRevision());
  670. res.setOrderVehicleId(resObject.getData().getOrderVehicleId());
  671. res.setTotalPriceFen(resObject.getData().getHllAmount());
  672. res.setOrderNumber(resObject.getData().getDeliveryOrderNo());//闪送订单号
  673. res.setShopId(delivery.getShopId());
  674. res.setThirdShopId(delivery.getThirdShopId());
  675. res.setAuthToken(delivery.getAuthToken());
  676. res.setPhone(delivery.getPhone());
  677. res.setDeliveryType(delivery.getType());
  678. }
  679. }