|
@@ -77,8 +77,10 @@ class AfterSaleService extends CrudService {
|
|
|
const { populate } = this.ctx.service.trade.orderDetail.getRefMods();
|
|
|
const orderDetail = await this.orderDetailModel.findById(data.order_detail).populate(populate);
|
|
|
if (!orderDetail) throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '未找到售后信息的订单');
|
|
|
- // 计算商品原价
|
|
|
+ // 计算商品原价,运费
|
|
|
let money = this.ctx.multiply(_.get(data, 'goods.sell_money'), _.get(data, 'goods.buy_num'));
|
|
|
+ const freight = this.ctx.multiply(_.get(data, 'goods.buy_num'), _.get(data, 'goods.freight'));
|
|
|
+ money = this.ctx.plus(money, freight);
|
|
|
const reason = _.get(data, 'desc');
|
|
|
const order_no = _.get(orderDetail, 'order.pay.pay_no');
|
|
|
if (!order_no) throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '未找到支付订单号');
|
|
@@ -93,12 +95,23 @@ class AfterSaleService extends CrudService {
|
|
|
money = this.ctx.minus(money, discountMoney);
|
|
|
}
|
|
|
|
|
|
+ // 取出商品输入的价格
|
|
|
+ const needRefund = _.get(data, 'money');
|
|
|
+ let refundMoney = 0;
|
|
|
+ if (money === needRefund) {
|
|
|
+ // 如果这俩价格相同,说明是正常退
|
|
|
+ refundMoney = money;
|
|
|
+ } else {
|
|
|
+ // 部分退,部分退是不退优惠券的
|
|
|
+ refundMoney = needRefund;
|
|
|
+ }
|
|
|
+
|
|
|
// 找下当前这个订单有多少次售后记录
|
|
|
let num = await this.model.count({ order_detail: data.order_detail });
|
|
|
num += 2;
|
|
|
// 组成退款单号
|
|
|
const out_refund_no = `${order_no}-r${num}`;
|
|
|
- const obj = { reason, money, order_no, out_refund_no };
|
|
|
+ const obj = { reason, money: refundMoney, order_no, out_refund_no };
|
|
|
// 退款请求
|
|
|
const res = await this.ctx.service.trade.pay.refund(obj);
|
|
|
if (res.errcode && res.errcode !== 0) throw new BusinessError(ErrorCode.SERVICE_FAULT, res.errmsg);
|
|
@@ -106,18 +119,14 @@ class AfterSaleService extends CrudService {
|
|
|
await tran.run();
|
|
|
|
|
|
// 检查优惠券是否都退了
|
|
|
- // TODO: 查看支付订单-优惠明细中,该优惠券影响的商品是否都有退款/退货成功的记录
|
|
|
+ // 查看支付订单-优惠明细中,该优惠券影响的商品是否都有退款/退货成功的记录,且退款成功的记录为退全款的.退部分是不退优惠券的
|
|
|
// 如果有,就说明该优惠券可以退了,没有影响任何一单了
|
|
|
const payOrder = _.get(orderDetail, 'order');
|
|
|
await this.checkToReturnUserCoupon(payOrder, tran);
|
|
|
- // tran.update('UserCoupon', id, { status: '0' });
|
|
|
-
|
|
|
- // 修改订单详情的优惠券标记
|
|
|
- // tran.update('OrderDetail', orderDetail._id, { 'total_detail.discount_detail': discount_detail });
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * 检查订单的优惠券并退优惠券
|
|
|
+ * 检查订单的优惠券并退优惠券, 必须是退全款,部分退款不退优惠券
|
|
|
* @param {Object} order 订单信息
|
|
|
* @param {Transaction} tran 事务的实例
|
|
|
*/
|
|
@@ -129,17 +138,27 @@ class AfterSaleService extends CrudService {
|
|
|
for (const od of orderDetailList) {
|
|
|
const { goods, _id: order_detail } = od;
|
|
|
// 组合成查售后的条件
|
|
|
- // 然后查这些商品有没有退款审核成功的记录
|
|
|
+ // 然后查这些商品有没有退款审核成功的记录, 且只有退全款的商品才能退券
|
|
|
const afterSaleQuerys = goods.map(i => ({ order_detail, 'goods._id': i._id, status: '-1' }));
|
|
|
for (const asq of afterSaleQuerys) {
|
|
|
- const num = await this.model.count(asq);
|
|
|
- if (num > 0) {
|
|
|
- // 商品有退款审核通过的记录,添加到已退款的列表中
|
|
|
- goodsRefundList.push(asq);
|
|
|
+ const asd = await this.model.findOne(asq);
|
|
|
+ if (asd) {
|
|
|
+ // 商品有退款审核通过的记录,查询每个商品是否退的是全款
|
|
|
+ // money: 实际退款的金额
|
|
|
+ const { money } = asd;
|
|
|
+ const od_id = _.get(asd, 'order_detail');
|
|
|
+ const goods_id = _.get(asd, 'goods._id');
|
|
|
+ const moneyDetail = await this.computedGoodsForRefund({ order_detail: od_id, goods_id });
|
|
|
+ if (moneyDetail) {
|
|
|
+ const { payTotal } = moneyDetail;
|
|
|
+ if (this.ctx.minus(payTotal, money) === 0) {
|
|
|
+ // 添加到已退款的列表中
|
|
|
+ goodsRefundList.push(asq);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
}
|
|
|
- // console.log(goodsRefundList);
|
|
|
// 获取支付单的优惠明细
|
|
|
const dd = _.get(order, 'total_detail.discount_detail', {});
|
|
|
for (const uc_id in dd) {
|
|
@@ -152,8 +171,32 @@ class AfterSaleService extends CrudService {
|
|
|
// 说明这个优惠券影响的商品都退了,这个优惠券也就能退了
|
|
|
tran.update('UserCoupon', uc_id, { status: '0' });
|
|
|
}
|
|
|
+ }
|
|
|
+ }
|
|
|
|
|
|
+ /**
|
|
|
+ * 计算商品退货的金额最大值
|
|
|
+ * @param {Object} body 参数体
|
|
|
+ * @param body.order_detail 订单详情id
|
|
|
+ * @param body.goods_id 商品id
|
|
|
+ */
|
|
|
+ async computedGoodsForRefund({ order_detail, goods_id }) {
|
|
|
+ const orderDetail = await this.orderDetailModel.findById(order_detail);
|
|
|
+ if (!orderDetail) throw new BusinessError(ErrorCode.DATA_NOT_EXIST, '未找到订单信息');
|
|
|
+ const goods = orderDetail.goods.find(f => f._id === goods_id);
|
|
|
+ // 货物支付金额, 数量*购买数量+ 数量*运费 - 优惠
|
|
|
+ const goodsTotal = this.ctx.multiply(goods.sell_money, goods.buy_num);
|
|
|
+ const freightTotal = this.ctx.multiply(goods.freight, goods.buy_num);
|
|
|
+ let discountTotal = 0;
|
|
|
+ const { total_detail = {} } = orderDetail;
|
|
|
+ const { discount_detail = {} } = total_detail;
|
|
|
+ for (const dd in discount_detail) {
|
|
|
+ const dm = _.get(discount_detail, `${dd}.${goods_id}`, 0);
|
|
|
+ discountTotal = this.ctx.plus(discountTotal, dm);
|
|
|
}
|
|
|
+ const payTotal = this.ctx.minus(this.ctx.plus(goodsTotal, freightTotal), discountTotal);
|
|
|
+ const obj = { payTotal, goodsTotal, freightTotal, discountTotal };
|
|
|
+ return obj;
|
|
|
}
|
|
|
|
|
|
async fetch(filter) {
|