|
|
@@ -0,0 +1,270 @@
|
|
|
+<?php
|
|
|
+
|
|
|
+namespace bizHd\refund\services;
|
|
|
+
|
|
|
+use biz\product\classes\ProductClass;
|
|
|
+use biz\shop\classes\MainClass;
|
|
|
+use biz\shop\classes\ShopCapitalClass;
|
|
|
+use biz\stat\classes\StatOutClass;
|
|
|
+use biz\stat\classes\StatRefundClass;
|
|
|
+use bizHd\base\services\BaseService;
|
|
|
+use bizHd\goods\classes\GoodsClass;
|
|
|
+use bizHd\merchant\classes\ShopClass;
|
|
|
+use bizHd\order\classes\OrderClass;
|
|
|
+use bizHd\order\classes\OrderGoodsClass;
|
|
|
+use bizHd\order\classes\OrderItemClass;
|
|
|
+use bizHd\refund\classes\HdRefundClass;
|
|
|
+use bizHd\refund\classes\HdRefundGoodsClass;
|
|
|
+use bizHd\refund\classes\HdRefundItemClass;
|
|
|
+use bizHd\wx\classes\WxOpenClass;
|
|
|
+use common\components\dict;
|
|
|
+use common\components\orderSn;
|
|
|
+use common\components\util;
|
|
|
+use Yii;
|
|
|
+
|
|
|
+class HdRefundService extends BaseService
|
|
|
+{
|
|
|
+
|
|
|
+ public static $baseFile = '\bizHd\refund\classes\HdRefundClass';
|
|
|
+
|
|
|
+ //新增退款
|
|
|
+ public static function addRefund($post, $order)
|
|
|
+ {
|
|
|
+ $refundPrice = $post['price'] ?? 0;
|
|
|
+ if ($refundPrice <= 0) {
|
|
|
+ util::fail('请填写退款金额');
|
|
|
+ }
|
|
|
+
|
|
|
+ //记录总的退款金额
|
|
|
+ $order->refundPrice = $refundPrice;
|
|
|
+ $currentTkPrice = bcadd($order->tkPrice, $refundPrice, 2);
|
|
|
+ $order->tkPrice = $currentTkPrice;
|
|
|
+ $order->refund = OrderClass::REFUND_YES;
|
|
|
+ $currentActPrice = bcsub($order->actPrice, $refundPrice, 2);
|
|
|
+ if ($currentActPrice < 0) {
|
|
|
+ util::fail('退款金额有问题!');
|
|
|
+ }
|
|
|
+ $order->actPrice = $currentActPrice;
|
|
|
+ $order->realPrice = $currentActPrice;
|
|
|
+ $order->save();
|
|
|
+
|
|
|
+ $transaction_id = $order->thirdNo ?? '';
|
|
|
+
|
|
|
+ $data = [];
|
|
|
+ $data['status'] = HdRefundClass::STATUS_UN_COMPLETE;
|
|
|
+ $refundSn = orderSn::getHdRefundSn();
|
|
|
+ $data['refundSn'] = $refundSn;
|
|
|
+ $data['orderSn'] = $order->orderSn ?? '';
|
|
|
+ $data['orderId'] = $order->id ?? 0;
|
|
|
+ $sjId = $post['sjId'] ?? 0;
|
|
|
+ $refundType = $post['refundType'] ?? 0;
|
|
|
+ $shopId = $post['shopId'] ?? 0;
|
|
|
+ $mainId = $post['mainId'] ?? 0;
|
|
|
+ $xsOrderSn = $order->orderSn ?? '';
|
|
|
+ $data['sjId'] = $sjId;
|
|
|
+ $data['shopId'] = $shopId;
|
|
|
+ $data['mainId'] = $mainId;
|
|
|
+ $data['shopAdminId'] = $post['shopAdminId'] ?? 0;
|
|
|
+ $data['shopAdminName'] = $post['shopAdminName'] ?? '';
|
|
|
+
|
|
|
+ $postProduct = $post['product'] ?? '';
|
|
|
+ if ($refundType == HdRefundClass::REFUND_TYPE_MONEY_GOOD) {
|
|
|
+ //商品花材结构 property 0成品 1花材
|
|
|
+ //[{productId:0,num:1,unitType:0,unitPrice:12,unitName:'扎',property:1}]
|
|
|
+ if (empty($postProduct)) {
|
|
|
+ util::fail('没有退款商品');
|
|
|
+ }
|
|
|
+ $goodsInfoList = [];
|
|
|
+ $itemInfoList = [];
|
|
|
+ foreach ($postProduct as $current) {
|
|
|
+ $property = $current['property'] ?? 0;
|
|
|
+ if ($property == 0) {
|
|
|
+ $goodsInfoList[] = $current;
|
|
|
+ } else {
|
|
|
+ $itemInfoList[] = $current;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (!empty($itemInfoList)) {
|
|
|
+ $ids = array_column($itemInfoList, 'productId');
|
|
|
+ $productInfo = ProductClass::getByids($ids, null, 'id');
|
|
|
+ $orderItemData = OrderItemClass::getAllByCondition(['orderSn' => $xsOrderSn], null, '*', 'itemId', true);
|
|
|
+ if (empty($orderItemData)) {
|
|
|
+ util::fail('没有找到商品');
|
|
|
+ }
|
|
|
+ foreach ($itemInfoList as $currentProduct) {
|
|
|
+ $id = $currentProduct['productId'] ?? 0;
|
|
|
+ $unitType = $currentProduct['unitType'] ?? 0;
|
|
|
+ $unitName = $currentProduct['unitName'] ?? '';
|
|
|
+ $currentRefundNum = $currentProduct['num'] ?? 0;
|
|
|
+ $name = $productInfo[$id]['name'] ?? '';
|
|
|
+ $ptItemId = $productInfo[$id]['itemId'] ?? 0;
|
|
|
+ $cover = $productInfo[$id]['cover'] ?? '';
|
|
|
+ $ratio = $productInfo[$id]['ratio'] ?? '';
|
|
|
+ $bigUnit = $productInfo[$id]['bigUnit'] ?? '';
|
|
|
+ $smallUnit = $productInfo[$id]['smallUnit'] ?? '';
|
|
|
+ $currentOrderItem = $orderItemData[$id] ?? null;
|
|
|
+ if (empty($currentOrderItem)) {
|
|
|
+ util::fail('没有找到退款的花材');
|
|
|
+ }
|
|
|
+ $orderItemNum = $currentOrderItem->num ?? 0;
|
|
|
+ //已退货数
|
|
|
+ $hasRefundNum = $currentOrderItem->refundNum ?? 0;
|
|
|
+ $remainNum = bcsub($orderItemNum, $hasRefundNum);
|
|
|
+ if ($currentRefundNum > $remainNum) {
|
|
|
+ util::fail("{$name}超过可退数量");
|
|
|
+ }
|
|
|
+ $currentOrderItem->refundNum = bcadd($hasRefundNum, $currentRefundNum);
|
|
|
+ $currentOrderItem->save();
|
|
|
+ $thisItemData = [
|
|
|
+ 'refundSn' => $refundSn,
|
|
|
+ 'mainId' => $mainId,
|
|
|
+ 'sjId' => $sjId,
|
|
|
+ 'shopId' => $shopId,
|
|
|
+ 'name' => $name,
|
|
|
+ 'itemId' => $id,
|
|
|
+ 'ptItemId' => $ptItemId,
|
|
|
+ 'num' => $currentRefundNum,
|
|
|
+ 'unitName' => $unitName,
|
|
|
+ 'unitType' => $unitType,
|
|
|
+ 'cover' => $cover,
|
|
|
+ 'ratio' => $ratio,
|
|
|
+ 'bigUnit' => $bigUnit,
|
|
|
+ 'smallUnit' => $smallUnit,
|
|
|
+ ];
|
|
|
+ HdRefundItemClass::addData($thisItemData, $refundSn, $post);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if (!empty($goodsInfoList)) {
|
|
|
+ $ids = array_column($goodsInfoList, 'productId');
|
|
|
+ $goodsData = GoodsClass::getByIds($ids, null, 'id');
|
|
|
+ $orderGoodsData = OrderGoodsClass::getAllByCondition(['orderSn' => $xsOrderSn], null, '*', 'goodsId', true);
|
|
|
+ foreach ($goodsInfoList as $currentGoods) {
|
|
|
+ $goodsId = $currentGoods['productId'] ?? 0;
|
|
|
+ $name = $goodsData[$goodsId]['name'] ?? '';
|
|
|
+ $currentRefundNum = $currentGoods['num'] ?? 0;
|
|
|
+ $currentOrderGoods = $orderGoodsData[$goodsId] ?? [];
|
|
|
+ if (empty($currentOrderGoods)) {
|
|
|
+ util::fail('没有找到商品呢');
|
|
|
+ }
|
|
|
+ $totalNum = $currentOrderGoods->num ?? 0;
|
|
|
+ $hasRefundNum = $currentOrderGoods->refundNum ?? 0;
|
|
|
+ $remainNum = bcsub($totalNum, $hasRefundNum);
|
|
|
+ if ($currentRefundNum > $remainNum) {
|
|
|
+ util::fail("{$name}超过可退数量");
|
|
|
+ }
|
|
|
+ $currentOrderGoods->refundNum = bcadd($hasRefundNum, $currentRefundNum);
|
|
|
+ $currentOrderGoods->save();
|
|
|
+
|
|
|
+ $cover = $goodsData[$goodsId]['cover'] ?? '';
|
|
|
+ $num = $currentGoods['num'] ?? 0;
|
|
|
+ $saveGoods = [
|
|
|
+ 'refundSn' => $refundSn,
|
|
|
+ 'mainId' => $mainId,
|
|
|
+ 'name' => $name,
|
|
|
+ 'cover' => $cover,
|
|
|
+ 'goodsId' => $goodsId,
|
|
|
+ 'num' => $num,
|
|
|
+ ];
|
|
|
+ HdRefundGoodsClass::addData($saveGoods, $refundSn, $post);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ $data['customId'] = $order->customId ?? 0;
|
|
|
+ $data['remark'] = $post['remark'] ?? '';
|
|
|
+ $data['refundPrice'] = $refundPrice;
|
|
|
+ $data['refundType'] = $post['refundType'] ?? 0;
|
|
|
+
|
|
|
+ //写入订单表
|
|
|
+ $refund = HdRefundClass::add($data, true);
|
|
|
+
|
|
|
+ $payWay = $order->payWay;
|
|
|
+ $shopId = $order->shopId;
|
|
|
+ $main = MainClass::getLockById($mainId);
|
|
|
+ $shop = ShopClass::getLockById($shopId);
|
|
|
+ if (empty($main)) {
|
|
|
+ util::fail('main信息缺失');
|
|
|
+ }
|
|
|
+ if (empty($shop)) {
|
|
|
+ util::fail('没有找到门店');
|
|
|
+ }
|
|
|
+ //总支出增加
|
|
|
+ $currentTotalExpend = bcadd($main->totalExpend, $refundPrice, 2);
|
|
|
+ $main->totalExpend = $currentTotalExpend;
|
|
|
+ $totalRefund = bcadd($main->totalRefund, $refundPrice, 2);
|
|
|
+ $main->totalRefund = $totalRefund;
|
|
|
+ $main->save();
|
|
|
+
|
|
|
+ //支出流水
|
|
|
+ $thisType = dict::getDict('capitalType', 'hdOrderRefund', 'id');
|
|
|
+ $sjId = $order->sjId ?? 0;
|
|
|
+ $event = '销售退款';
|
|
|
+ $capitalData = [
|
|
|
+ 'capitalType' => $thisType,
|
|
|
+ 'io' => 0,
|
|
|
+ 'totalExpend' => $currentTotalExpend,
|
|
|
+ 'payWay' => 0,
|
|
|
+ 'amount' => $refundPrice,
|
|
|
+ 'sjId' => $sjId,
|
|
|
+ 'shopId' => $shopId,
|
|
|
+ 'event' => $event,
|
|
|
+ ];
|
|
|
+ ShopCapitalClass::addCapital($capitalData);
|
|
|
+ //当天和当月支出统计
|
|
|
+ StatOutClass::updateOrInsert($shop, $refundPrice);
|
|
|
+ //退款统计
|
|
|
+ StatRefundClass::replace($shop, $payWay, $refundPrice);
|
|
|
+
|
|
|
+ //退款流程
|
|
|
+ if ($payWay == dict::getDict('payWay', 'wxPay')) {
|
|
|
+
|
|
|
+ //门店余额减少
|
|
|
+ \biz\shop\classes\ShopClass::hdSaleRefundReduceBalance($main, $shop, $refund, $refundPrice);
|
|
|
+
|
|
|
+ //微信收款的原路退回
|
|
|
+ ini_set('date.timezone', 'Asia/Shanghai');
|
|
|
+ $wx = Yii::getAlias("@vendor/wxPayApi_v3.0.10");
|
|
|
+ require_once($wx . '/lib/WxPay.Api.php');
|
|
|
+ require_once($wx . '/example/WxPay.Config.php');
|
|
|
+
|
|
|
+ $totalFee = $order->orderPrice * 100;
|
|
|
+ $refundFee = $refundPrice * 100;
|
|
|
+
|
|
|
+ $merchantExt = WxOpenClass::getMallWxInfo();
|
|
|
+ $mid = $merchantExt['wxPayMerchantId'] ?? '';
|
|
|
+ $appId = $merchantExt['miniAppId'] ?? '';
|
|
|
+ $key = $merchantExt['wxPayKey'] ?? '';
|
|
|
+
|
|
|
+ $input = new \WxPayRefund();
|
|
|
+ $input->SetTransaction_id($transaction_id);
|
|
|
+ $input->SetTotal_fee($totalFee);
|
|
|
+ $input->SetRefund_fee($refundFee);
|
|
|
+ $input->SetNotify_url(Yii::$app->params['mallHost'] . '/notice/wx-refund-callback/');
|
|
|
+
|
|
|
+ $config = new \WxPayConfig();
|
|
|
+ $config->SetAppId($appId);
|
|
|
+ $config->SetMerchantId($mid);
|
|
|
+ $config->SetKey($key);
|
|
|
+
|
|
|
+ $input->SetOut_refund_no($refundSn);
|
|
|
+ $input->SetOp_user_id($mid);
|
|
|
+ $return = \WxPayApi::refund($config, $input);
|
|
|
+ if (isset($return['return_code']) == false || $return['return_code'] != 'SUCCESS' || isset($return['result_code']) == false || $return['result_code'] != 'SUCCESS') {
|
|
|
+ $msg = $return['return_msg'] ?? '';
|
|
|
+ $err_code_des = $return['err_code_des'] ?? '';
|
|
|
+ Yii::info("退款失败 hd orderId:{$order->id} msg:{$msg}");
|
|
|
+ Yii::info($err_code_des);
|
|
|
+ Yii::info('微信退款返回信息:' . json_encode($return));
|
|
|
+ util::fail('退款失败');
|
|
|
+ }
|
|
|
+ $wxRefundId = $return['refund_id'] ?? '';
|
|
|
+ $refund->thirdRefundNo = $wxRefundId;
|
|
|
+ $refund->save();
|
|
|
+
|
|
|
+ } else {
|
|
|
+ util::fail('暂时只支持微信支付订单退款');
|
|
|
+ }
|
|
|
+ return $refund;
|
|
|
+ }
|
|
|
+
|
|
|
+}
|