Przeglądaj źródła

[POS][修改]:卡消费支持pos, 预支付及预支付取消

release_toaliyun_real
Stormeye Wu 6 lat temu
rodzic
commit
1b5fd04c55
14 zmienionych plików z 489 dodań i 11 usunięć
  1. +2
    -0
      mallinkAdmin/src/main/resources/db/migration/V201908150940__POS_CHANGED.sql
  2. +6
    -0
      mallinkAdmin/src/main/resources/db/migration/V201908151120__POS_CAR_SPEND.sql
  3. +74
    -0
      mallinkPosApi/src/main/java/com/iformall/controller/PosController.java
  4. +16
    -0
      mallinkPosApi/src/main/java/com/iformall/service/PosService.java
  5. +132
    -0
      mallinkPosApi/src/main/java/com/iformall/service/impl/PosServiceImpl.java
  6. +3
    -0
      mallinkService/src/main/java/com/iformall/common/ErrorCode.java
  7. +9
    -1
      mallinkService/src/main/java/com/iformall/domain/po/WxCardSpend.java
  8. +39
    -0
      mallinkService/src/main/java/com/iformall/enums/EnumCardSpendFrom.java
  9. +3
    -2
      mallinkService/src/main/java/com/iformall/enums/EnumCardSpendStatus.java
  10. +4
    -1
      mallinkService/src/main/java/com/iformall/mapper/WxCardSpendMapper.java
  11. +4
    -0
      mallinkService/src/main/java/com/iformall/pay/WxPayConstant.java
  12. +6
    -1
      mallinkService/src/main/java/com/iformall/service/WxCardSpendService.java
  13. +171
    -4
      mallinkService/src/main/java/com/iformall/service/impl/WxCardSpendServiceImpl.java
  14. +20
    -2
      mallinkService/src/main/resources/mapper/WxCardSpendMapper.xml

+ 2
- 0
mallinkAdmin/src/main/resources/db/migration/V201908150940__POS_CHANGED.sql Wyświetl plik

@@ -0,0 +1,2 @@
alter table pos_mall_config
add column `card` tinyint(6) NOT NULL DEFAULT '0' COMMENT '会员优惠券状态,0-使用中,1-禁用';

+ 6
- 0
mallinkAdmin/src/main/resources/db/migration/V201908151120__POS_CAR_SPEND.sql Wyświetl plik

@@ -0,0 +1,6 @@
ALTER TABLE `wx_card_spend`
ADD `from` tinyint(6) NOT NULL DEFAULT '0' COMMENT '来源(0:C端小程序扫一扫, 1:B端POS, 2:东软POS)',
ADD `pos_refund_status` tinyint(6) NULL COMMENT 'pos状态(1:POS线下退款开始, 2:POS线下退款成功)',
ADD COLUMN `pos_order_id` bigint(20) NULL COMMENT 'POS订单账号',
CHANGE COLUMN `ip` `ip` varchar(20) COMMENT 'ip地址',
CHANGE COLUMN `pay_status` `pay_status` smallint(2) NOT NULL DEFAULT 0 COMMENT '支付状态(0:未分帐, 1:已分账, 2:已人工分账, 10:预支付(POS))';

+ 74
- 0
mallinkPosApi/src/main/java/com/iformall/controller/PosController.java Wyświetl plik

@@ -388,6 +388,80 @@ public class PosController extends BaseController {
}
}

@ApiOperation(value = "消费卡支付接口", notes = "{" +
"\"dev_id\":\"string(必填)\"," +
"\"tenant_id\":\"string(必填)\"," +
"\"merchant_id\":\"string(必填)\"," +
"\"bu_user_id\":\"string(必填)\"," +
"\"nonce_str\":\"string(必填)\"," +
"\"pos_order_id\":\"string(必填)\"," +
"\"pos_amount\":\"string(必填)\"," +
"\"card_id\":\"string(必填)\" }")
@PostMapping("/cardPay")
public Map<String, String> cardPay(@RequestBody Map<String, String> params) {
JSONObject payContent = new JSONObject();

// 1. check sign
Map<String, String> retMap = checkSign(params, payContent);
if (retMap != null) {
// 签名相关异常返回
return retMap;
}
String resKey = payContent.getString("resKey");
logger.info("resKey: " + resKey);

try {
retMap = posService.cardPay(params);
return buildReturnMap(retMap, resKey, WxPayConstant.RET_SUCCESS, "",
WxPayConstant.RET_SUCCESS, null);
} catch (MallinkException e) {
return buildReturnMap(retMap, resKey, WxPayConstant.RET_SUCCESS, "",
WxPayConstant.RET_FAIL,
e.getErrorCode(), e.getMessage());
} catch (Exception e) {
return buildReturnMap(retMap, resKey, WxPayConstant.RET_SUCCESS, "",
WxPayConstant.RET_FAIL,
500, e.getMessage());
}
}

