storeModel = new StoreModel(); $this->orderModel = new OrderModel(); $this->productModel = new ProductModel(); $this->configModel = new ConfigModel(); $this->storeProductModel = new StoreProductModel(); $this->orderAnnualFeeModel = new OrderAnnualFeeModel(); $this->orderPaymentModel = new OrderPaymentModel(); $this->orderProductModel = new OrderProductModel(); $this->orderProceedsModel = new OrderProceedsModel(); $this->activityProductModel = new ActivityProductModel(); $this->adminModel = new AdminModel(); $this->customerModel = new CustomerModel(); $this->paymentChannelModel = new PaymentChannelModel(); $this->creditCardModel = new CreditCardConfigModel(); } /** * @param $params * @param array $store_products_params * @return \SResult * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\DbException * @throws \think\db\exception\ModelNotFoundException */ public function create($params, array $store_products_params) { // 客户 $customer = $this->customerModel->findById($params['customer_id']); if (!$customer) return $this->fail(lang("The Customer does not exist")); // 门店 $store = $this->storeModel->findById($params['store_id']); if (!$store) return $this->fail(lang("The store does not exist")); // 顾问 or 老师 ids $user_ids = []; // 门店商品ids $store_product_ids = []; for ($i = 0; $i < count($store_products_params); $i++) { $store_products_param = $store_products_params[$i]; $ids = []; if(isset($store_products_param->adviser_1_id)) array_push($ids, $store_products_param->adviser_1_id); if(isset($store_products_param->adviser_2_id)) array_push($ids, $store_products_param->adviser_2_id); if(isset($store_products_param->teacher_id)) array_push($ids, $store_products_param->teacher_id); $user_ids = array_unique(array_merge($user_ids, $ids)); array_push($store_product_ids, $store_products_param->store_product_id); } // Adviser|Teacher $users = $this->adminModel->findByIds($user_ids)->toArray(); if(count($users) != count($user_ids)) return $this->fail(lang("The Adviser|Teacher does not exist")); $fmt_users = array_reduce($users, function ($result, $item) { $result[$item['id']] = $item; return $result; }, []); // 门店商品 $store_products = $this->storeProductModel->fetchRelationsByOrder($store_product_ids)->toArray(); if(count($store_products) != count($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 = []; //项目总额 $rental_amount = 0; $product_amount = 0; // 总消费税 $total_sales_tax = 0; $advisor_1_ids = []; for ($i = 0; $i < count($store_products_params); $i++) { $store_products_param = $store_products_params[$i]; $store_product = $fmt_store_products[$store_products_param->store_product_id]; array_push($advisor_1_ids, $store_products_param->adviser_1_id); for ($j = 0; $j < $store_products_param->quantity; $j++) { array_push($order_products, [ 'order_id' => 0, 'product_id' => $store_product['product']['id'], 'store_product_id' => $store_product['id'], 'product_name' => $store_product['product']['name'], 'adviser_1_id' => isset($store_products_param->adviser_1_id) ?? null, 'adviser_1_name' => isset($store_products_param->adviser_1_id) ? $fmt_users[$store_products_param->adviser_1_id]['nickname'] : null, 'adviser_2_id' => isset($store_products_param->adviser_2_id) ?? null, 'adviser_2_name' => isset($store_products_param->adviser_2_id) ? $fmt_users[$store_products_param->adviser_2_id]['nickname'] : null, 'teacher_id' => isset($store_products_param->teacher_id) ?? null, 'teacher_name' => isset($store_products_param->teacher_id) ? $fmt_users[$store_products_param->teacher_id]['nickname'] : 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'], 'create_time' => time(), 'update_time' => time(), ]); $product_amount += $store_product['product']['real_price']; $total_sales_tax += $store_product['product']['sales_tax']; $rental_amount += ($store_product['product']['real_price'] + $store_product['product']['sales_tax']); } } $order = $this->orderModel->create([ 'no' => $this->orderModel->genOrderNo($store->id, $store->abbr), 'customer_id' => $customer->id, 'customer_name' => $customer->name_en, 'rental_amount' => $rental_amount, 'receivable_amount' => $rental_amount, 'receive_amount' => 0, 'imposed_amount' => $rental_amount, 'product_amount' => $product_amount, 'total_sales_tax' => $total_sales_tax, 'service_charge_amount' => 0, 'type' => 2, 'store_id' => $store->id, 'advisor_ids' => join(',', $advisor_1_ids), 'create_time' => time(), 'update_time' => time() ]); foreach ($order_products as &$order_product) $order_product['order_id'] = $order->id; Db::startTrans(); try { Db::table('erp_order_product')->insertAll($order_products); Db::commit(); } catch (\Exception $e) { Db::rollback(); Db::table('erp_order')->delete($order->id); return $this->fail(lang($e->getMessage())); } return $this->ok($order); } /** * @param $params * @param $channels * @return \SResult * @throws \app\exception\BaseException * @throws \think\db\exception\DataNotFoundException * @throws \think\db\exception\DbException * @throws \think\db\exception\ModelNotFoundException */ public function payment($params, $channels) { $order = $this->orderModel->findById($params); if(!$order) return $this->fail('订单不存在!'); if($order->type == 1) return $this->fail('订单状态为历史订单!不支持付款'); $pay_channels = $this->paymentChannelModel->where('is_delete', 0)->select()->toArray(); $fmt_pay_channels = array_reduce($pay_channels, function ($result, $item) { $result[$item['id']] = $item; return $result; },[]); $credit_card_configs = $this->creditCardModel->findAll()->toArray(); $fmt_credit_card_configs = array_reduce($credit_card_configs, function ($result, $item) { $result[$item['id']] = $item; return $result; },[]); // 本次总计支付费用 $total_fee = 0; // 本次信用卡支付手续费 $service_charge = 0; // 本次御龙币 $zue_coin = 0; $order_payments = []; $record_channel_names = []; for ($i = 0; $i < count($channels); $i++) { $channel = $channels[$i]; $fmt_pay_channel = $fmt_pay_channels[$channel->channel_id]; if (!$fmt_pay_channel) return $this->fail("支付渠道错误!"); array_push($record_channel_names, '['.$fmt_pay_channel['name'].']'); $item = [ 'order_id' => $order->id, 'channel_id' => $channel->channel_id, 'create_time' => time(), 'update_time' => time(), ]; if ($fmt_pay_channel['type'] == 1) { // 正常支付 predicate(isset($channel->fee) && $channel->fee > 0, '支付费用未填写'); $item['fee'] = $channel->fee; $total_fee += $channel->fee; if ($fmt_pay_channel['is_upload_code']) { predicate(isset($channel->code),'必须上传付款编号'); $item['code'] = $channel->code; } array_push($order_payments, $item); } else if($fmt_pay_channel['type'] == 2) { // 御龙币支付 predicate(isset($channel->fee) && $channel->fee > 0, '支付费用未填写'); $item['fee'] = $channel->fee; // TODO: 御龙币需求未明确 array_push($order_payments, $item); } else { for ($j = 0; $j < count($channel->credit_card); $j++) { $credit_card = $channel->credit_card[$j]; $fmt_credit_card_config = $fmt_credit_card_configs[$credit_card->credit_card_id]; if (!$fmt_credit_card_config) return $this->fail("信用卡支付渠道错误!"); predicate(isset($credit_card->fee) && $credit_card->fee > 0, '支付费用未填写'); $total_fee += $credit_card->fee; $el = [ 'order_id' => $order->id, 'channel_id' => $channel->channel_id, 'fee' => $credit_card->fee, 'credit_card_id' => $credit_card->credit_card_id, 'credit_card_name' => $fmt_credit_card_config['bank'], 'create_time' => time(), 'update_time' => time(), ]; if ($fmt_pay_channel['is_upload_code']) { predicate(isset($credit_card->code),'必须填写付款编号'); $el['code'] = $credit_card->code; } if ($fmt_credit_card_config['is_stage'] == 1) { predicate(isset($credit_card->stage_num),'必须选择分期数'); $el['stage_num'] = $credit_card->stage_num; $config = [ '6' => $fmt_credit_card_config['stage_6'], '9' => $fmt_credit_card_config['stage_9'], '12' => $fmt_credit_card_config['stage_12'], '24' => $fmt_credit_card_config['stage_24'], '36' => $fmt_credit_card_config['stage_36'], ]; $now_config = $config[$credit_card->stage_num]; predicate($now_config[0] == 1,'该分期未启用!'); if ($now_config[1] > 0) { // 收取手续费 $el['service_charge_rate'] = $now_config[1]; $now_service_charge = $el['fee'] * ($now_config[1] / 100); $el['service_charge'] = $now_service_charge; $service_charge += $now_service_charge; } } array_push($order_payments, $el); } } } // 总共需要收取这么多费用; (商品的价格 + 手续费 + 税费) - 御龙币抵扣的费用 $imposed_amount = fixed2Float($order->product_amount + ($order->service_charge_amount + $service_charge) + $order->total_sales_tax); // 总计实收金额 $receive_amount = fixed2Float($order->receive_amount + $total_fee); if (round($receive_amount) > round($imposed_amount)) return $this->fail("实收金额大于待收金额! 应该支付 {$imposed_amount}"); $order_annual_fees = []; $update_store_products = []; if (round($receive_amount) == round($imposed_amount)) { // 减库存 $order_products = $this->orderProductModel->findByOrderId($order->id)->toArray(); $store_products = $this->storeProductModel->findByIds(array_map(function ($r) {return $r['store_product_id'];}, $order_products))->toArray(); $fmt_store_products = array_reduce($store_products, function ($result, $item) { $result[$item['id']] = $item; return $result; },[]); foreach ($order_products as $order_product) { predicate($fmt_store_products[$order_product['store_product_id']]['now_stock'] > 0, lang('inventory shortage')); $fmt_store_products[$order_product['store_product_id']]['now_stock'] -= 1; if (isset($update_store_products[$order_product['store_product_id']])) { $update_store_products[$order_product['store_product_id']]['reduce_num'] += 1; } else { $update_store_products[$order_product['store_product_id']] = ['id' => $order_product['store_product_id'], 'reduce_num' => 1]; } if ($order_product['is_gather_annuity']) { array_push($order_annual_fees, [ 'order_id' => $order->id, 'order_product_id' => $order_product['product_id'], 'order_product_name' => $order_product['product_name'], 'fee' => $order_product['annuity'], 'is_pay' => 0, 'start_time' => time(), 'end_time' => time() + (365 * 24 * 60 * 60), 'create_time' => time(), 'update_time' => time(), ]); } } } Db::startTrans(); try { $update_order = [ 'rental_amount' => $imposed_amount, 'receivable_amount' => $imposed_amount, 'receive_amount' => $receive_amount, 'imposed_amount' => $imposed_amount - $receive_amount, 'service_charge_amount' => $order->service_charge_amount + $service_charge, ]; if (round($receive_amount) == round($imposed_amount)) { // 支付满了 $update_order['type'] = 2; Db::table('erp_order_product')->where('order_id', $order->id)->update(['is_pay' => 1]); if(count($order_annual_fees) > 0) { Db::table('erp_order_annual_fee')->insertAll($order_annual_fees); } if(count($update_store_products) > 0) { foreach ($update_store_products as $update) { Db::table('erp_store_product')->where('id', $update['id'])->dec('now_stock',1); Db::table('erp_store_product')->where('id', $update['id'])->inc('sale_stock',1); } } } Db::table('erp_order_proceeds')->save([ 'order_id' => $order->id, 'channels' => join(' ',$record_channel_names), 'fee' => $total_fee, 'admin_id' => $params['admin_id'], 'admin_name' => $params['admin_name'], 'create_time' => time(), 'update_time' => time(), ]); if(count($order_payments) > 0) { Db::table('erp_order_payment')->insertAll(array_map(function ($data) { return [ "order_id" => isset($data['order_id']) ? $data['order_id'] : null, "channel_id" => isset($data['channel_id']) ? $data['channel_id'] : null, "fee" => isset($data['fee']) ? $data['fee'] : null, "credit_card_id" => isset($data['credit_card_id']) ? $data['credit_card_id'] : null, "credit_card_name" => isset($data['credit_card_name']) ? $data['credit_card_name'] : null, "create_time" => isset($data['create_time']) ? $data['create_time'] : null, "update_time" => isset($data['update_time']) ? $data['update_time'] : null, "code" => isset($data['code']) ? $data['code'] : null, "stage_num" => isset($data['stage_num']) ? $data['stage_num'] : null, "service_charge_rate" => isset($data['service_charge_rate']) ? $data['service_charge_rate'] : null, "service_charge" => isset($data['service_charge']) ? $data['service_charge'] : null ]; },$order_payments)); } Db::table('erp_order')->where('id', $order->id)->update($update_order); Db::commit(); } catch (\Exception $e) { Db::rollback(); return $this->fail(lang($e->getMessage())); } return $this->ok(true); } }