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; // 总消费税 $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'], '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, 'report' => null, '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(), ]); $rental_amount += $store_product['product']['real_price']; $total_sales_tax += $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, 'total_sales_tax' => $total_sales_tax, '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->imposed_amount + $service_charge + $order->total_sales_tax); $total_fee = fixed2Float($total_fee); if (round($total_fee) > round($imposed_amount)) return $this->fail("实收金额大于待收金额! 应该支付 {$imposed_amount}"); return $this->ok($total_fee); Db::startTrans(); try { Db::table('erp_order_payment')->insertAll($order_payments); 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(), ]); $update_order = [ 'service_charge_amount' => $service_charge, 'receive_amount' => $order->receive_amount + $total_fee, 'imposed_amount' => $order->imposed_amount - $total_fee, ]; if (round($total_fee) < round($imposed_amount)) { // 未支付满 // DOTO: } else { $update_order['type'] = 2; } 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); } }