@ApiOperation(value = "卡支付取消", notes = "{" +
"\"dev_id\":\"string(必填)\"," +
"\"tenant_id\":\"string(必填)\"," +
"\"merchant_id\":\"string(必填)\"," +
"\"bu_user_id\":\"string(必填)\"," +
"\"pos_order_id\":\"string(必填)\"," +
"\"coupon_order_id\":\"string(必填)\"" +
"\"nonce_str\":\"string(必填)\"," +
"\"force\":\"string(选填true/false)\" }")
@PostMapping("/cardPayCancel")
public Map<String, String> cardPayCancel(@RequestBody Map<String, String> params) {
JSONObject payContent = new JSONObject();

// 1. check sign
Map<String, String> retMap = checkSign(params, payContent);
if (retMap != null) {
// 签名相关异常返回
return retMap;
}
String resKey = payContent.getString("resKey");
logger.info("resKey: " + resKey);

try {
retMap = posService.cardPayCancel(params);
return buildReturnMap(retMap, resKey, WxPayConstant.RET_SUCCESS, "",
WxPayConstant.RET_SUCCESS, null);
} catch (MallinkException e) {
return buildReturnMap(retMap, resKey, WxPayConstant.RET_SUCCESS, "",
WxPayConstant.RET_FAIL,
e.getErrorCode(), e.getMessage());
} catch (Exception e) {
return buildReturnMap(retMap, resKey, WxPayConstant.RET_SUCCESS, "",
WxPayConstant.RET_FAIL,
500, e.getMessage());
}
}


/**
* 构造返回map,无签名, 有错误


+ 16
- 0
mallinkPosApi/src/main/java/com/iformall/service/PosService.java Wyświetl plik

@@ -55,4 +55,20 @@ public interface PosService {
* @throws MallinkException
*/
Map<String, String> couponOrderVerifyListDo(@RequestBody Map<String, String> params, EnumVerifyActionType actionType) throws MallinkException;

/**
* 消费卡POS支付
* @param params
* @return
* @throws MallinkException
*/
Map<String, String> cardPay(@RequestBody Map<String, String> params) throws MallinkException;

/**
* 消费卡POS支付取消
* @param params
* @return
* @throws MallinkException
*/
Map<String, String> cardPayCancel(@RequestBody Map<String, String> params) throws MallinkException;
}

+ 132
- 0
mallinkPosApi/src/main/java/com/iformall/service/impl/PosServiceImpl.java Wyświetl plik

@@ -44,6 +44,8 @@ public class PosServiceImpl implements PosService {
private final PosCouponOrderVerifyService posCouponOrderVerifyService;
private final WxScoreRulesService scoreRulesService;
private final WxCreditHistoryService creditHistoryService;
private final WxCardInfoService cardInfoService;
private final WxCardSpendService cardSpendService;

private final WxOrderMapper orderMapper;
private final WxCouponOrderMapper couponOrderMapper;
@@ -1148,4 +1150,134 @@ public class PosServiceImpl implements PosService {
}
logger.info("核销已取消: " + couponOrderCVo.getId());
}

