1557492053 2 years ago
parent
commit
150bcbdc23
2 changed files with 272 additions and 8 deletions
  1. 3 3
      app/api/controller/Order.php
  2. 269 5
      app/api/service/OrderService.php

+ 3 - 3
app/api/controller/Order.php

@@ -203,10 +203,10 @@ class Order extends \app\BaseController
         $params = $this->request->param();
         predicate(isset($params['order_id']) && $params['order_id'] > 0, '订单ID不存在!');
         predicate(isset($params['origin_order_product_ids']) && $params['origin_order_product_ids'] > 0, '原来的订单商品IDs不存在!');
-        predicate(isset($params['append_product_ids']) && $params['append_product_ids'] > 0, '新添加的商品IDs不存在!');
+        predicate(isset($params['append_store_product_ids']) && $params['append_store_product_ids'] > 0, '新添加的门店商品IDs不存在!');
         $origin_order_product_ids = explode(',', $params['origin_order_product_ids']);
-        $append_product_ids = explode(',', $params['append_product_ids']);
-        $r = $this->service->exchange($params['admin_id'], $params['order_id'], $origin_order_product_ids, $append_product_ids);
+        $append_store_product_ids = explode(',', $params['append_store_product_ids']);
+        $r = $this->service->exchange($params['admin_id'], $params['admin_name'], $params['order_id'], $origin_order_product_ids, $append_store_product_ids);
         predicate($r->bool, $r->message);
         return $this->ok($r->data);
     }

+ 269 - 5
app/api/service/OrderService.php

@@ -714,7 +714,7 @@ class OrderService extends \app\BaseService
      * @throws \think\db\exception\ModelNotFoundException
      */
     public function returnOrderProduct($admin_id, $order_id, array $order_product_ids) {
-//        $verify = AuthService::verify($admin_id, 10005);
+        // $verify = AuthService::verify($admin_id, 10005);
         $order = $this->orderModel->findById($order_id);
         if (!$order) return $this->fail(lang("Order does not exist"));
         if ($order->type == 2) return $this->fail(lang("The status of the order does not support return or exchange"));
@@ -735,6 +735,10 @@ class OrderService extends \app\BaseService
                 array_push($result, $item['adviser_2_id']);
             return $result;
         },[]);
+        $zue_coin_config = $this->paymentChannelModel->findById(11);
+        if(!$zue_coin_config)
+            return $this->fail("御龙币设置不存在!");
+        $zue_coin_exchange_rate = $zue_coin_config['zue_coin_exchange_rate'] ?? 0; // 兑换比例
         //商品本金
         $total_product_amount = $order->product_amount;
         // 整体税费
@@ -748,7 +752,7 @@ class OrderService extends \app\BaseService
         // 御龙币兑换的金额
         $total_zue_coin_amount = $order->zue_coin_amount;
         // 御龙币当时的兑换比例
-        $zue_coin_exchange_rate = fixed2Float($order->zue_coin_amount / $order->zue_coin);
+        $zue_coin_exchange_rate = $order->zue_coin_amount > 0 && $order->zue_coin > 0 ? fixed2Float($order->zue_coin_amount / $order->zue_coin) : $zue_coin_exchange_rate;
         // 总计退还多少钱
         $total_return_amount = 0;
 
@@ -766,7 +770,7 @@ class OrderService extends \app\BaseService
             $total_sales_tax -= $return_order_product['sales_tax'];
             // 减少本金
             $total_product_amount -= $return_order_product['real_price'];
-            $total_return_amount += $return_order_product['transaction_price'];
+            $total_return_amount -= $return_order_product['transaction_price'];
             if(isset($return_now_stocks[$return_order_product['store_product_id']])) {
                 $return_now_stocks[$return_order_product['store_product_id']] += 1;
             } else {
@@ -826,7 +830,7 @@ class OrderService extends \app\BaseService
                 'order_id' => $order->id,
                 'channel_id' => 0,
                 'channel_name' => "Exchange a purchase",
-                'fee'   => -$total_return_amount,
+                'fee'   => $total_return_amount,
                 'create_time' => time(),
                 'update_time' => time(),
             ]);
@@ -849,7 +853,267 @@ class OrderService extends \app\BaseService
         return $this->ok(true);
     }
 
