v1.0.45 #57
@@ -16,6 +16,9 @@ public interface GaoOrderPaymentService {
|
|||||||
/// 登记收款
|
/// 登记收款
|
||||||
GaoFundRecord receive(GaoOrderPaymentReceiveRequest request);
|
GaoFundRecord receive(GaoOrderPaymentReceiveRequest request);
|
||||||
|
|
||||||
|
/// 登记已收款并直接核销
|
||||||
|
GaoFundRecord receiveAndVerify(GaoOrderPaymentReceiveRequest request);
|
||||||
|
|
||||||
/// 核销收款
|
/// 核销收款
|
||||||
GaoFundRecord verify(String fundRecordId);
|
GaoFundRecord verify(String fundRecordId);
|
||||||
|
|
||||||
|
|||||||
+30
-5
@@ -49,10 +49,17 @@ public class GaoOrderPaymentServiceImplement implements GaoOrderPaymentService {
|
|||||||
@Transactional(TimiServerDBConfig.ROLLBACKER)
|
@Transactional(TimiServerDBConfig.ROLLBACKER)
|
||||||
@Override
|
@Override
|
||||||
public GaoFundRecord receive(GaoOrderPaymentReceiveRequest request) {
|
public GaoFundRecord receive(GaoOrderPaymentReceiveRequest request) {
|
||||||
return receiveInternal(request);
|
return receiveInternal(request, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private GaoFundRecord receiveInternal(GaoOrderPaymentReceiveRequest request) {
|
@OperationAudit(AuditOperation.GAO_SALES_ORDER_PAYMENT_RECEIVE)
|
||||||
|
@Transactional(TimiServerDBConfig.ROLLBACKER)
|
||||||
|
@Override
|
||||||
|
public GaoFundRecord receiveAndVerify(GaoOrderPaymentReceiveRequest request) {
|
||||||
|
return receiveInternal(request, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private GaoFundRecord receiveInternal(GaoOrderPaymentReceiveRequest request, boolean verified) {
|
||||||
TimiException.required(request, "not found order payment request");
|
TimiException.required(request, "not found order payment request");
|
||||||
TimiException.required(request.getSalesOrderId(), "not found salesOrderId");
|
TimiException.required(request.getSalesOrderId(), "not found salesOrderId");
|
||||||
TimiException.required(request.getAmount(), "收款金额不能为空");
|
TimiException.required(request.getAmount(), "收款金额不能为空");
|
||||||
@@ -62,7 +69,7 @@ public class GaoOrderPaymentServiceImplement implements GaoOrderPaymentService {
|
|||||||
GaoFundRecord existing = fundRecordService.getByRequestNo(order.getStoreId(), requestNo);
|
GaoFundRecord existing = fundRecordService.getByRequestNo(order.getStoreId(), requestNo);
|
||||||
if (existing != null) {
|
if (existing != null) {
|
||||||
verifySameReceive(existing, order, request);
|
verifySameReceive(existing, order, request);
|
||||||
return existing;
|
return verified && existing.getStatus() == GaoFundRecord.Status.PENDING ? verify(existing.getId()) : existing;
|
||||||
}
|
}
|
||||||
TimiException.requiredTrue(order.getStatus() != GaoSalesOrder.Status.CANCELLED, "已取消订单不能收款");
|
TimiException.requiredTrue(order.getStatus() != GaoSalesOrder.Status.CANCELLED, "已取消订单不能收款");
|
||||||
TimiException.requiredTrue(order.getRefundStatus() != GaoSalesOrder.RefundStatus.REFUNDED, "已完成退款订单不能收款");
|
TimiException.requiredTrue(order.getRefundStatus() != GaoSalesOrder.RefundStatus.REFUNDED, "已完成退款订单不能收款");
|
||||||
@@ -71,9 +78,27 @@ public class GaoOrderPaymentServiceImplement implements GaoOrderPaymentService {
|
|||||||
TimiException.requiredTrue(pending + paid + request.getAmount() <= safe(order.getSaleAmount()), "累计收款不能超过成交价");
|
TimiException.requiredTrue(pending + paid + request.getAmount() <= safe(order.getSaleAmount()), "累计收款不能超过成交价");
|
||||||
TimiException.requiredTrue(hasPhoto(request.getAttachmentList()), "收款必须上传照片");
|
TimiException.requiredTrue(hasPhoto(request.getAttachmentList()), "收款必须上传照片");
|
||||||
GaoFundRecord record = newRecord(order, GaoFundRecord.OperationType.RECEIVE, requestNo, request.getAmount(), request.getOccurredAt(), request.getRemark());
|
GaoFundRecord record = newRecord(order, GaoFundRecord.OperationType.RECEIVE, requestNo, request.getAmount(), request.getOccurredAt(), request.getRemark());
|
||||||
record.setStatus(GaoFundRecord.Status.PENDING);
|
record.setStatus(verified ? GaoFundRecord.Status.VERIFIED : GaoFundRecord.Status.PENDING);
|
||||||
|
String verifierUserId = verified ? userLoginService.getRequireLoginUserId() : null;
|
||||||
|
Long verifiedAt = verified ? Time.now() : null;
|
||||||
|
if (verified) {
|
||||||
|
record.setVerifierUserId(verifierUserId);
|
||||||
|
record.setVerifiedAt(verifiedAt);
|
||||||
|
}
|
||||||
fundRecordService.createByOrderPayment(record);
|
fundRecordService.createByOrderPayment(record);
|
||||||
order.setPendingPaidAmount(pending + request.getAmount());
|
if (!verified) {
|
||||||
|
order.setPendingPaidAmount(pending + request.getAmount());
|
||||||
|
} else {
|
||||||
|
Long paidAtBefore = order.getPaidAt();
|
||||||
|
order.setPaidAmount(paid + request.getAmount());
|
||||||
|
orderService.recomputePaymentStatus(order);
|
||||||
|
orderService.updatePayment(order);
|
||||||
|
if (paidAtBefore == null && order.getPaidAt() != null) {
|
||||||
|
pointTriggerService.onSalesOrderPaid(order);
|
||||||
|
}
|
||||||
|
attachmentService.updateByBizId(Attachment.BizType.GAO_FUND_RECORD, record.getId(), request.getAttachmentList());
|
||||||
|
return record;
|
||||||
|
}
|
||||||
orderService.recomputePaymentStatus(order);
|
orderService.recomputePaymentStatus(order);
|
||||||
orderService.updatePayment(order);
|
orderService.updatePayment(order);
|
||||||
attachmentService.updateByBizId(Attachment.BizType.GAO_FUND_RECORD, record.getId(), request.getAttachmentList());
|
attachmentService.updateByBizId(Attachment.BizType.GAO_FUND_RECORD, record.getId(), request.getAttachmentList());
|
||||||
|
|||||||
+32
-6
@@ -43,29 +43,39 @@ public class GaoOrderStraightThroughServiceImplement implements GaoOrderStraight
|
|||||||
if (straightThrough == null) {
|
if (straightThrough == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
boolean paymentVerified = Boolean.TRUE.equals(straightThrough.getPaymentVerified());
|
||||||
boolean receiveFullPayment = Boolean.TRUE.equals(straightThrough.getReceiveFullPayment());
|
boolean receiveFullPayment = Boolean.TRUE.equals(straightThrough.getReceiveFullPayment());
|
||||||
boolean fulfillAll = Boolean.TRUE.equals(straightThrough.getFulfillAll());
|
boolean fulfillAll = Boolean.TRUE.equals(straightThrough.getFulfillAll());
|
||||||
if (!receiveFullPayment && !fulfillAll) {
|
Long paymentAmount = paymentVerified ? straightThrough.getPaymentAmount() : order.getSaleAmount();
|
||||||
|
if (!paymentVerified && !receiveFullPayment && !fulfillAll) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
TimiException.required(order, "not found sales order");
|
TimiException.required(order, "not found sales order");
|
||||||
TimiException.required(order.getId(), "not found salesOrderId");
|
TimiException.required(order.getId(), "not found salesOrderId");
|
||||||
TimiException.requiredTrue(!fulfillAll || receiveFullPayment || order.getSaleAmount() == 0,
|
TimiException.requiredTrue(!(paymentVerified && receiveFullPayment), "已核销收款和已全额收款和核销不能同时启用");
|
||||||
"全部履约直通必须同时直接全额收款");
|
if (paymentVerified) {
|
||||||
checkPermissions(order.getOrderType(), receiveFullPayment, fulfillAll);
|
TimiException.required(paymentAmount, "已核销收款金额不能为空");
|
||||||
|
TimiException.requiredTrue(0 < paymentAmount && paymentAmount <= safe(order.getSaleAmount()), "已核销收款金额不能超过订单金额");
|
||||||
|
}
|
||||||
|
TimiException.requiredTrue(!fulfillAll || receiveFullPayment || order.getSaleAmount() == 0
|
||||||
|
|| (paymentVerified && paymentAmount.equals(order.getSaleAmount())),
|
||||||
|
"全部履约直通必须同时完成收款核销");
|
||||||
|
checkPermissions(order.getOrderType(), paymentVerified || receiveFullPayment, fulfillAll);
|
||||||
if (receiveFullPayment) {
|
if (receiveFullPayment) {
|
||||||
settle(order, straightThrough);
|
settle(order, straightThrough);
|
||||||
|
} else if (paymentVerified) {
|
||||||
|
verifyReceivedPayment(order, straightThrough, paymentAmount);
|
||||||
}
|
}
|
||||||
if (fulfillAll) {
|
if (fulfillAll) {
|
||||||
fulfill(order, straightThrough);
|
fulfill(order, straightThrough);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkPermissions(GaoSalesOrder.OrderType orderType, boolean receiveFullPayment, boolean fulfillAll) {
|
private void checkPermissions(GaoSalesOrder.OrderType orderType, boolean paymentCompleted, boolean fulfillAll) {
|
||||||
List<String> permissionCodeList = new ArrayList<>();
|
List<String> permissionCodeList = new ArrayList<>();
|
||||||
permissionCodeList.add(orderType == GaoSalesOrder.OrderType.PACKAGE
|
permissionCodeList.add(orderType == GaoSalesOrder.OrderType.PACKAGE
|
||||||
? GaoPermissionCode.CUSTOMER_PACKAGE_CREATE.getValue() : GaoPermissionCode.SALES_ORDER_CREATE.getValue());
|
? GaoPermissionCode.CUSTOMER_PACKAGE_CREATE.getValue() : GaoPermissionCode.SALES_ORDER_CREATE.getValue());
|
||||||
if (receiveFullPayment) {
|
if (paymentCompleted) {
|
||||||
permissionCodeList.add(GaoPermissionCode.FUND_RECEIVE_CREATE.getValue());
|
permissionCodeList.add(GaoPermissionCode.FUND_RECEIVE_CREATE.getValue());
|
||||||
permissionCodeList.add(GaoPermissionCode.FUND_RECEIVE_VERIFY.getValue());
|
permissionCodeList.add(GaoPermissionCode.FUND_RECEIVE_VERIFY.getValue());
|
||||||
}
|
}
|
||||||
@@ -95,6 +105,18 @@ public class GaoOrderStraightThroughServiceImplement implements GaoOrderStraight
|
|||||||
TimiException.requiredTrue(record.getStatus() == GaoFundRecord.Status.VERIFIED, "直通收款记录不是已核销状态");
|
TimiException.requiredTrue(record.getStatus() == GaoFundRecord.Status.VERIFIED, "直通收款记录不是已核销状态");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void verifyReceivedPayment(GaoSalesOrder order, GaoOrderStraightThroughRequest straightThrough, Long paymentAmount) {
|
||||||
|
GaoOrderPaymentReceiveRequest paymentRequest = new GaoOrderPaymentReceiveRequest();
|
||||||
|
paymentRequest.setSalesOrderId(order.getId());
|
||||||
|
paymentRequest.setRequestNo("ORDER-%s-VERIFIED-PAY".formatted(order.getId()));
|
||||||
|
paymentRequest.setAmount(paymentAmount);
|
||||||
|
paymentRequest.setOccurredAt(TimiJava.defaultIfNull(straightThrough.getPaymentOccurredAt(), order.getPurchasedAt()));
|
||||||
|
paymentRequest.setAttachmentList(straightThrough.getPaymentAttachmentList());
|
||||||
|
paymentRequest.setRemark(TimiJava.defaultIfEmpty(straightThrough.getPaymentRemark(), "随订单创建直接核销已有收款"));
|
||||||
|
GaoFundRecord record = paymentService.receiveAndVerify(paymentRequest);
|
||||||
|
TimiException.requiredTrue(record.getStatus() == GaoFundRecord.Status.VERIFIED, "直通收款记录不是已核销状态");
|
||||||
|
}
|
||||||
|
|
||||||
private void fulfill(GaoSalesOrder order, GaoOrderStraightThroughRequest straightThrough) {
|
private void fulfill(GaoSalesOrder order, GaoOrderStraightThroughRequest straightThrough) {
|
||||||
List<GaoSalesOrderItem> orderItemList = order.getItemList();
|
List<GaoSalesOrderItem> orderItemList = order.getItemList();
|
||||||
TimiException.requiredTrue(orderItemList != null && !orderItemList.isEmpty(), "销售订单没有可履约明细");
|
TimiException.requiredTrue(orderItemList != null && !orderItemList.isEmpty(), "销售订单没有可履约明细");
|
||||||
@@ -126,4 +148,8 @@ public class GaoOrderStraightThroughServiceImplement implements GaoOrderStraight
|
|||||||
request.setFulfillmentId(fulfillmentId);
|
request.setFulfillmentId(fulfillmentId);
|
||||||
return request;
|
return request;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private long safe(Long value) {
|
||||||
|
return value == null ? 0L : value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,12 @@ import java.util.List;
|
|||||||
@Data
|
@Data
|
||||||
public class GaoOrderStraightThroughRequest {
|
public class GaoOrderStraightThroughRequest {
|
||||||
|
|
||||||
|
/// true 为已有收款并直接核销
|
||||||
|
private Boolean paymentVerified;
|
||||||
|
|
||||||
|
/// 已核销收款金额,单位分
|
||||||
|
private Long paymentAmount;
|
||||||
|
|
||||||
/// true 为直接全额收款并核销
|
/// true 为直接全额收款并核销
|
||||||
private Boolean receiveFullPayment;
|
private Boolean receiveFullPayment;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user