@Override
@Transactional(rollbackFor = Exception.class)
public Map<String, String> cardPay(@RequestBody Map<String, String> params) throws MallinkException {
Map<String, String> retMap = new HashMap<>();

String tenantId = params.get(WxPayConstant.TENANT_ID); // 租户ID
String merchantIdStr = params.get(WxPayConstant.MERCHANT_ID); // 商户ID
String buUserIdStr = params.get(WxPayConstant.BUSER_ID); // POS操作员ID
String posOrderIdStr = params.get(WxPayConstant.POS_ORDER_ID); // POS订单ID
String posAmountStr = params.get(WxPayConstant.POS_AMOUNT); // POS订单总额(单位:分)
String cardIdStr = params.get(WxPayConstant.CARD_ID); // 消费卡ID

if (StringUtils.isBlank(tenantId)) {
String errMessage = "request params[tenant_id] error.";
logger.error(errMessage);
throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), errMessage);
}
PosMallConfig config = posMallConfigService.getByTenantId(tenantId);
if (config == null) {
logger.error(ErrorCode.POS_CONFIG_NOT_FOUND.getMessage());
throw new MallinkException(ErrorCode.POS_CONFIG_NOT_FOUND);
}
if (!config.getCoupon().equals(EnumEnableType.Enable.getCode())) {
logger.error(ErrorCode.POS_CONFIG_MEM_COUPON_DISABLE.getMessage());
throw new MallinkException(ErrorCode.POS_CONFIG_MEM_COUPON_DISABLE);
}
if (StringUtils.isBlank(merchantIdStr)) {
String errMessage = "request params[merchant_id] error.";
logger.error(errMessage);
throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), errMessage);
}
if (StringUtils.isBlank(buUserIdStr)) {
String errMessage = "request params[bu_user_id] error.";
throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), errMessage);
}
if (StringUtils.isBlank(posOrderIdStr)) {
String errMessage = "request params[pos_order_id] error.";
throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), errMessage);
}
if (StringUtils.isBlank(posAmountStr)) {
String errMessage = "request params[pos_amount] error.";
throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), errMessage);
}
if (StringUtils.isBlank(cardIdStr)) {
String errMessage = "request params[coupon_order_id] error.";
throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL.getCode(), errMessage);
}

Long merchantId, buUserId, posOrderId, cardId;
Integer posAmount = 0;
try {
merchantId = Long.valueOf(merchantIdStr);
buUserId = Long.valueOf(buUserIdStr);
posOrderId = Long.valueOf(posOrderIdStr);
posAmount = Integer.valueOf(posAmountStr);
cardId = Long.valueOf(cardIdStr);
} catch (NumberFormatException e) {
logger.error(e.getMessage());
throw new MallinkException(ErrorCode.SYS_PARAMETER_CAST_ERROR.getCode(), e.getMessage());
}
WxCardInfo cardInfo = cardInfoService.getById(cardId);
if(cardInfo == null) {
String errMessage = "卡不存在: " + cardIdStr;
logger.error(errMessage);
throw new MallinkException(ErrorCode.CARD_IS_NOT_FOUND.getCode(), errMessage);
}
WxCouponMerchant couponMerchant = cardSpendService.checkMerchantInCoupon(cardInfo, merchantId);
if(couponMerchant == null) {
String errMessage = "商户不支持此卡 " + cardIdStr;
logger.error(errMessage);
throw new MallinkException(ErrorCode.COUPON_ORDER_MERANT_IS_NULL.getCode(), errMessage);
}
// 2. check merchant
WxMerchant merchant = merchantService.getById(merchantId);
if (merchant == null) {
logger.error(ErrorCode.MERCHANT_INFO_NOT_FOUND.getMessage() + ": " + merchantIdStr);
throw new MallinkException(ErrorCode.MERCHANT_INFO_NOT_FOUND);
}
if (merchant.getIsDel().equals(EnumDelStatus.DEL.getCode()) || merchant.getStatus().equals(EnumMerchantStatus.NOT_VALID.getCode())) {
logger.error(ErrorCode.MERCHANT_INFO_NOT_VALID.getMessage() + ": " + merchantIdStr);
throw new MallinkException(ErrorCode.MERCHANT_INFO_NOT_VALID);
}
// 3. check buUser
WxMerchantBUser buUser = merchantBUserService.getById(buUserId);
if (buUser == null) {
logger.error(ErrorCode.USER_IS_EMPTY.getMessage() + ": " + buUserIdStr);
throw new MallinkException(ErrorCode.USER_IS_EMPTY);
}
if (!buUser.getMerchantId().equals(merchantId)) {
logger.error(ErrorCode.VERIFY_BUSER_MERCHANT_NOT_BELONG.getMessage() + ": " + buUserIdStr);
throw new MallinkException(ErrorCode.VERIFY_BUSER_MERCHANT_NOT_BELONG);
}

