|
@@ -8,6 +8,7 @@ import com.caimei.modules.order.entity.*;
|
|
import com.caimei.modules.order.utils.Disguiser;
|
|
import com.caimei.modules.order.utils.Disguiser;
|
|
import com.caimei.redis.RedisService;
|
|
import com.caimei.redis.RedisService;
|
|
import com.caimei.utils.MathUtil;
|
|
import com.caimei.utils.MathUtil;
|
|
|
|
+import com.google.common.util.concurrent.AtomicDouble;
|
|
import com.thinkgem.jeesite.common.service.BaseService;
|
|
import com.thinkgem.jeesite.common.service.BaseService;
|
|
import okhttp3.*;
|
|
import okhttp3.*;
|
|
import org.apache.commons.lang3.StringUtils;
|
|
import org.apache.commons.lang3.StringUtils;
|
|
@@ -21,6 +22,8 @@ import java.math.BigDecimal;
|
|
import java.text.SimpleDateFormat;
|
|
import java.text.SimpleDateFormat;
|
|
import java.util.*;
|
|
import java.util.*;
|
|
import java.util.concurrent.TimeUnit;
|
|
import java.util.concurrent.TimeUnit;
|
|
|
|
+import java.util.concurrent.atomic.AtomicReference;
|
|
|
|
+import java.util.stream.Collectors;
|
|
|
|
|
|
|
|
|
|
@Service
|
|
@Service
|
|
@@ -46,388 +49,298 @@ public class SplitAccountService extends BaseService {
|
|
calendar.setTime(new Date());
|
|
calendar.setTime(new Date());
|
|
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
|
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
|
String currentTime = format.format(calendar.getTime());
|
|
String currentTime = format.format(calendar.getTime());
|
|
- // 查询未分账已支付收款
|
|
|
|
- List<OrderReceiptRelationPo> orderRelations = newOrderDao.getUndividedPaidReceipt(currentTime, shopOrderIds);
|
|
|
|
- if (null != orderRelations && orderRelations.size() > 0) {
|
|
|
|
|
|
+ List<String> ids = new ArrayList<>();
|
|
|
|
+ if (shopOrderIds.contains(",")) {
|
|
|
|
+ ids = Arrays.stream(shopOrderIds.split(",")).collect(Collectors.toList());
|
|
|
|
+ } else {
|
|
|
|
+ ids.add(shopOrderIds);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ ids.forEach(i -> {
|
|
|
|
+ // 查询未分账已支付收款
|
|
|
|
+ List<OrderReceiptRelationPo> orderRelations = newOrderDao.getUndividedPaidReceipt(currentTime, i);
|
|
|
|
+ List<SplitAccountPo> splitBillDetail = new ArrayList<>();
|
|
|
|
+ AtomicReference<Double> costPrice = new AtomicReference<Double>(0d);
|
|
|
|
+ AtomicReference<Double> cmCostPrice = new AtomicReference<Double>(0d);
|
|
|
|
+ AtomicReference<Double> organizeCostPrice = new AtomicReference<Double>(0d);
|
|
|
|
+ // 收款对应的订单信息
|
|
|
|
+ ShopOrderVo shopOrder = newOrderDao.getShopOrderListByOrderId(Integer.valueOf(i));
|
|
for (OrderReceiptRelationPo orderRelation : orderRelations) {
|
|
for (OrderReceiptRelationPo orderRelation : orderRelations) {
|
|
logger.info("【分账】>>>>>>>>>>子订单id:" + orderRelation.getShopOrderId() + "进入分账");
|
|
logger.info("【分账】>>>>>>>>>>子订单id:" + orderRelation.getShopOrderId() + "进入分账");
|
|
- // 收款对应的订单信息
|
|
|
|
- ShopOrderVo shopOrder = newOrderDao.getShopOrderListByOrderId(orderRelation.getShopOrderId());
|
|
|
|
- PayParamBo payParam = new PayParamBo();
|
|
|
|
- //支付金额
|
|
|
|
- payParam.setAllPay(orderRelation.getAssociateAmount());
|
|
|
|
- if (12 == orderRelation.getPayType()) {
|
|
|
|
- // 网银支付
|
|
|
|
- payParam.setPayWay("UNIONPAY");
|
|
|
|
- }
|
|
|
|
- if (17 == orderRelation.getPayType()) {
|
|
|
|
- //b2c网银
|
|
|
|
- payParam.setPayWay("B2C");
|
|
|
|
- }
|
|
|
|
- //微信0.65%手续费
|
|
|
|
- if (8 == orderRelation.getPayType() || 13 == orderRelation.getPayType() || 15 == orderRelation.getPayType()) {
|
|
|
|
- payParam.setPayWay("WX");
|
|
|
|
- }
|
|
|
|
- //快捷支付 借记卡支付29,贷记卡支付30
|
|
|
|
- if (29 == orderRelation.getPayType()) {
|
|
|
|
- payParam.setPayWay("DEBIT");
|
|
|
|
|
|
+ setSplitAccountDetail(costPrice, organizeCostPrice, cmCostPrice, shopOrder, orderRelation);
|
|
|
|
+ }
|
|
|
|
+ /**
|
|
|
|
+ * 线上订单,付第三方如果不为0,需要从供应商成本中支付
|
|
|
|
+ */
|
|
|
|
+ double payOther = newOrderDao.findPayOther(Integer.valueOf(i));
|
|
|
|
+ if (MathUtil.compare(payOther, 0) > 0) {
|
|
|
|
+ SplitAccountPo splitAccount = new SplitAccountPo();
|
|
|
|
+ splitAccount.setOrderId(shopOrder.getOrderId());
|
|
|
|
+ splitAccount.setShopOrderId(shopOrder.getShopOrderId());
|
|
|
|
+ splitAccount.setSplitAccount(payOther);
|
|
|
|
+ splitAccount.setProductType(6);
|
|
|
|
+ splitAccount.setType(6);
|
|
|
|
+ splitAccount.setSubUserNo(Constant.CUSTOMERNUM3);
|
|
|
|
+ logger.info("付第三方分账参数------------->" + splitAccount);
|
|
|
|
+ splitBillDetail.add(splitAccount);
|
|
|
|
+ // 当前版本付第三方从供应商成本支出
|
|
|
|
+ costPrice.updateAndGet(v -> MathUtil.sub(v, payOther).doubleValue());
|
|
|
|
+ }
|
|
|
|
+ if (costPrice.get() > 0) {
|
|
|
|
+ SplitAccountPo splitAccount = new SplitAccountPo();
|
|
|
|
+ splitAccount.setShopOrderId(shopOrder.getShopOrderId());
|
|
|
|
+ splitAccount.setOrderId(shopOrder.getOrderId());
|
|
|
|
+ splitAccount.setSplitAccount(costPrice.get());
|
|
|
|
+ splitAccount.setProductType(1);
|
|
|
|
+ // 该商品设置了商户号
|
|
|
|
+ splitAccount.setType(4);
|
|
|
|
+ splitAccount.setSubUserNo(shopOrder.getSplitCode());
|
|
|
|
+ logger.info("成本分账参数------------->" + splitAccount.toString());
|
|
|
|
+ splitBillDetail.add(splitAccount);
|
|
|
|
+ }
|
|
|
|
+ /** 成本分完,金额未尽,有组织佣金的情况,优先组织佣金
|
|
|
|
+ * 当前版本,采美供应商上架丽格商城,会存在三成本均>0的情况
|
|
|
|
+ * 若无组织佣金,所有剩余金额归于采美佣金
|
|
|
|
+ */
|
|
|
|
+ if (organizeCostPrice.get() > 0) {
|
|
|
|
+ SplitAccountPo splitAccount = new SplitAccountPo();
|
|
|
|
+ splitAccount.setShopOrderId(shopOrder.getShopOrderId());
|
|
|
|
+ splitAccount.setOrderId(shopOrder.getOrderId());
|
|
|
|
+ splitAccount.setSplitAccount(organizeCostPrice.get());
|
|
|
|
+ splitAccount.setProductType(5);
|
|
|
|
+ // 该商品设置了商户号
|
|
|
|
+ splitAccount.setType(4);
|
|
|
|
+ String code = newOrderDao.findSplitCodeByOrganize(shopOrder.getOrganizeId());
|
|
|
|
+ if (StringUtils.isBlank(code)) {
|
|
|
|
+ logger.info("组织的分帐号未空,无法分帐组织佣金!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!");
|
|
|
|
+ return;
|
|
}
|
|
}
|
|
- if (30 == orderRelation.getPayType()) {
|
|
|
|
- payParam.setPayWay("CREDIT");
|
|
|
|
|
|
+ splitAccount.setSubUserNo(code);
|
|
|
|
+ logger.info("组织佣金分账参数------------->" + splitAccount.toString());
|
|
|
|
+ splitBillDetail.add(splitAccount);
|
|
|
|
+ }
|
|
|
|
+ /** 当前版本还要考虑分组织/集团佣金
|
|
|
|
+ * 如果还有钱则为佣金,分到网络
|
|
|
|
+ */
|
|
|
|
+ if (cmCostPrice.get() > 0) {
|
|
|
|
+ // 此处不考虑手续费,外部计算总额
|
|
|
|
+ SplitAccountPo splitAccount = new SplitAccountPo();
|
|
|
|
+ splitAccount.setOrderId(shopOrder.getOrderId());
|
|
|
|
+ splitAccount.setShopOrderId(shopOrder.getShopOrderId());
|
|
|
|
+ splitAccount.setSplitAccount(cmCostPrice.get());
|
|
|
|
+ splitAccount.setProductType(3);
|
|
|
|
+ splitAccount.setType(5);
|
|
|
|
+ splitAccount.setSubUserNo(Constant.CUSTOMERNUM2);
|
|
|
|
+ logger.info("佣金分账参数------------->" + splitAccount);
|
|
|
|
+ splitBillDetail.add(splitAccount);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ HashMap<String, BigDecimal> sbm = new HashMap<>();
|
|
|
|
+ for (SplitAccountPo splitAccountPo : splitBillDetail) {
|
|
|
|
+ String subUserNo = splitAccountPo.getSubUserNo();
|
|
|
|
+ // 计算当前商户号总分账金额
|
|
|
|
+ if (sbm.containsKey(subUserNo)) {
|
|
|
|
+ BigDecimal v = MathUtil.add(sbm.get(subUserNo), splitAccountPo.getSplitAccount());
|
|
|
|
+ sbm.put(subUserNo, v);
|
|
|
|
+ } else {
|
|
|
|
+ sbm.put(subUserNo, BigDecimal.valueOf(splitAccountPo.getSplitAccount()));
|
|
}
|
|
}
|
|
- List<SplitAccountPo> splitBillDetail = setSplitAccountDetail(shopOrder, payParam);
|
|
|
|
- if (null == splitBillDetail || 0 == splitBillDetail.size()) {
|
|
|
|
- logger.info("分帐参数有误!!!!!!!!!!!!!");
|
|
|
|
- return;
|
|
|
|
|
|
+ // splitcode相同的收款的时候已经是成本已分帐
|
|
|
|
+ if (subUserNo.equals(shopOrder.getSplitCode())) {
|
|
|
|
+ // 供应商自己收款,此部分金额留在自己商户号,作为成本分账
|
|
|
|
+ splitAccountPo.setPayStatus(1);
|
|
|
|
+ // 保存分账详情
|
|
|
|
+ newOrderDao.insertSplitAccount(splitAccountPo);
|
|
}
|
|
}
|
|
- HashMap<String, BigDecimal> sbm = new HashMap<>();
|
|
|
|
- for (SplitAccountPo splitAccountPo : splitBillDetail) {
|
|
|
|
- String subUserNo = splitAccountPo.getSubUserNo();
|
|
|
|
- // 计算当前商户号总分账金额
|
|
|
|
- if (sbm.containsKey(subUserNo)) {
|
|
|
|
- BigDecimal v = MathUtil.add(sbm.get(subUserNo), splitAccountPo.getSplitAccount());
|
|
|
|
- sbm.put(subUserNo, v);
|
|
|
|
- } else {
|
|
|
|
- sbm.put(subUserNo, BigDecimal.valueOf(splitAccountPo.getSplitAccount()));
|
|
|
|
- }
|
|
|
|
- // splitcode相同的收款的时候已经是成本已分帐
|
|
|
|
- if (subUserNo.equals(shopOrder.getSplitCode())) {
|
|
|
|
- splitAccountPo.setMbOrderId(orderRelation.getMbOrderId());
|
|
|
|
- splitAccountPo.setOrderRequestNo(orderRelation.getOrderRequestNo());
|
|
|
|
- // 供应商自己收款,此部分金额留在自己商户号,作为成本分账
|
|
|
|
- splitAccountPo.setPayStatus(1);
|
|
|
|
- // 保存分账详情
|
|
|
|
- newOrderDao.insertSplitAccount(splitAccountPo);
|
|
|
|
|
|
+ }
|
|
|
|
+ ArrayList<AccountPayOrder.AccountPayOrderExt.SplitBillRule> splitBillRules = new ArrayList<>();
|
|
|
|
+ sbm.forEach((key, value) -> {
|
|
|
|
+ /**
|
|
|
|
+ * 不是自己的splitcode分走,是自己的不动
|
|
|
|
+ * 把成本之外的金额加入splitRule分账参数,延续上面逻辑,供应商自己的成本由自己的商户号收款,
|
|
|
|
+ * 自己成本部分不需要加入分账参数,仅需在else中做业务表参数处理
|
|
|
|
+ */
|
|
|
|
+ if (!key.equals(shopOrder.getSplitCode())) {
|
|
|
|
+ // 佣金
|
|
|
|
+ AccountPayOrder.AccountPayOrderExt.SplitBillRule splitBillRule = new AccountPayOrder.AccountPayOrderExt.SplitBillRule();
|
|
|
|
+ // 分账计算的时候未处理手续费,总额处理手续费 x + x * 0.1% = value
|
|
|
|
+ BigDecimal div = MathUtil.div(value, 1.001, 2);
|
|
|
|
+ if (MathUtil.sub(value, div).doubleValue() < 0.01) {
|
|
|
|
+ // 如果手续费小于最低手续费,取0.01
|
|
|
|
+ div = MathUtil.round(MathUtil.sub(value, 0.01), 2);
|
|
}
|
|
}
|
|
- }
|
|
|
|
- ArrayList<AccountPayOrder.AccountPayOrderExt.SplitBillRule> splitBillRules = new ArrayList<>();
|
|
|
|
- sbm.forEach((key, value) -> {
|
|
|
|
- /**
|
|
|
|
- * 不是自己的splitcode分走,是自己的不动
|
|
|
|
- * 把成本之外的金额加入splitRule分账参数,延续上面逻辑,供应商自己的成本由自己的商户号收款,
|
|
|
|
- * 自己成本部分不需要加入分账参数,仅需在else中做业务表参数处理
|
|
|
|
- */
|
|
|
|
- if (!key.equals(shopOrder.getSplitCode())) {
|
|
|
|
- // 佣金
|
|
|
|
- AccountPayOrder.AccountPayOrderExt.SplitBillRule splitBillRule = new AccountPayOrder.AccountPayOrderExt.SplitBillRule();
|
|
|
|
- // 分账计算的时候未处理手续费,总额处理手续费 x + x * 0.1% = value
|
|
|
|
- BigDecimal div = MathUtil.div(value, 1.001, 2);
|
|
|
|
- if (MathUtil.sub(value, div).doubleValue() < 0.01) {
|
|
|
|
- // 如果手续费小于最低手续费,取0.01
|
|
|
|
- div = MathUtil.round(MathUtil.sub(value, 0.01), 2);
|
|
|
|
|
|
+ splitBillRule.setSplitBillAmount(div);
|
|
|
|
+ splitBillRule.setSplitBillMerchantNo(key);
|
|
|
|
+ splitBillRules.add(splitBillRule);
|
|
|
|
+ } else {
|
|
|
|
+ // 修改子订单付款状态及付款金额
|
|
|
|
+ newOrderDao.updateShopOrderByPayStatus(Integer.valueOf(i), value.doubleValue(), shopOrder.getPayStatus());
|
|
|
|
+ SimpleDateFormat format2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
|
|
|
+ String currentTime2 = format2.format(new Date());
|
|
|
|
+ // 保存付款单表
|
|
|
|
+ PayShopPo payShop = new PayShopPo();
|
|
|
|
+ payShop.setShopId(shopOrder.getShopId());
|
|
|
|
+ payShop.setName("线上支付分账");
|
|
|
|
+ payShop.setTotalAmount(value.doubleValue());
|
|
|
|
+ payShop.setWipePayment(0d);
|
|
|
|
+ payShop.setPayType(6);
|
|
|
|
+ payShop.setStatus(1);
|
|
|
|
+ payShop.setDelFlag(0);
|
|
|
|
+ payShop.setApplyTime(currentTime2);
|
|
|
|
+ payShop.setReviewTime(currentTime2);
|
|
|
|
+ payShop.setPayTime(currentTime2);
|
|
|
|
+ newOrderDao.insertPayShop(payShop);
|
|
|
|
+ // 保存 付供应商记录
|
|
|
|
+ PayShopRecordPo shopRecord = new PayShopRecordPo();
|
|
|
|
+ shopRecord.setShopId(shopOrder.getShopId());
|
|
|
|
+ shopRecord.setShopOrderId(shopOrder.getShopOrderId());
|
|
|
|
+ shopRecord.setShopOrderNo(shopOrder.getShopOrderNo());
|
|
|
|
+ shopRecord.setPayAmount(value.doubleValue());
|
|
|
|
+ shopRecord.setWipePayment(0d);
|
|
|
|
+ shopRecord.setPayType(6);
|
|
|
|
+ shopRecord.setPayTime(currentTime2);
|
|
|
|
+ shopRecord.setPayShopId(payShop.getId());
|
|
|
|
+ shopRecord.setStatus(1);
|
|
|
|
+ shopRecord.setDelFlag(0);
|
|
|
|
+ newOrderDao.insertPayShopRecord(shopRecord);
|
|
|
|
+ // 子订单是否全部付款
|
|
|
|
+ List<String> payStatus = newShopOrderDao.findPayStatusByOrderID(shopOrder.getOrderId());
|
|
|
|
+ boolean isPay = true;
|
|
|
|
+ for (String shops : payStatus) {
|
|
|
|
+ if (!"3".equals(shops)) {
|
|
|
|
+ isPay = false;
|
|
|
|
+ break;
|
|
}
|
|
}
|
|
- splitBillRule.setSplitBillAmount(div);
|
|
|
|
- splitBillRule.setSplitBillMerchantNo(key);
|
|
|
|
- splitBillRules.add(splitBillRule);
|
|
|
|
|
|
+ }
|
|
|
|
+ // 修改主订单付款状态
|
|
|
|
+ if (isPay) {
|
|
|
|
+ newOrderDao.updateOrderByPayStatus(shopOrder.getOrderId(), 3);
|
|
} else {
|
|
} else {
|
|
- /**
|
|
|
|
- * 成本分账处理
|
|
|
|
- * 子订单的splitcode和分账对象的splitcode一样的是留在账户里的钱,实际在付款完成后,付款状态就为已付款,分账状态就为已分账
|
|
|
|
- * 为维持业务完整性,保持原来的分账流程不变
|
|
|
|
- */
|
|
|
|
- List<SplitAccountPo> splitAccountList = newOrderDao.getSplitAccountList(orderRelation.getMbOrderId());
|
|
|
|
- if (splitAccountList != null && splitAccountList.size() > 0) {
|
|
|
|
- Integer orderId = splitAccountList.get(0).getOrderId();
|
|
|
|
- List<ShopOrderVo> shopOrderList = newOrderDao.getShopOrderByOrderId(orderId);
|
|
|
|
- Integer shopOrderId = null;
|
|
|
|
- String shopOrderNo = "";
|
|
|
|
- for (SplitAccountPo account : splitAccountList) {
|
|
|
|
- // 本次付供应商金额(分账金额)
|
|
|
|
- Double splitAmount = account.getSplitAccount();
|
|
|
|
- orderId = account.getOrderId();
|
|
|
|
- Integer shopId = account.getShopId();
|
|
|
|
- for (ShopOrderVo shop : shopOrderList) {
|
|
|
|
- if (shopId.equals(shop.getShopId())) {
|
|
|
|
- shopOrderId = shop.getShopOrderId();
|
|
|
|
- shopOrderNo = shop.getShopOrderNo();
|
|
|
|
- // 已付供应商金额
|
|
|
|
- Double paidAmount = newOrderDao.getPaidShopAmount(shopOrderId);
|
|
|
|
- Double paidShop = MathUtil.add(paidAmount, splitAmount).doubleValue();
|
|
|
|
- shopOrder.setPayedShopAmount(paidShop);
|
|
|
|
- if (MathUtil.compare(shopOrder.getShouldPayShopAmount(), paidShop) == 0) {
|
|
|
|
- shopOrder.setPayStatus(3);
|
|
|
|
- } else {
|
|
|
|
- shopOrder.setPayStatus(2);
|
|
|
|
- }
|
|
|
|
- // 修改子订单付款状态及付款金额
|
|
|
|
- newOrderDao.updateShopOrderByPayStatus(shopOrderId, paidShop, shopOrder.getPayStatus());
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- SimpleDateFormat format2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
|
|
|
|
- String currentTime2 = format2.format(new Date());
|
|
|
|
- // 保存付款单表
|
|
|
|
- PayShopPo payShop = new PayShopPo();
|
|
|
|
- payShop.setShopId(shopId);
|
|
|
|
- payShop.setName("线上支付分账");
|
|
|
|
- payShop.setTotalAmount(splitAmount);
|
|
|
|
- payShop.setWipePayment(0d);
|
|
|
|
- payShop.setPayType(6);
|
|
|
|
- payShop.setStatus(1);
|
|
|
|
- payShop.setDelFlag(0);
|
|
|
|
- payShop.setApplyTime(currentTime2);
|
|
|
|
- payShop.setReviewTime(currentTime2);
|
|
|
|
- payShop.setPayTime(currentTime2);
|
|
|
|
- newOrderDao.insertPayShop(payShop);
|
|
|
|
- // 保存 付供应商记录
|
|
|
|
- PayShopRecordPo shopRecord = new PayShopRecordPo();
|
|
|
|
- shopRecord.setShopId(shopId);
|
|
|
|
- shopRecord.setShopOrderId(shopOrderId);
|
|
|
|
- shopRecord.setShopOrderNo(shopOrderNo);
|
|
|
|
- shopRecord.setPayAmount(splitAmount);
|
|
|
|
- shopRecord.setWipePayment(0d);
|
|
|
|
- shopRecord.setPayType(6);
|
|
|
|
- shopRecord.setPayTime(currentTime2);
|
|
|
|
- shopRecord.setPayShopId(payShop.getId());
|
|
|
|
- shopRecord.setStatus(1);
|
|
|
|
- shopRecord.setDelFlag(0);
|
|
|
|
- newOrderDao.insertPayShopRecord(shopRecord);
|
|
|
|
- }
|
|
|
|
- // 子订单是否全部付款
|
|
|
|
- List<String> payStatus = newShopOrderDao.findPayStatusByOrderID(orderRelation.getOrderId());
|
|
|
|
- boolean isPay = true;
|
|
|
|
- for (String shops : payStatus) {
|
|
|
|
- if (!"3".equals(shops)) {
|
|
|
|
- isPay = false;
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- // 修改主订单付款状态
|
|
|
|
- if (isPay) {
|
|
|
|
- newOrderDao.updateOrderByPayStatus(orderId, 3);
|
|
|
|
- } else {
|
|
|
|
- newOrderDao.updateOrderByPayStatus(orderId, 2);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
|
|
+ newOrderDao.updateOrderByPayStatus(shopOrder.getOrderId(), 2);
|
|
}
|
|
}
|
|
- });
|
|
|
|
- /**
|
|
|
|
- * 在上述else代码逻辑中已完成成本的业务表参数处理,在分账详情中排除成本,剩余佣金部分在分账结束收到
|
|
|
|
- * 成功返回码时处理(成本不参与分账)
|
|
|
|
- */
|
|
|
|
- splitBillDetail.removeIf(s -> s.getSubUserNo().equals(shopOrder.getSplitCode()));
|
|
|
|
- if (null != splitBillRules && splitBillRules.size() > 0) {
|
|
|
|
- //第三方分账接口
|
|
|
|
- try {
|
|
|
|
- AccountPayOrder accountPayOrder = new AccountPayOrder();
|
|
|
|
- accountPayOrder.setP1_bizType("AccountPaySub");
|
|
|
|
- accountPayOrder.setP2_signType("MD5");
|
|
|
|
- String format1 = new SimpleDateFormat("yyyy-MM-dd_HH:mm:ss.SSS").format(new Date());
|
|
|
|
- accountPayOrder.setP3_timestamp(format1);
|
|
|
|
- String substring = format1.substring(20);
|
|
|
|
- // fz+当前微秒时间+原唯一订单号
|
|
|
|
- accountPayOrder.setP4_orderId("FZ" + substring + orderRelation.getOrderRequestNo());
|
|
|
|
- //付款账户子订单绑定商户号
|
|
|
|
- accountPayOrder.setP5_customerNumber(shopOrder.getSplitCode());
|
|
|
|
- AccountPayOrder.AccountPayOrderExt accountPayOrderExt = new AccountPayOrder.AccountPayOrderExt();
|
|
|
|
- //收款账户商编 填写splitBillRules时候不填写MerchantNo,Amount并且即使填写这两个参数不生效!!
|
|
|
|
- //accountPayOrderExt.setInMerchantNo(splitMoneyVo.getName());
|
|
|
|
- //accountPayOrderExt.setAmount(splitMoneyVo.getSplitMoney());
|
|
|
|
- accountPayOrderExt.setOrderType(AccountPayOrderType.TRANSFER);
|
|
|
|
- accountPayOrderExt.setServerCallbackUrl(Constant.prodSplit);
|
|
|
|
- accountPayOrderExt.setGoodsName("分账");
|
|
|
|
- if (null != splitBillRules && splitBillRules.size() > 0) {
|
|
|
|
- accountPayOrderExt.setSplitBillRules(splitBillRules);
|
|
|
|
- }
|
|
|
|
- String ext = JSON.toJSONString(accountPayOrderExt);
|
|
|
|
- logger.info("分账规则串json串:" + ext);
|
|
|
|
- accountPayOrder.setP6_ext(ext);
|
|
|
|
- // 生成签名
|
|
|
|
- StringBuilder builder = new StringBuilder();
|
|
|
|
- builder.append(Constant.SPLIT)
|
|
|
|
- .append(accountPayOrder.getP1_bizType()).append(Constant.SPLIT)
|
|
|
|
- .append(accountPayOrder.getP2_signType()).append(Constant.SPLIT)
|
|
|
|
- .append(accountPayOrder.getP3_timestamp()).append(Constant.SPLIT)
|
|
|
|
- .append(accountPayOrder.getP4_orderId()).append(Constant.SPLIT)
|
|
|
|
- .append(accountPayOrder.getP5_customerNumber()).append(Constant.SPLIT)
|
|
|
|
- .append(accountPayOrder.getP6_ext()).append(Constant.SPLIT)
|
|
|
|
- .append(Constant.XUNI);
|
|
|
|
- String sign = Disguiser.disguiseMD5(builder.toString().trim());
|
|
|
|
- Map<String, String> bean = convertBean(accountPayOrder);
|
|
|
|
- logger.info("--------------------> 发送分账参数: " + bean);
|
|
|
|
- Map<String, String> map = postForm(bean, Constant.FZ, sign, Map.class);
|
|
|
|
- logger.info("----------------分账返回数据: " + map.toString());
|
|
|
|
- if (map != null) {
|
|
|
|
- String code = map.get("rt5_retCode");
|
|
|
|
- if (!"0000".equals(code)) {
|
|
|
|
- String msg = map.get("rt6_retMsg");
|
|
|
|
- logger.info("【手动分账】>>>>>>>>>>手动分账失败>>>>>>>msg:" + msg);
|
|
|
|
- } else {
|
|
|
|
- for (SplitAccountPo splitAccount : splitBillDetail) {
|
|
|
|
- splitAccount.setMbOrderId(orderRelation.getMbOrderId());
|
|
|
|
- splitAccount.setOrderRequestNo(orderRelation.getOrderRequestNo());
|
|
|
|
- splitAccount.setPayStatus(1);
|
|
|
|
- // 保存分账详情
|
|
|
|
- newOrderDao.insertSplitAccount(splitAccount);
|
|
|
|
- }
|
|
|
|
- redisService.remove("XSFZMDS");
|
|
|
|
- logger.info("【手动分账】>>>>>>>>>>此订单分账结束");
|
|
|
|
|
|
+ }
|
|
|
|
+ });
|
|
|
|
+ /**
|
|
|
|
+ * 在上述else代码逻辑中已完成成本的业务表参数处理,在分账详情中排除成本,剩余佣金部分在分账结束收到
|
|
|
|
+ * 成功返回码时处理(成本不参与分账)
|
|
|
|
+ */
|
|
|
|
+ splitBillDetail.removeIf(s -> s.getSubUserNo().equals(shopOrder.getSplitCode()));
|
|
|
|
+ if (null != splitBillRules && splitBillRules.size() > 0) {
|
|
|
|
+ //第三方分账接口
|
|
|
|
+ try {
|
|
|
|
+ AccountPayOrder accountPayOrder = new AccountPayOrder();
|
|
|
|
+ accountPayOrder.setP1_bizType("AccountPaySub");
|
|
|
|
+ accountPayOrder.setP2_signType("MD5");
|
|
|
|
+ String format1 = new SimpleDateFormat("yyyy-MM-dd_HH:mm:ss.SSS").format(new Date());
|
|
|
|
+ accountPayOrder.setP3_timestamp(format1);
|
|
|
|
+ String substring = format1.substring(20);
|
|
|
|
+ // fz+当前微秒时间+原唯一订单号
|
|
|
|
+ accountPayOrder.setP4_orderId("FZ" + substring + shopOrder.getShopOrderNo());
|
|
|
|
+ //付款账户子订单绑定商户号
|
|
|
|
+ accountPayOrder.setP5_customerNumber(shopOrder.getSplitCode());
|
|
|
|
+ AccountPayOrder.AccountPayOrderExt accountPayOrderExt = new AccountPayOrder.AccountPayOrderExt();
|
|
|
|
+ //收款账户商编 填写splitBillRules时候不填写MerchantNo,Amount并且即使填写这两个参数不生效!!
|
|
|
|
+ //accountPayOrderExt.setInMerchantNo(splitMoneyVo.getName());
|
|
|
|
+ //accountPayOrderExt.setAmount(splitMoneyVo.getSplitMoney());
|
|
|
|
+ accountPayOrderExt.setOrderType(AccountPayOrderType.TRANSFER);
|
|
|
|
+ accountPayOrderExt.setServerCallbackUrl(Constant.prodSplit);
|
|
|
|
+ accountPayOrderExt.setGoodsName("分账");
|
|
|
|
+ if (null != splitBillRules && splitBillRules.size() > 0) {
|
|
|
|
+ accountPayOrderExt.setSplitBillRules(splitBillRules);
|
|
|
|
+ }
|
|
|
|
+ String ext = JSON.toJSONString(accountPayOrderExt);
|
|
|
|
+ logger.info("分账规则串json串:" + ext);
|
|
|
|
+ accountPayOrder.setP6_ext(ext);
|
|
|
|
+ // 生成签名
|
|
|
|
+ StringBuilder builder = new StringBuilder();
|
|
|
|
+ builder.append(Constant.SPLIT)
|
|
|
|
+ .append(accountPayOrder.getP1_bizType()).append(Constant.SPLIT)
|
|
|
|
+ .append(accountPayOrder.getP2_signType()).append(Constant.SPLIT)
|
|
|
|
+ .append(accountPayOrder.getP3_timestamp()).append(Constant.SPLIT)
|
|
|
|
+ .append(accountPayOrder.getP4_orderId()).append(Constant.SPLIT)
|
|
|
|
+ .append(accountPayOrder.getP5_customerNumber()).append(Constant.SPLIT)
|
|
|
|
+ .append(accountPayOrder.getP6_ext()).append(Constant.SPLIT)
|
|
|
|
+ .append(Constant.XUNI);
|
|
|
|
+ String sign = Disguiser.disguiseMD5(builder.toString().trim());
|
|
|
|
+ Map<String, String> bean = convertBean(accountPayOrder);
|
|
|
|
+ logger.info("--------------------> 发送分账参数: " + bean);
|
|
|
|
+ Map<String, String> map = postForm(bean, Constant.FZ, sign, Map.class);
|
|
|
|
+ logger.info("----------------分账返回数据: " + map.toString());
|
|
|
|
+ if (map != null) {
|
|
|
|
+ String code = map.get("rt5_retCode");
|
|
|
|
+ if (!"0000".equals(code)) {
|
|
|
|
+ String msg = map.get("rt6_retMsg");
|
|
|
|
+ logger.info("【手动分账】>>>>>>>>>>手动分账失败>>>>>>>msg:" + msg);
|
|
|
|
+ } else {
|
|
|
|
+ for (SplitAccountPo splitAccount : splitBillDetail) {
|
|
|
|
+ splitAccount.setPayStatus(1);
|
|
|
|
+ // 保存分账详情
|
|
|
|
+ newOrderDao.insertSplitAccount(splitAccount);
|
|
}
|
|
}
|
|
|
|
+ redisService.remove("XSFZMDS");
|
|
|
|
+ logger.info("【手动分账】>>>>>>>>>>此订单分账结束");
|
|
}
|
|
}
|
|
- } catch (Exception e) {
|
|
|
|
- logger.error("【手动分账】>>>>>>>>>>错误信息", e);
|
|
|
|
}
|
|
}
|
|
- } else {
|
|
|
|
- // 没有佣金分账,全是成本,本笔交易已分帐
|
|
|
|
- newOrderDao.updateBySplitStatus(orderRelation.getMbOrderId());
|
|
|
|
- //没有佣金分账也解锁
|
|
|
|
- redisService.remove("XSFZMDS");
|
|
|
|
|
|
+ } catch (Exception e) {
|
|
|
|
+ logger.error("【手动分账】>>>>>>>>>>错误信息", e);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
- }
|
|
|
|
|
|
+ });
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
- public List<SplitAccountPo> setSplitAccountDetail(ShopOrderVo shopOrder, PayParamBo payParam) {
|
|
|
|
- List<SplitAccountPo> list = new ArrayList<>();
|
|
|
|
- // 本次支付金额,单位/元
|
|
|
|
- double payAmount = payParam.getAllPay();
|
|
|
|
|
|
+ public void setSplitAccountDetail(AtomicReference<Double> costPrice, AtomicReference<Double> organizePrice,
|
|
|
|
+ AtomicReference<Double> cmCostPrice, ShopOrderVo shopOrder, OrderReceiptRelationPo orderRelation) {
|
|
// 待分账总金额
|
|
// 待分账总金额
|
|
- double splitAmount = payAmount;
|
|
|
|
|
|
+ double splitAmount = orderRelation.getAssociateAmount();
|
|
// 总手续费
|
|
// 总手续费
|
|
double procedureFee;
|
|
double procedureFee;
|
|
- if ("UNIONPAY".equals(payParam.getPayWay())) {
|
|
|
|
|
|
+ if (12 == orderRelation.getPayType()) {
|
|
procedureFee = 10.00;
|
|
procedureFee = 10.00;
|
|
- } else if ("B2C".equals(payParam.getPayWay())) {
|
|
|
|
|
|
+ } else if (17 == orderRelation.getPayType()) {
|
|
//b2c 0.2%
|
|
//b2c 0.2%
|
|
- procedureFee = MathUtil.mul(payAmount, 0.002, 2).doubleValue();
|
|
|
|
|
|
+ procedureFee = MathUtil.mul(splitAmount, 0.002, 2).doubleValue();
|
|
//b2c最低手续费0.1
|
|
//b2c最低手续费0.1
|
|
if (procedureFee < 0.1) {
|
|
if (procedureFee < 0.1) {
|
|
procedureFee = 0.1;
|
|
procedureFee = 0.1;
|
|
}
|
|
}
|
|
- } else if ("WX".equals(payParam.getPayWay())) {
|
|
|
|
|
|
+ } else if (13 == orderRelation.getPayType() || 15 == orderRelation.getPayType()) {
|
|
//微信0.65%
|
|
//微信0.65%
|
|
- procedureFee = MathUtil.mul(payAmount, 0.0065, 2).doubleValue();
|
|
|
|
- } else if ("DEBIT".equals(payParam.getPayWay())) {
|
|
|
|
- procedureFee = MathUtil.mul(payAmount, 0.003, 2).doubleValue();
|
|
|
|
|
|
+ procedureFee = MathUtil.mul(splitAmount, 0.0065, 2).doubleValue();
|
|
|
|
+ } else if (29 == orderRelation.getPayType()) {
|
|
|
|
+ procedureFee = MathUtil.mul(splitAmount, 0.003, 2).doubleValue();
|
|
if (procedureFee < 0.1) {
|
|
if (procedureFee < 0.1) {
|
|
procedureFee = 0.1;
|
|
procedureFee = 0.1;
|
|
}
|
|
}
|
|
- } else if ("CREDIT".equals(payParam.getPayWay())) {
|
|
|
|
- procedureFee = MathUtil.mul(payAmount, 0.006, 2).doubleValue();
|
|
|
|
|
|
+ } else if (30 == orderRelation.getPayType()) {
|
|
|
|
+ procedureFee = MathUtil.mul(splitAmount, 0.006, 2).doubleValue();
|
|
if (procedureFee < 0.1) {
|
|
if (procedureFee < 0.1) {
|
|
procedureFee = 0.1;
|
|
procedureFee = 0.1;
|
|
}
|
|
}
|
|
} else {
|
|
} else {
|
|
//手续费 其他0.25%
|
|
//手续费 其他0.25%
|
|
- procedureFee = MathUtil.mul(payAmount, 0.0025, 2).doubleValue();
|
|
|
|
|
|
+ procedureFee = MathUtil.mul(splitAmount, 0.0025, 2).doubleValue();
|
|
}
|
|
}
|
|
if (MathUtil.compare(procedureFee, 0.01) <= 0) {
|
|
if (MathUtil.compare(procedureFee, 0.01) <= 0) {
|
|
procedureFee = 0.01;
|
|
procedureFee = 0.01;
|
|
}
|
|
}
|
|
- //手续费承担方 线上支付手续费:默认1采美承担,2供应商承担
|
|
|
|
- Integer supportFlag = newOrderDao.findSupport(shopOrder.getShopOrderId());
|
|
|
|
- //减去收款手续费
|
|
|
|
- splitAmount = MathUtil.sub(splitAmount, procedureFee).doubleValue();
|
|
|
|
-
|
|
|
|
// 商品数据
|
|
// 商品数据
|
|
List<OrderProductVo> orderProductList = newOrderDao.getOrderProductByShopOrderId(shopOrder.getShopOrderId());
|
|
List<OrderProductVo> orderProductList = newOrderDao.getOrderProductByShopOrderId(shopOrder.getShopOrderId());
|
|
-
|
|
|
|
for (OrderProductVo orderProduct : orderProductList) {
|
|
for (OrderProductVo orderProduct : orderProductList) {
|
|
/** 价格 * 数量
|
|
/** 价格 * 数量
|
|
* 前版本为全比例成本,当前版本重新加回固定成本,新增字段cmCostPrice(平台服务费,分帐分采美),organizeCostPrice(组织/集团成本。分帐分组织)
|
|
* 前版本为全比例成本,当前版本重新加回固定成本,新增字段cmCostPrice(平台服务费,分帐分采美),organizeCostPrice(组织/集团成本。分帐分组织)
|
|
* 在此规则下,分帐方式取cop固定成本值。因存在成本修改,不能取cm_sku实时更新成本!
|
|
* 在此规则下,分帐方式取cop固定成本值。因存在成本修改,不能取cm_sku实时更新成本!
|
|
*/
|
|
*/
|
|
- double costPrice = MathUtil.mul(orderProduct.getCostPrice(), orderProduct.getNum(), 2).doubleValue();
|
|
|
|
- double organizePrice = MathUtil.mul(orderProduct.getOrganizeCostPrice(), orderProduct.getNum(), 2).doubleValue();
|
|
|
|
- if (2 == supportFlag) {
|
|
|
|
- //供应商自己承担手续费
|
|
|
|
- costPrice = MathUtil.sub(costPrice, procedureFee).doubleValue();
|
|
|
|
- }
|
|
|
|
- /**
|
|
|
|
- * todo
|
|
|
|
- * 出于兼容性考虑,且多次支付手续费不同,分账方式为循环每次支付记录,
|
|
|
|
- * 当前业务满足子订单支付完成才进行分账,可以循环子订单统计支付金额,
|
|
|
|
- * 进行一次性分账,在当前模式下如果用户分多次支付,精度损失问题较为常见。
|
|
|
|
- */
|
|
|
|
- // 判断是否支付过
|
|
|
|
- Double paidAmount = newOrderDao.getOrderProductPaidAmount(orderProduct.getOrderProductId());
|
|
|
|
- // 支付过金额大于0
|
|
|
|
- if (null != paidAmount && MathUtil.compare(paidAmount, 0) > 0) {
|
|
|
|
- //已付>0,成本-已付
|
|
|
|
- costPrice = MathUtil.sub(costPrice, paidAmount).doubleValue();
|
|
|
|
- }
|
|
|
|
- // 待分账金额>成本
|
|
|
|
- if (MathUtil.compare(splitAmount, costPrice) > 0) {
|
|
|
|
- // 待分账金额-成本
|
|
|
|
- splitAmount = MathUtil.sub(splitAmount, costPrice).doubleValue();
|
|
|
|
- } else {
|
|
|
|
- costPrice = splitAmount;
|
|
|
|
- splitAmount = 0.00;
|
|
|
|
- }
|
|
|
|
- if (costPrice > 0) {
|
|
|
|
- SplitAccountPo splitAccount = new SplitAccountPo();
|
|
|
|
- splitAccount.setShopOrderId(shopOrder.getShopOrderId());
|
|
|
|
- splitAccount.setOrderId(shopOrder.getOrderId());
|
|
|
|
- splitAccount.setOrderProductId(orderProduct.getOrderProductId());
|
|
|
|
- splitAccount.setShopId(orderProduct.getShopId());
|
|
|
|
- splitAccount.setSplitAccount(costPrice);
|
|
|
|
- splitAccount.setProductType(1);
|
|
|
|
- // 该商品设置了商户号
|
|
|
|
- splitAccount.setType(4);
|
|
|
|
- splitAccount.setSubUserNo(shopOrder.getSplitCode());
|
|
|
|
- logger.info("成本分账参数------------->" + splitAccount.toString());
|
|
|
|
- list.add(splitAccount);
|
|
|
|
- }
|
|
|
|
- if (MathUtil.compare(splitAmount, 0) == 0) {
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- // 判断是否支付过组织佣金
|
|
|
|
- Double organizePaid = newOrderDao.getPaidOrganizePrice(orderProduct.getOrderProductId());
|
|
|
|
- // 支付过金额大于0
|
|
|
|
- if (null != organizePaid && MathUtil.compare(organizePaid, 0) > 0) {
|
|
|
|
- //已付>0,组织佣金 - 已付
|
|
|
|
- organizePrice = MathUtil.sub(organizePrice, paidAmount).doubleValue();
|
|
|
|
- }
|
|
|
|
- // 待分账金额>组织佣金
|
|
|
|
- if (MathUtil.compare(splitAmount, organizePrice) > 0) {
|
|
|
|
- // 待分账金额-组织佣金
|
|
|
|
- splitAmount = MathUtil.sub(splitAmount, organizePrice).doubleValue();
|
|
|
|
- } else {
|
|
|
|
- organizePrice = splitAmount;
|
|
|
|
- splitAmount = 0.00;
|
|
|
|
- }
|
|
|
|
- /** 成本分完,金额未尽,有组织佣金的情况,优先组织佣金
|
|
|
|
- * 当前版本,采美供应商上架丽格商城,会存在三成本均>0的情况
|
|
|
|
- * 若无组织佣金,所有剩余金额归于采美佣金
|
|
|
|
- */
|
|
|
|
- if (organizePrice > 0) {
|
|
|
|
- SplitAccountPo splitAccount = new SplitAccountPo();
|
|
|
|
- splitAccount.setShopOrderId(shopOrder.getShopOrderId());
|
|
|
|
- splitAccount.setOrderId(shopOrder.getOrderId());
|
|
|
|
- splitAccount.setOrderProductId(orderProduct.getOrderProductId());
|
|
|
|
- splitAccount.setShopId(orderProduct.getShopId());
|
|
|
|
- splitAccount.setSplitAccount(organizePrice);
|
|
|
|
- splitAccount.setProductType(5);
|
|
|
|
- // 该商品设置了商户号
|
|
|
|
- splitAccount.setType(4);
|
|
|
|
- String code = newOrderDao.findSplitCodeByOrganize(orderProduct.getOrganizeId());
|
|
|
|
- if (StringUtils.isBlank(code)) {
|
|
|
|
- return null;
|
|
|
|
- }
|
|
|
|
- splitAccount.setSubUserNo(code);
|
|
|
|
- logger.info("组织佣金分账参数------------->" + splitAccount.toString());
|
|
|
|
- list.add(splitAccount);
|
|
|
|
- }
|
|
|
|
- if (MathUtil.compare(splitAmount, 0) == 0) {
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
|
|
+ costPrice.updateAndGet(v -> MathUtil.add(v, MathUtil.mul(orderProduct.getCostPrice(), orderProduct.getNum(), 2)).doubleValue());
|
|
|
|
+ organizePrice.updateAndGet(v -> MathUtil.add(v, MathUtil.mul(orderProduct.getOrganizeCostPrice(), orderProduct.getNum(), 2)).doubleValue());
|
|
|
|
+ cmCostPrice.updateAndGet(v -> MathUtil.add(v, MathUtil.mul(orderProduct.getCmCostPrice(), orderProduct.getNum(), 2)).doubleValue());
|
|
}
|
|
}
|
|
- /** 当前版本还要考虑分组织/集团佣金
|
|
|
|
- * 如果还有钱则为佣金,分到网络
|
|
|
|
- */
|
|
|
|
- if (MathUtil.compare(splitAmount, 0) > 0) {
|
|
|
|
- // 此处不考虑手续费,外部计算总额
|
|
|
|
- SplitAccountPo splitAccount = new SplitAccountPo();
|
|
|
|
- splitAccount.setOrderId(shopOrder.getOrderId());
|
|
|
|
- splitAccount.setShopOrderId(shopOrder.getShopOrderId());
|
|
|
|
- splitAccount.setSplitAccount(splitAmount);
|
|
|
|
- splitAccount.setProductType(3);
|
|
|
|
- splitAccount.setType(5);
|
|
|
|
- splitAccount.setSubUserNo(Constant.CUSTOMERNUM2);
|
|
|
|
- logger.info("佣金分账参数------------->" + splitAccount);
|
|
|
|
- list.add(splitAccount);
|
|
|
|
|
|
+ //手续费承担方 线上支付手续费:默认1采美承担,2供应商承担
|
|
|
|
+ Integer supportFlag = newOrderDao.findSupport(shopOrder.getShopOrderId());
|
|
|
|
+ if (2 == supportFlag) {
|
|
|
|
+ //供应商自己承担手续费
|
|
|
|
+ costPrice.set(costPrice.get() - procedureFee);
|
|
}
|
|
}
|
|
- return list;
|
|
|
|
}
|
|
}
|
|
|
|
|
|
public <T> T postForm(Map<String, String> params, String url, String sign, Class<T> clazz) {
|
|
public <T> T postForm(Map<String, String> params, String url, String sign, Class<T> clazz) {
|