-    public function exchange($admin_id, $order_id, $origin_order_product_ids, $append_product_ids) {
+    /**
+     * @param $admin_id
+     * @param $admin_name
+     * @param $order_id
+     * @param $origin_order_product_ids
+     * @param $append_store_product_ids
+     * @return \SResult
+     * @throws \think\db\exception\DataNotFoundException
+     * @throws \think\db\exception\DbException
+     * @throws \think\db\exception\ModelNotFoundException
+     */
+    public function exchange($admin_id, $admin_name, $order_id, $origin_order_product_ids, $append_store_product_ids) {
+        // $verify = AuthService::verify($admin_id, 10005);
+        $order = $this->orderModel->findById($order_id);
+        if (!$order) return $this->fail(lang("Order does not exist"));
+        if ($order->type == 2) return $this->fail(lang("The status of the order does not support return or exchange"));
+        $return_order_products = $this->orderProductModel->findByIds($origin_order_product_ids)->toArray();
+        if (count($origin_order_product_ids) != count($return_order_products)) return $this->fail(lang("The order item was incorrectly selected"));
+        $all_order_products = $this->orderProductModel->findByOrderId($order->id)->toArray();
+        $merge_order_products = array_reduce($all_order_products,
+            function ($result, $item) use($origin_order_product_ids) {
+                if(!in_array($item['id'], $origin_order_product_ids))
+                    array_push($result, $item);
+                return $result;
+            }, []);
+        $obj_names = array_map(function ($data) {return $data['product_name'];}, $merge_order_products);
+        $advisor_ids = array_reduce($merge_order_products, function ($result, $item) {
+            if ($item['adviser_1_id'])
+                array_push($result, $item['adviser_1_id']);
+            if ($item['adviser_2_id'])
+                array_push($result, $item['adviser_2_id']);
+            return $result;
+        },[]);
+        $zue_coin_config = $this->paymentChannelModel->findById(11);
+        if(!$zue_coin_config)
+            return $this->fail("御龙币设置不存在!");
+        $zue_coin_exchange_rate = $zue_coin_config['zue_coin_exchange_rate'] ?? 0; // 兑换比例
+        //商品本金
+        $total_product_amount = $order->product_amount;
+        // 整体税费
+        $total_sales_tax = $order->total_sales_tax;
+        // 总体信用卡服务费
+        $total_service_amount = $order->service_charge_amount;
+        // 总体年费
+        $total_annual_fee = $order->total_annual_fee;
+        // 总体御龙币
+        $total_zue_coin = $order->zue_coin;
+        // 御龙币兑换的金额
+        $total_zue_coin_amount = $order->zue_coin_amount;
+        // 御龙币当时的兑换比例
+        $zue_coin_exchange_rate = $order->zue_coin_amount > 0 && $order->zue_coin > 0 ? fixed2Float($order->zue_coin_amount / $order->zue_coin) : $zue_coin_exchange_rate;
+        // 差价
+        $diff_amount = 0;
+
+        // 商品库存
+        $return_now_stocks = [];
+        // 减操作
+        foreach ($return_order_products as $return_order_product) {
+            // 减少御龙币
+            $total_zue_coin -= $return_order_product['zue_coin'];
+            $total_zue_coin_amount -= ($return_order_product['zue_coin'] * $zue_coin_exchange_rate);
+            // 减少年费
+            $total_annual_fee -= $return_order_product['annuity'];
+            // 减少信用卡服务费
+            $total_service_amount -= $return_order_product['service_charge'];
+            // 减少税费
+            $total_sales_tax -= $return_order_product['sales_tax'];
+            // 减少本金
+            $total_product_amount -= $return_order_product['real_price'];
+            $diff_amount -= $return_order_product['transaction_price'];
+            if(isset($return_now_stocks[$return_order_product['store_product_id']])) {
+                $return_now_stocks[$return_order_product['store_product_id']] += 1;
+            } else {
+                $return_now_stocks[$return_order_product['store_product_id']] = 1;
+            }
+        }
+
+        /////////////// 加操作
+        // 客户
+        $customer = $this->customerModel->findById($order->customer_id);
+        if (!$customer)
+            return $this->fail(lang("The Customer does not exist"));
+        // 门店商品
+        $store_products = $this->storeProductModel->fetchRelationsByOrder($append_store_product_ids)->toArray();
+        if(count($store_products) != count($append_store_product_ids))
+            return $this->fail(lang("The Product does not exist"));
+        // 商品信息
+        $products = array_map(function ($p) {
+            return $p['product'] ? $p['product'] : null;
+        }, $store_products);
+        if(in_array(null, $products))
+            return $this->fail(lang("The Product does not exist"));
+        $config = $this->configModel->findConfig();
+        $activityProducts = $this->activityProductModel->fetchByProductIds(array_map(function ($data) {
+            return $data['id'];
+        }, $products))->toArray();
+        $fmt_store_products = [];
+        foreach ($store_products as &$item) {
+            $aProducts = array_filter($activityProducts, function ($aProduct) use ($item) {
+                return $aProduct['product_id'] == $item['product_id'];
+            });
+            $res = compare($item['product']['real_price'] ?? 0, $aProducts);
+            $item['activity'] = $res['item'];
+            $item['product']['origin_price'] = $item['product']['real_price'];
+            $item['product']['real_price'] = fixed2Float($res['min_num'] > 0 ? $res['min_num'] : 0);
+            $sales_tax_rate = $item['product']['sales_tax_rate'] > 0 ? $item['product']['sales_tax_rate'] : $config->sales_tax_rate;
+            $sales_tax = fixed2Float($sales_tax_rate > 0 && $item['product']['real_price'] > 0 ? ($item['product']['real_price'] * ($sales_tax_rate / 100)) : 0);
+            $item['product']['sales_tax_rate'] = $sales_tax_rate;
+            $item['product']['sales_tax'] = $sales_tax;
+            $fmt_store_products[$item['id']] = $item;
+        }
+        $order_products = [];
+        $order_annual_fees = [];
+        for ($j = 0; $j < count($store_products); $j++) {
+            $store_product = $store_products[$j];
+            array_push($obj_names, $store_product['product']['name']);
+            array_push($advisor_ids, $admin_id);
+            array_push($order_products, [
+                'order_id' => $order->id,
+                'order_no' => $order->no,
+                'customer_id' => $order->customer_id,
+                'product_id' => $store_product['product']['id'],
+                'product_category_id'   => $store_product['product']['category_id'],
+                'is_serve'  =>  $store_product['product']['is_serve'],
+                'store_product_id' => $store_product['id'],
+                'product_name' => $store_product['product']['name'],
+                'adviser_1_id' => $admin_id,
+                'adviser_1_name'  => $admin_name,
+                'adviser_2_id' => null,
+                'adviser_2_name'  => null,
+                'teacher_1_id' => null,
+                'teacher_1_name'  => null,
+                'teacher_2_id' => null,
+                'teacher_2_name'  => null,
+                'is_upload_numerology' => $store_product['product']['is_upload_numerology'],
+                'is_upload' => 0,
+                'report'    => null,
+                'is_gather_annuity' => $store_product['product']['is_gather_annuity'],
+                'annuity' => $store_product['product']['annuity'],
+                'real_price'    =>  $store_product['product']['real_price'],
+                'service_charge'    => 0,
+                'reduce_price'    => $store_product['activity'] ? $store_product['product']['origin_price'] - $store_product['product']['real_price'] : 0,
+                'reduce_type'    => $store_product['activity'] ? $store_product['activity']['type'] : 0,
+                'sales_tax_rate' => $store_product['product']['sales_tax_rate'],
+                'sales_tax' => $store_product['product']['sales_tax'],
+                'transaction_price' => fixed2Float($store_product['product']['real_price'] + $store_product['product']['sales_tax'] + $store_product['product']['annuity']),
+                'zue_coin'  =>  0,
+                'is_pay' => 1,
+                'create_time' => time(),
+                'update_time' => time(),
+            ]);
+
+            array_push($order_annual_fees, $store_product['product']['is_gather_annuity'] ?  [
+                'order_id' => $order->id,
+                'customer_id'   => $order->customer_id,
+                'customer_name'   => $order->customer_name,
+                'customer_mobile'  => $customer->mobile,
+                'customer_create_username' => $customer->create_username,
+                'index' => 1,
+                'order_product_id'  => -1,
+                'order_product_name' =>  $store_product['product']['name'],
+                'fee' =>  $store_product['product']['name'],
+                'is_pay' => 1,
+                'start_time' => time(),
+                'end_time' => time() + (365 * 24 * 60 * 60),
+                'order_create_time' => strtotime($order->create_time),
+                'adviser_1_id'  =>  $store_product['product']['annuity'],
+                'store_id' => $order->store_id,
+                'create_time'   =>  time(),
+                'update_time'   =>  time()
+            ] : null);
+            $total_product_amount += $store_product['product']['real_price'];
+            $total_sales_tax += $store_product['product']['sales_tax'];
+            if($store_product['product']['is_gather_annuity'] == 1)
+                $total_annual_fee += $store_product['product']['annuity'];
+            $diff_amount += fixed2Float($store_product['product']['real_price'] + $store_product['product']['sales_tax'] + $store_product['product']['annuity']);
+        }
+        $total_order_rental_amount = fixed2Float( $total_product_amount + $total_sales_tax + $total_service_amount + $total_annual_fee);
+        $total_receivable_amount = fixed2Float($total_product_amount + $total_sales_tax + $total_service_amount + $total_annual_fee - ($total_zue_coin * $zue_coin_exchange_rate));
+        $total_receive_amount = $total_receivable_amount;
+        $annual_fees = $this->orderAnnualFeeModel->fetchByOrderProductId($origin_order_product_ids);
+        Db::startTrans();
+        try {
+            // 退还御龙币
+            $return_zue_coin = $order->zue_coin - $total_zue_coin;
+            if ($return_zue_coin > 0) {
+                $customer_zue_coin = $this->zueCoinModel->findByCustomerId($order->customer_id);
+                if(!$customer_zue_coin) {
+                    throw new BaseException('御龙币账户记录不存在',1012);
+                }
+                Db::table('erp_customer_zue_coin')->where('id', '=', $customer_zue_coin->id)->inc('zue_coin', $return_zue_coin)->update();
+                Db::table('erp_zue_coin_record')->save([
+                    'zue_coin_id'   =>  $customer_zue_coin->id,
+                    'order_id'   =>  $order->id,
+                    'origin'        =>  $customer_zue_coin->zue_coin,
+                    'change'        =>  $return_zue_coin,
+                    'after'        =>  $customer_zue_coin->zue_coin + $return_zue_coin,
+                    'reason'        =>  3,
+                    'create_time'   =>  time(),
+                    'update_time'   =>  time(),
+                ]);
+            }
+            // 退还年费
+            if (count($annual_fees) > 0)
+                Db::table('erp_order_annual_fee')->where('id', 'in', array_map(function ($data) {return $data['id'];}, $annual_fees))->update(['is_delete' => 1, 'delete_time' => time()]);
+            // 插入退款记录
+            Db::table('erp_order_payment')->save([
+                'order_id' => $order->id,
+                'channel_id' => 0,
+                'channel_name' => "Exchange a purchase",
+                'fee'   => $diff_amount,
+                'create_time' => time(),
+                'update_time' => time(),
+            ]);
+            // 退还商品库存
+            $return_stock_keys = array_keys($return_now_stocks);
+            foreach ($return_stock_keys as $key) {
+                Db::table("erp_store_product")
+                    ->where('id', $key)
+                    ->inc('now_stock', $return_now_stocks[$key])
+                    ->dec('sale_stock', $return_now_stocks[$key])
+                    ->update();
+            }
+            // 删除订单商品
+            Db::table('erp_order_product')->where('id', 'in', $origin_order_product_ids)->update(['is_delete' => 1, 'delete_time' => time()]);
+
+            // 新增商品
+            for ($i = 0; $i < count($order_products); $i++) {
+                $order_product = $order_products[$i];
+                $order_annual_fee = $order_annual_fees[$i];
+                $last_id = Db::table('erp_order_product')->insert($order_product, true);
+                if($order_annual_fee != null) {
+                    $order_annual_fee['order_product_id'] = $last_id;
+                    Db::table('erp_order_annual_fee')->save($order_annual_fee);
+                }
+                Db::table("erp_store_product")
+                    ->where('id', $order_product['store_product_id'])
+                    ->dec('now_stock', 1)
+                    ->inc('sale_stock', 1)
+                    ->update();
+            }
+
+            // 更新订单
+            Db::table('erp_order')->where('id', $order->id)->update([
+                'rental_amount' => $total_order_rental_amount,
+                'receivable_amount' => $total_receivable_amount,
+                'receive_amount' => $total_receive_amount,
+                'product_amount' => $total_product_amount,
+                'total_sales_tax'   =>  $total_sales_tax,
+                'service_charge_amount' =>  $total_service_amount,
+                'total_annual_fee'  =>  $total_annual_fee,
+                'zue_coin'  =>  $total_zue_coin,
+                'zue_coin_amount'   =>  $total_zue_coin_amount,
+                'obj_names' => join(',', array_unique($obj_names)),
+                'advisor_ids' => join(',', array_unique($advisor_ids)),
+            ]);
+            Db::commit();
+        } catch (\Exception $e) {
+            Db::rollback();
+            return $this->fail(lang($e->getMessage()));
+        }
         return $this->ok(true);
     }