WxCouponOrder couponOrder = couponOrderService.getById(cardId);
if(couponOrder == null) {
logger.error("卡不存在: " + cardIdStr);
throw new MallinkException(ErrorCode.CARD_IS_NOT_FOUND);
}

if(posAmount > cardInfo.getRemainingAmount()) {
logger.error("卡余额不足: " + cardIdStr);
throw new MallinkException(ErrorCode.CARD_REMAIN_AMOUNT_IS_NOT_ENOUGH);
}
WxCardSpend record = new WxCardSpend();
record.setTenantId(merchant.getTenantId());
record.setCardId(cardId);
record.setOwnerId(couponOrder.getOwnerId());
record.setMerchantId(merchantId);
record.setOrderId(posOrderId);
record.setDeductionAmount(posAmount);

try {
//return cardSpendService.createCardSpend(record, order, couponMerchant);
} catch (MallinkException e) {
logger.error("card spend error, req 2: " + record.toString() + ", e:" + e.getMessage());
throw new MallinkException(e.getErrorCode(), e.getMessage());
} catch (Exception e) {
logger.error("card spend error, req 3: " + record.toString() + ", e:" + e.getMessage());
throw new MallinkException(500, e.getMessage());
}
retMap.put(WxPayConstant.RET, "");
return retMap;
}

@Override
@Transactional(rollbackFor = Exception.class)
public Map<String, String> cardPayCancel(@RequestBody Map<String, String> params) throws MallinkException {
return null;
}
}

+ 3
- 0
mallinkService/src/main/java/com/iformall/common/ErrorCode.java Wyświetl plik

@@ -27,6 +27,7 @@ public enum ErrorCode{
SYS_EXTEND_JSON_ERROR(1012, "JSON格式异常"),
SYS_REPEAT_SUBMIT_EXCEPTION(1013, "请勿重复操作"),
REPORT_TYPE_UNKNOWN(1014, "不支持的报表类型"),
SYS_MCH_NOT_FOUND(1015, "微信商户号未找到"),

/**
* 菜单
@@ -198,11 +199,13 @@ public enum ErrorCode{
CARD_IS_NOT_COST(9003, "优惠卡未消费,退款请用卡券退款,钱直接退回购买人手里"),
CARD_TRANSFERED(9004, "卡已被领取"),
CARD_TRANSFER_INVALID(9005, "卡转赠已失效"),
CARD_SUBSIDY_NOT_SET(9006, "卡补贴未设置"),

/**
* 卡消费
*/
CARD_SPEND_IS_PAID(9050, "卡消费已支付"),
CARD_SPEND_IS_NOT_PREV(9051, "卡消费不是预消费订单"),

/**
* 砍价


+ 9
- 1
mallinkService/src/main/java/com/iformall/domain/po/WxCardSpend.java Wyświetl plik

@@ -35,6 +35,8 @@ public class WxCardSpend extends BaseEntity {
@Excel(name = "订单号", width = 20, orderNum = "5")
@io.swagger.annotations.ApiModelProperty(value="订单账号",name="orderId")
private Long orderId;
@io.swagger.annotations.ApiModelProperty(value="POS订单账号",name="posOrderId")
private Long posOrderId;
@io.swagger.annotations.ApiModelProperty(value="ip地址",name="ip")
private String ip;
@io.swagger.annotations.ApiModelProperty(value="抵扣金额",name="deductionAmount")
@@ -60,9 +62,15 @@ public class WxCardSpend extends BaseEntity {
private Date updateDate;

@Excel(name = "支付状态", width = 20, orderNum = "11", replace = {"未支付_0", "已分账_1", "已人工分账_2"})
@io.swagger.annotations.ApiModelProperty(value="支付状态(0:未分帐, 1:已分账, 2:已人工分账)",name="payStatus")
@io.swagger.annotations.ApiModelProperty(value="支付状态(0:未分帐, 1:已分账, 2:已人工分账, 10:预支付(POS))",name="payStatus")
private Integer payStatus;

@io.swagger.annotations.ApiModelProperty(value="来源(0:C端小程序扫一扫, 1:B端POS, 2:东软POS)",name="from")
private Integer from;

@io.swagger.annotations.ApiModelProperty(value="pos状态(1:POS线下退款开始, 2:POS线下退款成功)",name="posRefundStatus")
private Integer posRefundStatus;

@Transient
@Excel(name = "消费金额(元)", width = 20, orderNum = "7")
private String deductionAmountStr;


+ 39
- 0
mallinkService/src/main/java/com/iformall/enums/EnumCardSpendFrom.java Wyświetl plik

@@ -0,0 +1,39 @@
package com.iformall.enums;

/**
* Created by Stormeye on 2018/08/09.
*/
public enum EnumCardSpendFrom {

// 0:C端小程序扫一扫, 1:B端POS, 2:东软POS

C(0, "支付"),
POS_B(1, "B端POS"),
POS_NEUSOFT(2, "东软POS"),
;

public static EnumCardSpendFrom getEnum(Integer code) {
for (EnumCardSpendFrom value : values()) {
if (value.getCode().equals(code)) {
return value;
}
}
return null;
}

private Integer code;
private String message;

EnumCardSpendFrom(Integer code, String message) {
this.code = code;
this.message = message;
}

public Integer getCode() {
return code;
}

public String getMessage() {
return message;
}
}

+ 3
- 2
mallinkService/src/main/java/com/iformall/enums/EnumCardSpendStatus.java Wyświetl plik

@@ -7,9 +7,10 @@ public enum EnumCardSpendStatus {

// 0-未支付;1-已分账;2:已人工分账;

NOT_PAY(0, "未支付"),
NOT_PAY(0, "未支付,开始记录"),
PS_SHARED(1, "已分账"),
MANUAL_PAY(2, "已人工分账")
MANUAL_PAY(2, "已人工分账"),
PREV_PAY(10, "预支付(POS短期内占用)"),
;

public static EnumCardSpendStatus getEnum(Integer code) {


+ 4
- 1
mallinkService/src/main/java/com/iformall/mapper/WxCardSpendMapper.java Wyświetl plik

@@ -22,7 +22,10 @@ public interface WxCardSpendMapper extends CommonMapper<WxCardSpend, Long> {

List<Map<String,Object>> sumCardSpendVoForOwner(WxCardSpendVo wxCardSpend);

/**
* POS
*/
int deleteForPrevCancel(WxCardSpend record);
}

+ 4
- 0
mallinkService/src/main/java/com/iformall/pay/WxPayConstant.java Wyświetl plik

@@ -31,6 +31,8 @@ public class WxPayConstant {
public final static String VERIFY_INDEPENT = "independent";
public final static String VERIFY_PAY = "pay";

public final static String CARD_ID = "card_id";

public final static String REG_QRCODE_URL = "qrcode_url";
public final static String POS_QRCODE_RULE = "pos_qrcode_rule";

@@ -49,4 +51,6 @@ public class WxPayConstant {

public final static String ORG_AMOUNT = "org_amount";

public final static String RET = "ret";

}

+ 6
- 1
mallinkService/src/main/java/com/iformall/service/WxCardSpendService.java Wyświetl plik

@@ -4,6 +4,7 @@ import com.github.pagehelper.PageInfo;
import com.iformall.common.ResultData;
import com.iformall.domain.po.*;
import com.iformall.domain.vo.WxCardSpendVo;
import com.iformall.exception.MallinkException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -102,5 +103,9 @@ public interface WxCardSpendService {
*/
void exportData(WxCardSpendVo wxCardSpendVo, HttpServletRequest request, HttpServletResponse response);


/**
* POS 卡支付相关接口
*/
void cardSpendForPosPrePay(WxCardSpend record) throws MallinkException;
void cardSpendForPosPrePayCancel(WxCardSpend record) throws MallinkException;
}

+ 171
- 4
mallinkService/src/main/java/com/iformall/service/impl/WxCardSpendServiceImpl.java Wyświetl plik

@@ -127,7 +127,6 @@ public class WxCardSpendServiceImpl implements WxCardSpendService {
int iChargeFee = PayUtils.getPayRate(payment, payAccount.getRate());
Integer real_payment = payment - iChargeFee;
Integer remain_real_pament = cardInfo.getRemainingShareFeeAmount() - real_payment;

Integer remaingAmount = cardInfo.getRemainingAmount()-record.getDeductionAmount();
if(remaingAmount.equals(0)) {
// 最后一次支付时
@@ -137,6 +136,8 @@ public class WxCardSpendServiceImpl implements WxCardSpendService {

// 5 insert card_spend
record.setId(idWorker.nextId());
record.setTenantId(cardInfo.getTenantId());
record.setFrom(EnumCardSpendFrom.C.getCode());
record.setPayment(payment);
record.setRealPayment(real_payment);
record.setCardBeforeAmount(cardInfo.getRemainingAmount());
@@ -180,7 +181,7 @@ public class WxCardSpendServiceImpl implements WxCardSpendService {
}
// 7.1 update coupon card status
if(cardInfo.getRemainingAmount().equals(0)) {
if (cardFinished(order, curDate, cardInfo)) {
if (cardFinished(curDate, cardInfo)) {
return new ResultData(ErrorCode.DB_FAIL.getCode(), "couponOrder status 更新出错!");
}
}
@@ -279,11 +280,16 @@ public class WxCardSpendServiceImpl implements WxCardSpendService {
return new ResultData(record);
}

private boolean cardFinished(WxOrder order, Date curDate, WxCardInfo cardInfo) {
/**
* 卡已用完
* @param curDate
* @param cardInfo
* @return
*/
private boolean cardFinished(Date curDate, WxCardInfo cardInfo) {
WxCouponOrder couponOrder = new WxCouponOrder();
couponOrder.setId(cardInfo.getId());
couponOrder.setCouponId(cardInfo.getCouponId());
couponOrder.setOrderId(order.getId());
couponOrder.setCouponOrderStatus(EnumCouponOrderStatus.CARD_COMPLETE.getCode());
couponOrder.setUpdateDate(curDate);
try {
@@ -542,4 +548,165 @@ public class WxCardSpendServiceImpl implements WxCardSpendService {
excelService.exportExcel(list, null, "卡消费记录", WxCardSpendVo.class, "卡消费记录.xlsx", response, false);
}

@Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class})
public void cardSpendForPosPrePay(WxCardSpend record) throws MallinkException {
Date curDate = new Date();
final IdWorker idWorker = IdWorker.get();
// 1. get card info
WxCardInfo cardInfo = wxCardInfoMapper.selectByPrimaryKey(record.getCardId());
if (cardInfo == null) {
logger.error("card not found: " + record.getCardId());
throw new MallinkException(ErrorCode.CARD_IS_NOT_FOUND);
}
// 2. coupon
Integer subsidyRate = 0;
WxCoupon coupon = wxCouponMapper.selectByPrimaryKey(cardInfo.getCouponId());
if (coupon == null) {
logger.error("card's coupon not found: " + cardInfo.getCouponId());
throw new MallinkException(ErrorCode.CARD_IS_NOT_FOUND);
}
if (coupon.getSubsidyNum() == null) {
logger.error("卡补贴额未填写: " + cardInfo.getCouponId());
throw new MallinkException(ErrorCode.CARD_SUBSIDY_NOT_SET);
}

// 3. get pay account
WxPayAccount payAccount = null;
WxPayAccount payAccountQ = new WxPayAccount();
payAccountQ.setTenantId(record.getTenantId());
try {
payAccount = payAccountMapper.selectOne(payAccountQ);
} catch (Exception e) {
logger.error("获取payAccount error: " + record.getTenantId());
throw new MallinkException(ErrorCode.SYS_MCH_NOT_FOUND);
}

// 4. 扣减计算
Double paymentD = 1.0 * cardInfo.getSaleAmount() * record.getDeductionAmount() / cardInfo.getAmount();
Integer payment = paymentD.intValue();
int iChargeFee = PayUtils.getPayRate(payment, payAccount.getRate());
Integer real_payment = payment - iChargeFee;
Integer remain_real_pament = cardInfo.getRemainingShareFeeAmount() - real_payment;
Integer remaingAmount = cardInfo.getRemainingAmount()-record.getDeductionAmount();
if (remaingAmount.equals(0)) {
// 最后一次支付时
real_payment = Math.min(real_payment, cardInfo.getRemainingShareFeeAmount());
remain_real_pament = cardInfo.getRemainingShareFeeAmount() - real_payment;
}

// 5 insert card_spend
record.setId(idWorker.nextId());
record.setTenantId(cardInfo.getTenantId());
record.setPayment(payment);
record.setRealPayment(real_payment);
record.setCardBeforeAmount(cardInfo.getRemainingAmount());
record.setCardRemainAmount(remaingAmount);
record.setCardBeforeRealAmount(cardInfo.getRemainingShareFeeAmount());
record.setCardRemainRealAmount(remain_real_pament);
record.setPayStatus(EnumCardSpendStatus.PREV_PAY.getCode());
record.setCreateDate(curDate);
record.setUpdateDate(curDate);
try {
wxCardSpendMapper.insertSelective(record);
} catch (Exception e) {
logger.error("card spend insert error");
throw new MallinkException(ErrorCode.DB_FAIL.getCode(), "卡消费插入出错");
}

// 7. update card info
cardInfo.setRemainingAmount(remaingAmount);
cardInfo.setRemainingShareFeeAmount(remain_real_pament);
cardInfo.setUpdateDate(curDate);
// 消费后,修改卡转赠状态
if (cardInfo.getSupportTransfer().equals(EnumCouponTransfer.YES.getCode())) {
cardInfo.setSupportTransfer(EnumCouponTransfer.NO.getCode());
}
try {
wxCardInfoMapper.updateByPrimaryKeySelective(cardInfo);
} catch (Exception e) {
String errMessage = "消费卡信息更新出错: " + cardInfo.getId();
logger.error(errMessage);
throw new MallinkException(ErrorCode.DB_FAIL.getCode(), errMessage);
}
}

@Transactional(propagation = Propagation.REQUIRED, readOnly = false, rollbackFor = {Exception.class})
public void cardSpendForPosPrePayCancel(WxCardSpend record) throws MallinkException {
Date curDate = new Date();
if (record.getId() == null) {
throw new MallinkException(ErrorCode.SYS_PARAMETER_NOT_NULL);
}
if (!record.getPayStatus().equals(EnumCardSpendStatus.PREV_PAY.getCode())) {
logger.error("card spend not prev pay");
throw new MallinkException(ErrorCode.CARD_SPEND_IS_NOT_PREV);
}
// 1. get card info
WxCardInfo cardInfo = wxCardInfoMapper.selectByPrimaryKey(record.getCardId());
if (cardInfo == null) {
logger.error("card not found: " + record.getCardId());
throw new MallinkException(ErrorCode.CARD_IS_NOT_FOUND);
}
// 2. coupon
Integer subsidyRate = 0;
WxCoupon coupon = wxCouponMapper.selectByPrimaryKey(cardInfo.getCouponId());
if (coupon == null) {
logger.error("card's coupon not found: " + cardInfo.getCouponId());
throw new MallinkException(ErrorCode.CARD_IS_NOT_FOUND);
}
if (coupon.getSubsidyNum() == null) {
String errMessage = "券补贴额未填写";
logger.error(errMessage);
throw new MallinkException(ErrorCode.SYS_PARAMETER_ERROR.getCode(), errMessage);
}

// 3. get pay account
WxPayAccount payAccount = null;
WxPayAccount payAccountQ = new WxPayAccount();
payAccountQ.setTenantId(record.getTenantId());
try {
payAccount = payAccountMapper.selectOne(payAccountQ);
} catch (Exception e) {
logger.error("获取payAccount error: " + record.getTenantId());
throw new MallinkException(ErrorCode.SYS_MCH_NOT_FOUND);
}

// 4. 增加计算
Double paymentD = 1.0 * cardInfo.getSaleAmount() * record.getDeductionAmount() / cardInfo.getAmount();
Integer payment = paymentD.intValue();
int iChargeFee = PayUtils.getPayRate(payment, payAccount.getRate());
Integer real_payment = payment - iChargeFee;
Integer remain_real_pament = cardInfo.getRemainingShareFeeAmount() + real_payment;
Integer remaingAmount = cardInfo.getRemainingAmount()+record.getDeductionAmount();

// 5.、如果还是原价更改卡转赠状态
WxCardInfo updateCardInfo = new WxCardInfo();
updateCardInfo.setId(record.getCardId());
if (cardInfo.getAmount().equals(remaingAmount) &&
cardInfo.getSupportTransfer().equals(EnumCouponTransfer.NO.getCode())) {
updateCardInfo.setSupportTransfer(EnumCouponTransfer.YES.getCode());
}

// 6. update card info
cardInfo.setRemainingAmount(remaingAmount);
cardInfo.setRemainingShareFeeAmount(remain_real_pament);
cardInfo.setUpdateDate(curDate);
try {
wxCardInfoMapper.updateByPrimaryKeySelective(cardInfo);
} catch (Exception e) {
String errMessage = "卡信息更新出错";
logger.error(errMessage);
throw new MallinkException(ErrorCode.DB_FAIL.getCode(), errMessage);
}

// 100. delete prev card_spend
record.setTenantId(cardInfo.getTenantId());
try {
wxCardSpendMapper.deleteForPrevCancel(record);
} catch (Exception e) {
String errMessage = "卡消费信息删除出错";
logger.error(errMessage);
throw new MallinkException(ErrorCode.DB_FAIL.getCode(), errMessage);
}
}

}

+ 20
- 2
mallinkService/src/main/resources/mapper/WxCardSpendMapper.xml Wyświetl plik

@@ -8,6 +8,7 @@
<result column="owner_id" jdbcType="BIGINT" property="ownerId"/>
<result column="merchant_id" jdbcType="BIGINT" property="merchantId"/>
<result column="order_id" jdbcType="BIGINT" property="orderId"/>
<result column="pos_order_id" jdbcType="BIGINT" property="posOrderId"/>
<result column="deduction_amount" jdbcType="INTEGER" property="deductionAmount"/>
<result column="payment" jdbcType="INTEGER" property="payment"/>
<result column="real_payment" jdbcType="INTEGER" property="realPayment"/>
@@ -18,12 +19,14 @@
<result column="create_date" jdbcType="TIMESTAMP" property="createDate"/>
<result column="update_date" jdbcType="TIMESTAMP" property="updateDate"/>
<result column="pay_status" jdbcType="INTEGER" property="payStatus"/>
<result column="from" jdbcType="INTEGER" property="from"/>
<result column="pos_refund_status" jdbcType="INTEGER" property="posRefundStatus"/>
</resultMap>

<sql id="allColumns">
`id`,`tenant_id`,`card_id`,`owner_id`,`merchant_id`,`order_id`,`deduction_amount`,`payment`,`real_payment`,
`id`,`tenant_id`,`card_id`,`owner_id`,`merchant_id`,`order_id`,`pos_order_id`,``deduction_amount`,`payment`,`real_payment`,
`card_remain_amount`,`card_before_amount`,`card_remain_real_amount`,`card_before_real_amount`,
`create_date`,`update_date`, `pay_status`
`create_date`,`update_date`, `pay_status`, `from`, `pos_refund_status`
</sql>

<sql id="dynamicWhereConditions">
@@ -46,6 +49,9 @@
<if test=" null != orderId ">
and `order_id` = #{orderId}
</if>
<if test=" null != posOrderId ">
and `pos_order_id` = #{posOrderId}
</if>
<if test=" null != deductionAmount ">
and `deduction_amount` = #{deductionAmount}
</if>
@@ -76,6 +82,12 @@
<if test=" null != payStatus ">
and `pay_status` = #{payStatus}
</if>
<if test=" null != from ">
and `from` = #{from}
</if>
<if test=" null != posRefundStatus ">
and `pos_refund_status` = #{posRefundStatus}
</if>
<if test=" null != startdate and null!=enddate">
and `create_date` between #{startdate} and #{enddate}
</if>
@@ -115,6 +127,11 @@
</where>
</select>

<delete id="deleteForPrevCancel" parameterType="com.iformall.domain.po.WxCardSpend">
delete from wx_card_spend
where `tenant_id` = #{tenantId} and `id` = #{id} and `use_status` = #{}
</delete>

<select id="findCount" parameterType="com.iformall.domain.po.WxCardSpend" resultType="Integer">
select count(*)
from wx_card_spend cs
@@ -263,6 +280,7 @@
<result column="owner_id" jdbcType="BIGINT" property="ownerId"/>
<result column="merchant_id" jdbcType="BIGINT" property="merchantId"/>
<result column="order_id" jdbcType="BIGINT" property="orderId"/>
<result column="pos_order_id" jdbcType="BIGINT" property="posOrderId"/>
<result column="deduction_amount" jdbcType="INTEGER" property="deductionAmount"/>
<result column="payment" jdbcType="INTEGER" property="payment"/>
<result column="real_payment" jdbcType="INTEGER" property="realPayment"/>


Ładowanie…
Anuluj
Zapisz