diff --git a/app/common/model/StockOrders.php b/app/common/model/StockOrders.php index f91191b..a5dc48d 100644 --- a/app/common/model/StockOrders.php +++ b/app/common/model/StockOrders.php @@ -50,7 +50,7 @@ class StockOrders extends Model 'trade_term_id', 'trade_term_snapshot', 'clearance_port_id', 'clearance_port_snapshot', 'latest_arrival_date', 'contract_exchange_rate', 'settlement_currency', 'status', 'remark', 'created_at', 'updated_at', 'deleted_at', - 'object_id', 'contract', 'is_use', 'is_final', 'approval_status', 'file_url' + 'object_id', 'contract', 'is_use', 'is_final', 'approval_status', 'file_url', 'pick_up_date', 'collect_all_date' ]; /** diff --git a/app/common/utils/pdf/template/stockOrder.stub b/app/common/utils/pdf/template/stockOrder.stub index 850f31f..2c051c1 100644 --- a/app/common/utils/pdf/template/stockOrder.stub +++ b/app/common/utils/pdf/template/stockOrder.stub @@ -140,23 +140,27 @@ 颜色/外 内饰 改装 + 官方指导价/二手挂牌价 + 优惠 单价 总价 - 官方指导价/二手挂牌价 - 优惠/二手减价 + 利润 - + + + 0): ?> + () + + - - 0): ?> @@ -166,6 +170,9 @@ + + + @@ -173,7 +180,7 @@ 合同汇率: - + 合计到岸价: @@ -193,11 +200,23 @@ 清关人: - 预计发运日期: + + + 全款收齐日: + + 预计发运日期: + + 出运方式: 国内收货港: 贸易条款/清关目的港: / - 最迟到港时间: + + + 提车日期: + + 最迟到港时间: + + @@ -241,7 +260,6 @@ -
diff --git a/app/controller/IndexController.php b/app/controller/IndexController.php index 289d5b7..b755f5b 100644 --- a/app/controller/IndexController.php +++ b/app/controller/IndexController.php @@ -96,7 +96,7 @@ class IndexController } - public function test() + public function test(Request $request) { @@ -127,8 +127,15 @@ class IndexController // $up = new UploadService(); // $res = $up->uploadLocalFile($param); // var_dump($res); - - $service = new \app\common\service\StockOrdersService(); - $service->createdPdfFile(60); + $param = $request->all(); + try { + $service = new \app\crm\service\StockOrdersService(); + $result = $service->createdPdfFile($param['id']); + return json($result); + } catch (\Throwable $th) { + //throw $th; + var_dump($th->getMessage().$th->getLine().$th->getFile()); + } + } } \ No newline at end of file diff --git a/app/crm/controller/StockOrdersController.php b/app/crm/controller/StockOrdersController.php index 45a3632..b967d76 100644 --- a/app/crm/controller/StockOrdersController.php +++ b/app/crm/controller/StockOrdersController.php @@ -58,6 +58,8 @@ class StockOrdersController extends BaseController if (isset($data['eta_ship_date'])) $data['eta_ship_date'] = date('Y-m-d', $data['eta_ship_date']); if (isset($data['biz_date'])) $data['biz_date'] = date('Y-m-d', $data['biz_date']); if (isset($data['latest_arrival_date'])) $data['latest_arrival_date'] = date('Y-m-d', $data['latest_arrival_date']); + if (isset($data['pick_up_date'])) $data['pick_up_date'] = date('Y-m-d', $data['pick_up_date']); + if (isset($data['collect_all_date'])) $data['collect_all_date'] = date('Y-m-d', $data['collect_all_date']); if (!empty($data['contract'])) { $data['contract_url'] = (new \app\common\service\OssService)->generatePrivateUrl($data['contract']); @@ -127,7 +129,9 @@ class StockOrdersController extends BaseController return $data; } - + /** + * 获取打印数据 + */ public function print(Request $request) { try { @@ -141,7 +145,21 @@ class StockOrdersController extends BaseController } } - + /** + * 启动审批 + */ + public function approval(Request $request) + { + try { + $raw = $this->service->serviceApproval($request); + $data = $this->transformData($raw, method_exists($this, 'approvalFormat') + ? [$this, 'approvalFormat'] + : null); + return $this->success($data); + } catch (\Throwable $e) { + return $this->error($e->getMessage()); + } + } public function desc(Request $request) { diff --git a/app/crm/service/StockOrdersService.php b/app/crm/service/StockOrdersService.php index 70bb4ec..a8c4732 100644 --- a/app/crm/service/StockOrdersService.php +++ b/app/crm/service/StockOrdersService.php @@ -13,6 +13,7 @@ use support\Request; use app\common\model\User; use support\exception\BusinessException; use support\Db; +use support\Model; class StockOrdersService { @@ -67,6 +68,7 @@ class StockOrdersService $config['where']['salesperson_id'] = $request->user->uid; break; case 'print': + case 'approval': $config['where']['id'] = $p['id']; break; case 'show': @@ -93,111 +95,121 @@ class StockOrdersService } - public function serviceStore(Request $request, array $data = []) - { - // 关联表较多,增加事务处理 - return Db::transaction(function () use ($request, $data) { - $data = $this->preProcess('Store', $data, $request); - $dl = $this->getDataLimitFromRequest($request); - $created = $this->logicCreate($data, $dl); // 表1 + // public function serviceStore2(Request $request, array $data = []) + // { + // // 关联表较多,增加事务处理 + // return Db::transaction(function () use ($request, $data) { + // $data = $this->preProcess('Store', $data, $request); + // $dl = $this->getDataLimitFromRequest($request); + // $created = $this->logicCreate($data, $dl); // 表1 - // 车辆 - $cifTotalAmount = 0; - $cifTotalAmountRate = 0; - $cifTotalAmountCurrency = 'CNY'; - // $profit = 0; - foreach ($data['veh_list'] as $veh) { - $veh['order_id'] = $created->id; + // // 车辆 + // $cifTotalAmount = 0; + // $cifTotalAmountRate = 0; + // $cifTotalAmountCurrency = 'CNY'; + // // $profit = 0; + // foreach ($data['veh_list'] as $veh) { + // $veh['order_id'] = $created->id; - // 唯一标识 - $uniqueIdStr = ""; - $uniqueIdStr .= $veh['sku_id']; - $uniqueIdStr .= $veh['model_snapshot']; - $uniqueIdStr .= $veh['color_interior_code']; - $uniqueIdStr .= $veh['color_exterior_code']; - $uniqueIdStr .= $veh['mileage']; - $uniqueIdStr .= json($veh['modify_list']); - $veh['unique_id'] = md5($uniqueIdStr); - $item = StockOrderItems::create($veh); // 表2 + // // 唯一标识 + // $uniqueIdStr = ""; + // $uniqueIdStr .= $veh['sku_id']; + // $uniqueIdStr .= $veh['model_snapshot']; + // $uniqueIdStr .= $veh['color_interior_code']; + // $uniqueIdStr .= $veh['color_exterior_code']; + // $uniqueIdStr .= $veh['mileage']; + // $uniqueIdStr .= json($veh['modify_list']); + // $veh['unique_id'] = md5($uniqueIdStr); + // $item = StockOrderItems::create($veh); // 表2 - // 金额 // 表3 - // $item->addMoney('official_price', $veh['official_price']['currency'], $veh['official_price']['amount'], $veh['official_price']['rate'], '官方指导价'); - // $item->addMoney('discount_price', $veh['discount_price']['currency'], $veh['discount_price']['amount'], $veh['discount_price']['rate'], '优惠价'); - if ($veh['unit_price']['amount']) { - $item->addMoney('unit_price', $veh['unit_price']['currency'], $veh['unit_price']['amount'], $veh['unit_price']['rate'], '单价'); - } - if ($veh['total_price']['amount']) { - $item->addMoney('total_price', $veh['total_price']['currency'], $veh['total_price']['amount'], $veh['total_price']['rate'], '总价'); - } - if ($veh['handling_fee']['amount']) { - $item->addMoney('handling_fee', $veh['handling_fee']['currency'], $veh['handling_fee']['amount'], $veh['handling_fee']['rate'], '手续费'); - } - if ($veh['fob_transport_fee']['amount']) { - $item->addMoney('fob_transport_fee', $veh['fob_transport_fee']['currency'], $veh['fob_transport_fee']['amount'], $veh['fob_transport_fee']['rate'], 'FOB运输费'); - } - if ($veh['port_misc_fee']['amount']) { - $item->addMoney('port_misc_fee', $veh['port_misc_fee']['currency'], $veh['port_misc_fee']['amount'], $veh['port_misc_fee']['rate'], '港杂'); - } - if ($veh['retrofit_fee']['amount']) { - $item->addMoney('retrofit_fee', $veh['retrofit_fee']['currency'], $veh['retrofit_fee']['amount'], $veh['retrofit_fee']['rate'], '改装费'); - } + // // 金额 // 表3 + // // $item->addMoney('official_price', $veh['official_price']['currency'], $veh['official_price']['amount'], $veh['official_price']['rate'], '官方指导价'); + // // $item->addMoney('discount_price', $veh['discount_price']['currency'], $veh['discount_price']['amount'], $veh['discount_price']['rate'], '优惠价'); + // if ($veh['unit_price']['amount']) { + // $item->addMoney('unit_price', $veh['unit_price']['currency'], $veh['unit_price']['amount'], $veh['unit_price']['rate'], '单价'); + // } + // if ($veh['total_price']['amount']) { + // $item->addMoney('total_price', $veh['total_price']['currency'], $veh['total_price']['amount'], $veh['total_price']['rate'], '总价'); + // } + // if ($veh['handling_fee']['amount']) { + // $item->addMoney('handling_fee', $veh['handling_fee']['currency'], $veh['handling_fee']['amount'], $veh['handling_fee']['rate'], '手续费'); + // } + // if ($veh['fob_transport_fee']['amount']) { + // $item->addMoney('fob_transport_fee', $veh['fob_transport_fee']['currency'], $veh['fob_transport_fee']['amount'], $veh['fob_transport_fee']['rate'], 'FOB运输费'); + // } + // if ($veh['port_misc_fee']['amount']) { + // $item->addMoney('port_misc_fee', $veh['port_misc_fee']['currency'], $veh['port_misc_fee']['amount'], $veh['port_misc_fee']['rate'], '港杂'); + // } + // if ($veh['retrofit_fee']['amount']) { + // $item->addMoney('retrofit_fee', $veh['retrofit_fee']['currency'], $veh['retrofit_fee']['amount'], $veh['retrofit_fee']['rate'], '改装费'); + // } + // if ($veh['ocean_freight']['amount']) { + // $item->addMoney('ocean_freight', $veh['ocean_freight']['currency'], $veh['ocean_freight']['amount'], $veh['ocean_freight']['rate'], '海运费'); + // } - // 二手车 or 新车 - if ($veh['mileage'] > 0) { - if ($veh['listing_price']['amount']) { - $item->addMoney('listing_price', $veh['listing_price']['currency'], $veh['listing_price']['amount'], $veh['listing_price']['rate'], '二手挂牌价'); - } - if ($veh['reduction_price']['amount']) { - $item->addMoney('reduction_price', $veh['reduction_price']['currency'], $veh['reduction_price']['amount'], $veh['reduction_price']['rate'], '二手减价'); - } + // // 二手车 or 新车 + // if ($veh['mileage'] > 0) { + // if ($veh['listing_price']['amount']) { + // $item->addMoney('listing_price', $veh['listing_price']['currency'], $veh['listing_price']['amount'], $veh['listing_price']['rate'], '二手挂牌价'); + // } + // if ($veh['reduction_price']['amount']) { + // $item->addMoney('reduction_price', $veh['reduction_price']['currency'], $veh['reduction_price']['amount'], $veh['reduction_price']['rate'], '二手减价'); + // } - $ttPrice = ($veh['listing_price']['amount'] / $created->contract_exchange_rate); - $ddPrice = $veh['reduction_price']['amount']; - } else { - if ($veh['official_price']['amount']) { - $item->addMoney('official_price', $veh['official_price']['currency'], $veh['official_price']['amount'], $veh['official_price']['rate'], '官方指导价'); - } - if ($veh['discount_price']['amount'] ) { - $item->addMoney('discount_price', $veh['discount_price']['currency'], $veh['discount_price']['amount'], $veh['discount_price']['rate'], '优惠价'); - } + // $ttPrice = ($veh['listing_price']['amount'] / $created->contract_exchange_rate); + // $ddPrice = $veh['reduction_price']['amount']; + // } else { + // if ($veh['official_price']['amount']) { + // $item->addMoney('official_price', $veh['official_price']['currency'], $veh['official_price']['amount'], $veh['official_price']['rate'], '官方指导价'); + // } + // if ($veh['discount_price']['amount'] ) { + // $item->addMoney('discount_price', $veh['discount_price']['currency'], $veh['discount_price']['amount'], $veh['discount_price']['rate'], '优惠价'); + // } - $ttPrice = ($veh['official_price']['amount'] / $created->contract_exchange_rate); - $ddPrice = $veh['discount_price']['amount']; - } + // $ttPrice = ($veh['official_price']['amount'] / $created->contract_exchange_rate); + // $ddPrice = $veh['discount_price']['amount']; + // } - // 利润 - $profit = (float)$veh['unit_price']['amount'] - (float)$ttPrice - (float)$ddPrice - (float)$veh['handling_fee']['amount'] - (float)$veh['fob_transport_fee']['amount'] - (float)$veh['port_misc_fee']['amount'] - (float)$veh['retrofit_fee']['amount']; - $item->addMoney('profit', $veh['unit_price']['currency'], $profit, $veh['unit_price']['rate'], '利润'); + // // 利润 + // $profit = (float)$veh['unit_price']['amount'] + // - (float)$ttPrice + // - (float)$ddPrice + // - (float)$veh['handling_fee']['amount'] + // - (float)$veh['fob_transport_fee']['amount'] + // - (float)$veh['port_misc_fee']['amount'] + // - (float)$veh['retrofit_fee']['amount'] + // - (float)$veh['ocean_freight']['amount']; + // $item->addMoney('profit', $veh['unit_price']['currency'], $profit, $veh['unit_price']['rate'], '利润'); - // cif_total_amount - $cifTotalAmount += $veh['total_price']['amount']; - $cifTotalAmountRate = $veh['retrofit_fee']['rate']; - $cifTotalAmountCurrency = $veh['retrofit_fee']['currency']; + // // cif_total_amount + // $cifTotalAmount += $veh['total_price']['amount']; + // $cifTotalAmountRate = $veh['retrofit_fee']['rate']; + // $cifTotalAmountCurrency = $veh['retrofit_fee']['currency']; - // 改装 - if (count($veh['modify_list']) > 0) { - foreach ($veh['modify_list'] as $modify) { - $modify['order_item_id'] = $item->id; - StockOrderItemOptions::create($modify); // 表4 - } - } - } + // // 改装 + // if (count($veh['modify_list']) > 0) { + // foreach ($veh['modify_list'] as $modify) { + // $modify['order_item_id'] = $item->id; + // StockOrderItemOptions::create($modify); // 表4 + // } + // } + // } - // 计算&&插入 表1 - $created->addMoney('cif_total_amount', $cifTotalAmountCurrency, $cifTotalAmount, $cifTotalAmountRate, '合计到岸价'); + // // 计算&&插入 表1 + // $created->addMoney('cif_total_amount', $cifTotalAmountCurrency, $cifTotalAmount, $cifTotalAmountRate, '合计到岸价'); - // 账户 - if (count($data['account_list']) > 0) { - foreach ($data['account_list'] as $account) { - $account['order_id'] = $created->id; - $account['remit_date'] = strtotime($account['remit_date']); - StockOrderAccounts::create($account); // 表5 - } - } + // // 账户 + // if (count($data['account_list']) > 0) { + // foreach ($data['account_list'] as $account) { + // $account['order_id'] = $created->id; + // $account['remit_date'] = strtotime($account['remit_date']); + // StockOrderAccounts::create($account); // 表5 + // } + // } - return $this->postProcess('Store', $created); - }); - } + // return $this->postProcess('Store', $created); + // }); + // } public function beforeServiceStore($data, Request $request) { @@ -209,7 +221,12 @@ class StockOrdersService $data['latest_arrival_date'] = strtotime($data['latest_arrival_date']); $data['salesperson_id'] = $userId; $data['salesperson_snapshot'] = User::where('id', $userId)->value('name') ?? ''; + $data['approval_status'] = $data['approval_status'] == 1 ? 1 : 0; + if ($data['is_final'] == 1) { + $data['pick_up_date'] = strtotime($data['pick_up_date']); + $data['collect_all_date'] = strtotime($data['collect_all_date']); + } return $data; } @@ -225,16 +242,27 @@ class StockOrdersService } } // 启动审批 - $appro = new \app\common\utils\approval\service\ApprovalFlowService(); - $result = $appro->start('stock_order_flow', 'stock_orders', $res->id, $res->toArray(), $res->salesperson_id); - var_dump($result); - - // 异步生成pdf文件 - \Webman\RedisQueue\Redis::send('stock-order-pdf', ['id'=>$res->id]); + if ($res->approval_status == 1) { + $this->startApproval($res); + } return $res; } + /** + * 启动审批 + */ + public function startApproval($item) + { + // 启动审批 + $appro = new \app\common\utils\approval\service\ApprovalFlowService(); + $appro->start('stock_order_flow', 'stock_orders', $item->id, $item->toArray(), $item->salesperson_id); + // 异步生成pdf文件 + \Webman\RedisQueue\Redis::send('stock-order-pdf', ['id'=>$item->id]); + } + /** + * 创建PDF文件 + */ public function createdPdfFile($id) { $config = []; @@ -268,17 +296,6 @@ class StockOrdersService $fileName ); - // // 在线预览 - // return new \support\Response(200, [ - // 'Content-Type' => 'application/pdf', - // 'Content-Disposition' => 'inline; filename="stock-order.pdf"', - // ], $pdfBin); - - // $url = [ - // 'file_name' => $fileName, - // 'file_url' => getenv('MAIN_DOMAIN').'/pdf/'.$fileName - // ]; - // 上传云端 $param = [ 'path' => $dir . $fileName, @@ -298,18 +315,144 @@ class StockOrdersService return $res; } - public function servicePrint(Request $request) - { - $config = $this->buildQueryConfig($request, 'show'); - $item = $this->logicShow($config); - return $this->postProcess('Print', $item); - } + // public function pdfData2($item) + // { + // $vehList = []; + // $mv = []; + // $mfy = ''; + // $index = 0; + // foreach ($item->items as $k => $v) { + // // 存在则数量加1 + // if (count($vehList) > 0 && isset($vehList[$v->unique_id])) { + // $vehList[$v->unique_id]['num'] += 1; + // $vehList[$v->unique_id]['total_price'] += $vehList[$v->unique_id]['unit_price']; + // $vehList[$v->unique_id]['total_price_text'] = $vehList[$v->unique_id]['total_price_symbol'].number_format($vehList[$v->unique_id]['total_price'], 2, '.', ','); + // continue; + // } + // $index += 1; + + // // 处理金额 + // foreach ($v->moneyValues as $money) { + // $mv[$money->field] = [ + // 'currency' => $money->currency, + // 'amount' => $money->amount, + // 'rate' => $money->exchange_rate, + // 'currency_symbol' => SysCurrency::where('currency_code', $money->currency)->value('currency_symbol'), + // ]; + // } + + // // 处理改装 + // foreach ($v->options as $my) { + // $mfy .= $my->option_name_snapshot.' '; + // } + + // // 处理结果集 + // $vehList[$v->unique_id] = [ + // 'index' => $index, + // 'model_snapshot' => $v->model_snapshot, + // 'color_interior_snapshot' => $v->color_interior_snapshot, + // 'color_exterior_snapshot' => $v->color_exterior_snapshot, + // 'num' => 1, + // 'modify' => $mfy, + // 'mileage' => $v->mileage, + // 'unit_price' => $mv['unit_price']['amount'], + // 'total_price' => $mv['total_price']['amount'], + // 'unit_price_symbol' => $mv['unit_price']['currency_symbol'], + // 'total_price_symbol' => $mv['total_price']['currency_symbol'], + // 'unit_price_text' => $mv['unit_price']['currency_symbol'].number_format($mv['unit_price']['amount'], 2, '.', ','), + // 'total_price_text' => $mv['total_price']['currency_symbol'].number_format($mv['total_price']['amount'], 2, '.', ',') + // ]; + + // // 根据里程处理 新车or二手车 + // if ($v->mileage > 0) { + // if (isset($mv['reduction_price'])) { + // $vehList[$v->unique_id]['reduction_price'] = $mv['reduction_price']['amount']; + // $vehList[$v->unique_id]['reduction_price_symbol'] = $mv['reduction_price']['currency_symbol']; + // $vehList[$v->unique_id]['reduction_price_text'] = $mv['reduction_price']['currency_symbol'].number_format($mv['reduction_price']['amount'], 2, '.', ','); + // } + // $vehList[$v->unique_id]['listing_price'] = $mv['listing_price']['amount']; + // $vehList[$v->unique_id]['listing_price_symbol'] = $mv['listing_price']['currency_symbol']; + // $vehList[$v->unique_id]['listing_price_text'] = $mv['listing_price']['currency_symbol'].number_format($mv['listing_price']['amount'], 2, '.', ','); + // } else { + // if (isset($mv['discount_price'])) { + // $vehList[$v->unique_id]['discount_price'] = $mv['discount_price']['amount']; + // $vehList[$v->unique_id]['discount_price_symbol'] = $mv['discount_price']['currency_symbol']; + // $vehList[$v->unique_id]['discount_price_text'] = $mv['discount_price']['currency_symbol'].number_format($mv['discount_price']['amount'], 2, '.', ','); + // } + // $vehList[$v->unique_id]['official_price'] = $mv['official_price']['amount']; + // $vehList[$v->unique_id]['official_price_symbol'] = $mv['official_price']['currency_symbol']; + // $vehList[$v->unique_id]['official_price_text'] = $mv['official_price']['currency_symbol'].number_format($mv['official_price']['amount'], 2, '.', ','); + // } + // } + + // $accList = []; + // $accIndex = 1; + // foreach ($item->accounts as $k => $v) { + // $accList[] = [ + // 'index' => '收款'.$k + 1, + // 'remit_country_name_snapshot' => $v->remit_country_name_snapshot, + // 'remit_date' => date('Y-m-d', $v->remit_date), + // 'currency_name_snapshot' => $v->currency_name_snapshot, + // 'account_name_snapshot' => $v->account_name_snapshot, + // 'remitter_name' => $v->remitter_name, + // 'amount' => $v->amount, + // ]; + // $accIndex += 1; + // } + + // $cifTotalAmount = 0.00; + // if ($item->moneyValues) { + // $cifTotalAmountSysboml = SysCurrency::where('currency_code', $item->moneyValues->currency)->value('currency_symbol'); + // $cifTotalAmount = $cifTotalAmountSysboml.sprintf("%.2f", $item->moneyValues->amount, $item->moneyValues->exchange_rate); + // } + + // $profit = 0.00; + // $profit = $this->calculateProfit($mv, $item); + + // $veh = [ + // 'order_no' => $item->order_no, + // 'salesperson_snapshot' => $item->salesperson_snapshot, + // 'sign_img_url' => (!empty($item->salesperson->sign_img))?(new \app\common\service\OssService)->generatePrivateUrl($item->salesperson->sign_img):'', + // 'created_at' => date('Y-m-d', strtotime($item->created_at)), + + // 'pi_no' => $item->pi_no, + // 'biz_date' => date('Y-m-d', $item->biz_date), + // 'clearance_country_snapshot' => $item->clearance_country_snapshot, + // 'customer_source_snapshot' => $item->customer_source_snapshot, + // 'customer_snapshot' => $item->customer_snapshot, + // 'customer_country_snapshot' => $item->customer_country_snapshot, + + // // 订单项 + // 'veh_list' => $vehList, + + // 'contract_exchange_rate' => $item->contract_exchange_rate, + // 'cif_total_amount' => $item->cif_total_amount, + + // 'declarant_name' => $item->declarant_name, + // 'eta_ship_date' => date('Y-m-d', $item->eta_ship_date), + // 'shipping_method_snapshot' => $item->shipping_method_snapshot, + // 'domestic_port_snapshot' => $item->domestic_port_snapshot, + // 'trade_term_snapshot' => $item->trade_term_snapshot, + // 'clearance_port_snapshot' => $item->clearance_port_snapshot, + // 'latest_arrival_date' => date('Y-m-d', $item->latest_arrival_date), + + // // 账户 + // 'account_list' => $accList, + // 'acc_index' => $accIndex, + // 'cif_total_amount' => $cifTotalAmount, + // 'profit' => $profit + // ]; + + // return $veh; + // } public function pdfData($item) { $vehList = []; $index = 0; + $totalProfit = 0; // 总利润 + foreach ($item->items as $k => $v) { // 存在则数量加1 if (count($vehList) > 0 && isset($vehList[$v->unique_id])) { @@ -318,117 +461,508 @@ class StockOrdersService $vehList[$v->unique_id]['total_price_text'] = $vehList[$v->unique_id]['total_price_symbol'].number_format($vehList[$v->unique_id]['total_price'], 2, '.', ','); continue; } + $index += 1; - // 处理金额 + + // 处理金额 (每次循环重新初始化) $mv = []; foreach ($v->moneyValues as $money) { $mv[$money->field] = [ 'currency' => $money->currency, 'amount' => $money->amount, 'rate' => $money->exchange_rate, - 'currency_symbol' => SysCurrency::where('currency_code', $money->currency)->value('currency_symbol'), + 'currency_symbol' => SysCurrency::where('currency_code', $money->currency)->value('currency_symbol'), ]; } - // 处理改装 + + // 处理改装 (每次循环重新初始化) $mfy = ''; foreach ($v->options as $my) { $mfy .= $my->option_name_snapshot.' '; } + // 计算单项利润并累加到总利润 + $itemProfit = $this->calculateProfit($mv, $item); + $totalProfit += $itemProfit; + // 处理结果集 - $vehList[$v->unique_id] = [ - 'index' => $index, - 'model_snapshot' => $v->model_snapshot, + $vehListItem = [ + 'index' => $index, + 'model_snapshot' => $v->model_snapshot, 'color_interior_snapshot' => $v->color_interior_snapshot, - 'color_exterior_snapshot' => $v->color_exterior_snapshot, - 'num' => 1, - 'modify' => $mfy, - 'mileage' => $v->mileage, - 'unit_price' => $mv['unit_price']['amount'], - 'total_price' => $mv['total_price']['amount'], - 'unit_price_symbol' => $mv['unit_price']['currency_symbol'], - 'total_price_symbol' => $mv['total_price']['currency_symbol'], - 'unit_price_text' => $mv['unit_price']['currency_symbol'].number_format($mv['unit_price']['amount'], 2, '.', ','), - 'total_price_text' => $mv['total_price']['currency_symbol'].number_format($mv['total_price']['amount'], 2, '.', ',') + 'color_exterior_snapshot' => $v->color_exterior_snapshot, + 'num' => 1, + 'modify' => $mfy, + 'mileage' => $v->mileage, + 'unit_price' => $mv['unit_price']['amount'] ?? 0, + 'total_price' => $mv['total_price']['amount'] ?? 0, + 'profit' => $itemProfit, // 单项利润 + 'profit_symbol' => $mv['unit_price']['currency_symbol'] ?? '', + 'profit_text' => isset($mv['unit_price']['currency_symbol']) ? + $mv['unit_price']['currency_symbol'].number_format($itemProfit, 2, '.', ',') : '0.00', + 'unit_price_symbol' => $mv['unit_price']['currency_symbol'] ?? '', + 'total_price_symbol' => $mv['total_price']['currency_symbol'] ?? '', + 'unit_price_text' => isset($mv['unit_price']['currency_symbol']) ? + $mv['unit_price']['currency_symbol'].number_format($mv['unit_price']['amount'], 2, '.', ',') : '0.00', + 'total_price_text' => isset($mv['total_price']['currency_symbol']) ? + $mv['total_price']['currency_symbol'].number_format($mv['total_price']['amount'], 2, '.', ',') : '0.00' ]; // 根据里程处理 新车or二手车 if ($v->mileage > 0) { + // 二手车 if (isset($mv['reduction_price'])) { - $vehList[$v->unique_id]['reduction_price'] = $mv['reduction_price']['amount']; - $vehList[$v->unique_id]['reduction_price_symbol'] = $mv['reduction_price']['currency_symbol']; - $vehList[$v->unique_id]['reduction_price_text'] = $mv['reduction_price']['currency_symbol'].number_format($mv['reduction_price']['amount'], 2, '.', ','); + $vehListItem['reduction_price'] = $mv['reduction_price']['amount']; + $vehListItem['reduction_price_symbol'] = $mv['reduction_price']['currency_symbol']; + $vehListItem['reduction_price_text'] = $mv['reduction_price']['currency_symbol'].number_format($mv['reduction_price']['amount'], 2, '.', ','); + } + + if (isset($mv['listing_price'])) { + $vehListItem['listing_price'] = $mv['listing_price']['amount']; + $vehListItem['listing_price_symbol'] = $mv['listing_price']['currency_symbol']; + $vehListItem['listing_price_text'] = $mv['listing_price']['currency_symbol'].number_format($mv['listing_price']['amount'], 2, '.', ','); } - $vehList[$v->unique_id]['listing_price'] = $mv['listing_price']['amount']; - $vehList[$v->unique_id]['listing_price_symbol'] = $mv['listing_price']['currency_symbol']; - $vehList[$v->unique_id]['listing_price_text'] = $mv['listing_price']['currency_symbol'].number_format($mv['listing_price']['amount'], 2, '.', ','); } else { + // 新车 if (isset($mv['discount_price'])) { - $vehList[$v->unique_id]['discount_price'] = $mv['discount_price']['amount']; - $vehList[$v->unique_id]['discount_price_symbol'] = $mv['discount_price']['currency_symbol']; - $vehList[$v->unique_id]['discount_price_text'] = $mv['discount_price']['currency_symbol'].number_format($mv['discount_price']['amount'], 2, '.', ','); + $vehListItem['discount_price'] = $mv['discount_price']['amount']; + $vehListItem['discount_price_symbol'] = $mv['discount_price']['currency_symbol']; + $vehListItem['discount_price_text'] = $mv['discount_price']['currency_symbol'].number_format($mv['discount_price']['amount'], 2, '.', ','); + } + + if (isset($mv['official_price'])) { + $vehListItem['official_price'] = $mv['official_price']['amount']; + $vehListItem['official_price_symbol'] = $mv['official_price']['currency_symbol']; + $vehListItem['official_price_text'] = $mv['official_price']['currency_symbol'].number_format($mv['official_price']['amount'], 2, '.', ','); } - $vehList[$v->unique_id]['official_price'] = $mv['official_price']['amount']; - $vehList[$v->unique_id]['official_price_symbol'] = $mv['official_price']['currency_symbol']; - $vehList[$v->unique_id]['official_price_text'] = $mv['official_price']['currency_symbol'].number_format($mv['official_price']['amount'], 2, '.', ','); } + + $vehList[$v->unique_id] = $vehListItem; } $accList = []; - $accIndex = 1; foreach ($item->accounts as $k => $v) { $accList[] = [ - 'index' => '收款'.$k + 1, - 'remit_country_name_snapshot' => $v->remit_country_name_snapshot, - 'remit_date' => date('Y-m-d', $v->remit_date), - 'currency_name_snapshot' => $v->currency_name_snapshot, - 'account_name_snapshot' => $v->account_name_snapshot, - 'remitter_name' => $v->remitter_name, - 'amount' => $v->amount, + 'index' => '收款'.($k + 1), + 'remit_country_name_snapshot' => $v->remit_country_name_snapshot, + 'remit_date' => date('Y-m-d', $v->remit_date), + 'currency_name_snapshot' => $v->currency_name_snapshot, + 'account_name_snapshot' => $v->account_name_snapshot, + 'remitter_name' => $v->remitter_name, + 'amount' => $v->amount, ]; - $accIndex += 1; } $cifTotalAmount = 0.00; + $cifTotalAmountSymbol = ''; if ($item->moneyValues) { - $cifTotalAmountSysboml = SysCurrency::where('currency_code', $item->moneyValues->currency)->value('currency_symbol'); - $cifTotalAmount = $cifTotalAmountSysboml.sprintf("%.2f", $item->moneyValues->amount, $item->moneyValues->exchange_rate); + $cifTotalAmountSymbol = SysCurrency::where('currency_code', $item->moneyValues->currency)->value('currency_symbol'); + $cifTotalAmount = $cifTotalAmountSymbol.sprintf("%.2f", $item->moneyValues->amount); } $veh = [ - 'order_no' => $item->order_no, - 'salesperson_snapshot' => $item->salesperson_snapshot, - // 'sign_img' => $item->salesperson->sign_img, - 'sign_img_url' => (!empty($item->salesperson->sign_img))?(new \app\common\service\OssService)->generatePrivateUrl($item->salesperson->sign_img):'', - 'created_at' => date('Y-m-d', strtotime($item->created_at)), + 'order_no' => $item->order_no, + 'salesperson_snapshot' => $item->salesperson_snapshot, + 'sign_img_url' => (!empty($item->salesperson->sign_img)) ? + (new \app\common\service\OssService)->generatePrivateUrl($item->salesperson->sign_img) : '', + 'created_at' => date('Y-m-d', strtotime($item->created_at)), - 'pi_no' => $item->pi_no, - 'biz_date' => date('Y-m-d', $item->biz_date), - 'clearance_country_snapshot' => $item->clearance_country_snapshot, - 'customer_source_snapshot' => $item->customer_source_snapshot, - 'customer_snapshot' => $item->customer_snapshot, - 'customer_country_snapshot' => $item->customer_country_snapshot, + 'pi_no' => $item->pi_no, + 'biz_date' => date('Y-m-d', $item->biz_date), + 'clearance_country_snapshot' => $item->clearance_country_snapshot, + 'customer_source_snapshot' => $item->customer_source_snapshot, + 'customer_snapshot' => $item->customer_snapshot, + 'customer_country_snapshot' => $item->customer_country_snapshot, // 订单项 - 'veh_list' => $vehList, + 'veh_list' => array_values($vehList), // 重新索引数组 - 'contract_exchange_rate' => $item->contract_exchange_rate, - 'cif_total_amount' => $item->cif_total_amount, + 'contract_exchange_rate' => $item->contract_exchange_rate, + 'cif_total_amount' => $item->cif_total_amount, - 'declarant_name' => $item->declarant_name, - 'eta_ship_date' => date('Y-m-d', $item->eta_ship_date), - 'shipping_method_snapshot' => $item->shipping_method_snapshot, - 'domestic_port_snapshot' => $item->domestic_port_snapshot, - 'trade_term_snapshot' => $item->trade_term_snapshot, - 'clearance_port_snapshot' => $item->clearance_port_snapshot, - 'latest_arrival_date' => date('Y-m-d', $item->latest_arrival_date), + 'declarant_name' => $item->declarant_name, + 'eta_ship_date' => date('Y-m-d', $item->eta_ship_date), + 'shipping_method_snapshot' => $item->shipping_method_snapshot, + 'domestic_port_snapshot' => $item->domestic_port_snapshot, + 'trade_term_snapshot' => $item->trade_term_snapshot, + 'clearance_port_snapshot' => $item->clearance_port_snapshot, + 'latest_arrival_date' => date('Y-m-d', $item->latest_arrival_date), + 'pick_up_date' => date('Y-m-d', $item->pick_up_date), + 'collect_all_date' => date('Y-m-d', $item->collect_all_date), + 'is_final' => $item->is_final, // 账户 'account_list' => $accList, - 'acc_index' => $accIndex, - 'cif_total_amount' => $cifTotalAmount + 'acc_index' => count($accList)+1, + 'cif_total_amount' => $cifTotalAmount, + 'cif_total_amount_symbol' => $cifTotalAmountSymbol, + 'profit' => number_format($totalProfit, 2, '.', ''), + 'profit_symbol' => $cifTotalAmountSymbol // 假设利润使用相同货币 ]; - return $veh; } + + + /** + * 打印数据 + */ + public function servicePrint(Request $request) + { + $config = $this->buildQueryConfig($request, 'show'); + $item = $this->logicShow($config); + return $this->postProcess('Print', $item); + } + + /** + * 审批 + */ + public function serviceApproval(Request $request) + { + $config = $this->buildQueryConfig($request, 'approval'); + $this->logicUpdateBy($config, [ + 'approval_status' => 1 + ]); + $item = $this->logicShow($config); + $this->startApproval($item); + return $this->postProcess('Approval', $item); + } + + /** + * 创建 + * + * @param Request $request + * @param array $data + * @return mixed + */ + public function serviceStore(Request $request, array $data = []) + { + // 关联表较多,增加事务处理 + return Db::transaction(function () use ($request, $data) { + $data = $this->preProcess('Store', $data, $request); + $dl = $this->getDataLimitFromRequest($request); + $created = $this->logicCreate($data, $dl); + + // 处理车辆和账户信息 + $this->processOrderItems($created, $data); + + return $this->postProcess('Store', $created); + }); + } + + protected function onlyFillableData(Model|string $model, array $data, array $extraWhitelist = []): array + { + // 兼容传类名或实例 + $m = \is_string($model) ? new $model : $model; + // 1) 优先使用 fillable + $keys = $m->getFillable(); + // 2) 若没配置 fillable(常见:用 guarded),回退到完整表字段,避免误伤 + if (empty($keys)) { + $keys = $m->getConnection() + ->getSchemaBuilder() + ->getColumnListing($m->getTable()); + } + // 3) 允许额外白名单(如虚拟字段、JSON映射字段) + if ($extraWhitelist) { + $keys = array_merge($keys, $extraWhitelist); + } + return array_intersect_key($data, array_flip($keys)); + } + + /** + * 更新前处理 + * + * @param array $data + * @param Request $request + * @return array + */ + public function beforeServiceUpdate($data, Request $request) + { + $data['biz_date'] = strtotime($data['biz_date']); + $data['eta_ship_date'] = strtotime($data['eta_ship_date']); + $data['latest_arrival_date'] = strtotime($data['latest_arrival_date']); + $data['approval_status'] = $data['approval_status'] == 1 ? 1 : 0; + return $data; + } + + /** + * 更新后处理 + * + * @param mixed $res + * @return mixed + */ + protected function afterServiceUpdate($res) + { + // 启动审批 + if ($res->approval_status == 1) { + $this->startApproval($res); + } + return $res; + } + + /** + * 更新 + * + * @param Request $request + * @param array $data + * @return mixed + */ + public function serviceUpdate(Request $request, array $data = []) + { + // 关联表较多,增加事务处理 + return Db::transaction(function () use ($request, $data) { + $data = $this->preProcess('Update', $data, $request); + $config = $this->buildQueryConfig($request, 'update'); + // 过滤掉非库字段 + $dbData = $this->onlyFillableData($config['model'], $data); + // 更新主表 + $updated = $this->logicUpdateBy($config, $dbData); + // 获取更新后的数据 + $order = $this->logicShow($config); + // 处理车辆和账户信息 + $this->processOrderItems($order, $data, true); + return $this->postProcess('Update', $order); + }); + } + + /** + * 处理订单项(车辆和账户) + * @param StockOrders $order 订单对象 + * @param array $data 数据 + * @param bool $isUpdate 是否为更新操作 + */ + private function processOrderItems($order, array $data, bool $isUpdate = false): void + { + // 如果是更新操作,先删除原有的关联数据 + if ($isUpdate) { + $this->clearExistingOrderItems($order->id); + } + + // 处理车辆项 + $this->processVehicleItems($order, $data['veh_list'] ?? []); + + // 处理账户项 + $this->processAccountItems($order, $data['account_list'] ?? []); + } + + /** + * (更新时)清除已存在的订单项 + * @param int $orderId 订单ID + */ + private function clearExistingOrderItems(int $orderId): void + { + // 删除车辆改装项 + StockOrderItemOptions::whereHas('item', function ($query) use ($orderId) { + $query->where('order_id', $orderId); + })->delete(); + + // 删除车辆项及其相关金额记录 + $orderItems = StockOrderItems::where('order_id', $orderId)->get(); + foreach ($orderItems as $item) { + // 删除车辆项的金额记录 + Db::table('veh_money_value') + ->where('object_scene', 'stock_order_items') + ->where('object_id', $item->id) + ->delete(); + } + + // 删除车辆项 + StockOrderItems::where('order_id', $orderId)->delete(); + + // 删除订单本身的金额记录 + Db::table('veh_money_value') + ->where('object_scene', 'stock_orders') + ->where('object_id', $orderId) + ->delete(); + + // 删除账户项 + StockOrderAccounts::where('order_id', $orderId)->delete(); + } + + /** + * 处理车辆项 + */ + private function processVehicleItems($order, array $vehList): void + { + $cifTotalAmount = 0; + $cifTotalAmountRate = 0; + $cifTotalAmountCurrency = 'CNY'; + + foreach ($vehList as $veh) { + $veh['order_id'] = $order->id; + $veh['unique_id'] = $this->generateVehicleUniqueId($veh); + + $item = StockOrderItems::create($veh); + + // 处理金额信息 + $this->processVehiclePrices($item, $veh); + + // 计算利润 + $profit = $this->calculateProfit($veh, $order); + $item->addMoney('profit', $veh['unit_price']['currency'], $profit, $veh['unit_price']['rate'], '利润'); + + // 累计到岸价 + $cifTotalAmount += $veh['total_price']['amount'] ?? 0; + if (isset($veh['retrofit_fee']['rate'])) { + $cifTotalAmountRate = $veh['retrofit_fee']['rate']; + } + if (isset($veh['retrofit_fee']['currency'])) { + $cifTotalAmountCurrency = $veh['retrofit_fee']['currency']; + } + + // 处理改装项 + $this->processModificationItems($item->id, $veh['modify_list'] ?? []); + } + + // 保存合计到岸价 + $order->addMoney('cif_total_amount', $cifTotalAmountCurrency, $cifTotalAmount, $cifTotalAmountRate, '合计到岸价'); + } + + /** + * 生成车辆唯一标识 + */ + private function generateVehicleUniqueId(array $veh): string + { + $uniqueIdStr = ""; + $uniqueIdStr .= $veh['sku_id'] ?? ''; + $uniqueIdStr .= $veh['model_snapshot'] ?? ''; + $uniqueIdStr .= $veh['color_interior_code'] ?? ''; + $uniqueIdStr .= $veh['color_exterior_code'] ?? ''; + $uniqueIdStr .= $veh['mileage'] ?? ''; + $uniqueIdStr .= json_encode($veh['modify_list'] ?? []); + + return md5($uniqueIdStr); + } + + /** + * 处理车辆价格信息 + */ + private function processVehiclePrices($item, array $veh): void + { + // 基础费用 + $priceFields = [ + 'unit_price' => '单价', + 'total_price' => '总价', + 'handling_fee' => '手续费', + 'fob_transport_fee' => 'FOB运输费', + 'port_misc_fee' => '港杂', + 'retrofit_fee' => '改装费', + 'ocean_freight' => '海运费' + ]; + + foreach ($priceFields as $field => $description) { + if (!empty($veh[$field]['amount'])) { + $item->addMoney( + $field, + $veh[$field]['currency'], + $veh[$field]['amount'], + $veh[$field]['rate'], + $description + ); + } + } + + // 根据里程处理新车或二手车价格 + if (!empty($veh['mileage']) && $veh['mileage'] > 0) { + // 二手车 + if (!empty($veh['listing_price']['amount'])) { + $item->addMoney( + 'listing_price', + $veh['listing_price']['currency'], + $veh['listing_price']['amount'], + $veh['listing_price']['rate'], + '二手挂牌价' + ); + } + + if (!empty($veh['reduction_price']['amount'])) { + $item->addMoney( + 'reduction_price', + $veh['reduction_price']['currency'], + $veh['reduction_price']['amount'], + $veh['reduction_price']['rate'], + '二手减价' + ); + } + } else { + // 新车 + if (!empty($veh['official_price']['amount'])) { + $item->addMoney( + 'official_price', + $veh['official_price']['currency'], + $veh['official_price']['amount'], + $veh['official_price']['rate'], + '官方指导价' + ); + } + + if (!empty($veh['discount_price']['amount'])) { + $item->addMoney( + 'discount_price', + $veh['discount_price']['currency'], + $veh['discount_price']['amount'], + $veh['discount_price']['rate'], + '优惠价' + ); + } + } + } + + /** + * 计算利润 + */ + private function calculateProfit(array $veh, $order): float + { + $unitPrice = (float)($veh['unit_price']['amount'] ?? 0); + + if (!empty($veh['mileage']) && $veh['mileage'] > 0) { + // 二手车 + $ttPrice = ($veh['listing_price']['amount'] ?? 0) / ($order->contract_exchange_rate ?: 1); + $ddPrice = $veh['reduction_price']['amount'] ?? 0; + } else { + // 新车 + $ttPrice = ($veh['official_price']['amount'] ?? 0) / ($order->contract_exchange_rate ?: 1); + $ddPrice = $veh['discount_price']['amount'] ?? 0; + } + + $handlingFee = (float)($veh['handling_fee']['amount'] ?? 0); + $fobTransportFee = (float)($veh['fob_transport_fee']['amount'] ?? 0); + $portMiscFee = (float)($veh['port_misc_fee']['amount'] ?? 0); + $retrofitFee = (float)($veh['retrofit_fee']['amount'] ?? 0); + $oceanFreight = (float)($veh['ocean_freight']['amount'] ?? 0); + + return $unitPrice - $ttPrice - $ddPrice - $handlingFee - $fobTransportFee - $portMiscFee - $retrofitFee - $oceanFreight; + } + + /** + * 处理改装项 + */ + private function processModificationItems(int $orderItemId, array $modifyList): void + { + if (empty($modifyList)) { + return; + } + + foreach ($modifyList as $modify) { + $modify['order_item_id'] = $orderItemId; + StockOrderItemOptions::create($modify); + } + } + + /** + * 处理账户项 + */ + private function processAccountItems($order, array $accountList): void + { + if (empty($accountList)) { + return; + } + + foreach ($accountList as $account) { + $account['order_id'] = $order->id; + if (!empty($account['remit_date'])) { + $account['remit_date'] = strtotime($account['remit_date']); + } + StockOrderAccounts::create($account); + } + } } \ No newline at end of file diff --git a/app/crm/service/StockOrdersService_bak.php b/app/crm/service/StockOrdersService_bak.php new file mode 100644 index 0000000..356fcca --- /dev/null +++ b/app/crm/service/StockOrdersService_bak.php @@ -0,0 +1,444 @@ +validator; + } + + + protected function buildQueryConfig(Request $request, string $scene = 'index'): array + { + $p = $request->all(); + + $config = []; + $config['model'] = $this->modelClass; + switch ($scene) { + case 'index': + + // ====== ====== 筛选 ====== ====== + // 业务id + if (isset($p['salesperson_id']) && $p['salesperson_id']) { + $config['where']['salesperson_id'] = $p['salesperson_id']; + } + // 初、终版 + $config['where']['is_final'] = $p['is_final'] ?? 0; + // 关键字 + if (isset($p['keyword']) && $p['keyword']) { + $k = '%' . $p['keyword'] . '%'; + foreach (['pi_no', 'order_no', 'customer_snapshot'] as $col) { + $config['orWhere'][] = [$col, 'like', $k]; + } + } + + $config['order']['id'] = 'desc'; + + $config['where']['salesperson_id'] = $request->user->uid; + break; + case 'print': + $config['where']['id'] = $p['id']; + break; + case 'show': + $config['where']['id'] = $p['id']; + + $config['with'][] = 'items'; + $config['with'][] = 'items.options'; + $config['with'][] = 'items.moneyValues'; + $config['with'][] = 'accounts'; + $config['with'][] = 'moneyValues'; + $config['with'][] = 'salesperson'; + break; + case 'store': + break; + case 'update': + $config['where']['id'] = $p['id']; + break; + case 'destroy': + $config['where']['id'] = $p['id']; + break; + } + + return $config; + } + + + public function serviceStore(Request $request, array $data = []) + { + // 关联表较多,增加事务处理 + return Db::transaction(function () use ($request, $data) { + $data = $this->preProcess('Store', $data, $request); + $dl = $this->getDataLimitFromRequest($request); + $created = $this->logicCreate($data, $dl); // 表1 + + // 车辆 + $cifTotalAmount = 0; + $cifTotalAmountRate = 0; + $cifTotalAmountCurrency = 'CNY'; + // $profit = 0; + foreach ($data['veh_list'] as $veh) { + $veh['order_id'] = $created->id; + + // 唯一标识 + $uniqueIdStr = ""; + $uniqueIdStr .= $veh['sku_id']; + $uniqueIdStr .= $veh['model_snapshot']; + $uniqueIdStr .= $veh['color_interior_code']; + $uniqueIdStr .= $veh['color_exterior_code']; + $uniqueIdStr .= $veh['mileage']; + $uniqueIdStr .= json($veh['modify_list']); + $veh['unique_id'] = md5($uniqueIdStr); + $item = StockOrderItems::create($veh); // 表2 + + // 金额 // 表3 + // $item->addMoney('official_price', $veh['official_price']['currency'], $veh['official_price']['amount'], $veh['official_price']['rate'], '官方指导价'); + // $item->addMoney('discount_price', $veh['discount_price']['currency'], $veh['discount_price']['amount'], $veh['discount_price']['rate'], '优惠价'); + if ($veh['unit_price']['amount']) { + $item->addMoney('unit_price', $veh['unit_price']['currency'], $veh['unit_price']['amount'], $veh['unit_price']['rate'], '单价'); + } + if ($veh['total_price']['amount']) { + $item->addMoney('total_price', $veh['total_price']['currency'], $veh['total_price']['amount'], $veh['total_price']['rate'], '总价'); + } + if ($veh['handling_fee']['amount']) { + $item->addMoney('handling_fee', $veh['handling_fee']['currency'], $veh['handling_fee']['amount'], $veh['handling_fee']['rate'], '手续费'); + } + if ($veh['fob_transport_fee']['amount']) { + $item->addMoney('fob_transport_fee', $veh['fob_transport_fee']['currency'], $veh['fob_transport_fee']['amount'], $veh['fob_transport_fee']['rate'], 'FOB运输费'); + } + if ($veh['port_misc_fee']['amount']) { + $item->addMoney('port_misc_fee', $veh['port_misc_fee']['currency'], $veh['port_misc_fee']['amount'], $veh['port_misc_fee']['rate'], '港杂'); + } + if ($veh['retrofit_fee']['amount']) { + $item->addMoney('retrofit_fee', $veh['retrofit_fee']['currency'], $veh['retrofit_fee']['amount'], $veh['retrofit_fee']['rate'], '改装费'); + } + if ($veh['ocean_freight']['amount']) { + $item->addMoney('ocean_freight', $veh['ocean_freight']['currency'], $veh['ocean_freight']['amount'], $veh['ocean_freight']['rate'], '海运费'); + } + + // 二手车 or 新车 + if ($veh['mileage'] > 0) { + if ($veh['listing_price']['amount']) { + $item->addMoney('listing_price', $veh['listing_price']['currency'], $veh['listing_price']['amount'], $veh['listing_price']['rate'], '二手挂牌价'); + } + if ($veh['reduction_price']['amount']) { + $item->addMoney('reduction_price', $veh['reduction_price']['currency'], $veh['reduction_price']['amount'], $veh['reduction_price']['rate'], '二手减价'); + } + + $ttPrice = ($veh['listing_price']['amount'] / $created->contract_exchange_rate); + $ddPrice = $veh['reduction_price']['amount']; + } else { + if ($veh['official_price']['amount']) { + $item->addMoney('official_price', $veh['official_price']['currency'], $veh['official_price']['amount'], $veh['official_price']['rate'], '官方指导价'); + } + if ($veh['discount_price']['amount'] ) { + $item->addMoney('discount_price', $veh['discount_price']['currency'], $veh['discount_price']['amount'], $veh['discount_price']['rate'], '优惠价'); + } + + $ttPrice = ($veh['official_price']['amount'] / $created->contract_exchange_rate); + $ddPrice = $veh['discount_price']['amount']; + } + + // 利润 + $profit = (float)$veh['unit_price']['amount'] + - (float)$ttPrice + - (float)$ddPrice + - (float)$veh['handling_fee']['amount'] + - (float)$veh['fob_transport_fee']['amount'] + - (float)$veh['port_misc_fee']['amount'] + - (float)$veh['retrofit_fee']['amount'] + - (float)$veh['ocean_freight']['amount']; + $item->addMoney('profit', $veh['unit_price']['currency'], $profit, $veh['unit_price']['rate'], '利润'); + + // cif_total_amount + $cifTotalAmount += $veh['total_price']['amount']; + $cifTotalAmountRate = $veh['retrofit_fee']['rate']; + $cifTotalAmountCurrency = $veh['retrofit_fee']['currency']; + + // 改装 + if (count($veh['modify_list']) > 0) { + foreach ($veh['modify_list'] as $modify) { + $modify['order_item_id'] = $item->id; + StockOrderItemOptions::create($modify); // 表4 + } + } + } + + // 计算&&插入 表1 + $created->addMoney('cif_total_amount', $cifTotalAmountCurrency, $cifTotalAmount, $cifTotalAmountRate, '合计到岸价'); + + // 账户 + if (count($data['account_list']) > 0) { + foreach ($data['account_list'] as $account) { + $account['order_id'] = $created->id; + $account['remit_date'] = strtotime($account['remit_date']); + StockOrderAccounts::create($account); // 表5 + } + } + + return $this->postProcess('Store', $created); + }); + } + + public function beforeServiceStore($data, Request $request) + { + $userId = $request->user->uid; + + $data['order_no'] = generateStockNo(); + $data['biz_date'] = strtotime($data['biz_date']); + $data['eta_ship_date'] = strtotime($data['eta_ship_date']); + $data['latest_arrival_date'] = strtotime($data['latest_arrival_date']); + $data['salesperson_id'] = $userId; + $data['salesperson_snapshot'] = User::where('id', $userId)->value('name') ?? ''; + + return $data; + } + + protected function afterServiceStore($res) + { + // 处理原单 + if ($res->is_final == 1 && $res->object_id > 0) { + $order = StockOrders::find($res->object_id); + $order->is_use = 1; + $order->object_id = $res->id; + if (!$order->save()) { + flg('备货单【'.$order->order_no.'】创建终版成功,但更新原单失败'); + } + } + // 启动审批 + $appro = new \app\common\utils\approval\service\ApprovalFlowService(); + $result = $appro->start('stock_order_flow', 'stock_orders', $res->id, $res->toArray(), $res->salesperson_id); + var_dump($result); + + // 异步生成pdf文件 + \Webman\RedisQueue\Redis::send('stock-order-pdf', ['id'=>$res->id]); + return $res; + } + + + public function createdPdfFile($id) + { + $config = []; + $config['model'] = $this->modelClass; + $config['where']['id'] = $id; + $config['with'][] = 'items'; + $config['with'][] = 'items.options'; + $config['with'][] = 'items.moneyValues'; + $config['with'][] = 'accounts'; + $config['with'][] = 'moneyValues'; + $config['with'][] = 'salesperson'; + $item = $this->logicShow($config); + $pdfData = $this->pdfData($item); + + // 渲染模板为最终HTML + $tplPath = app_path('common/utils/pdf/template/stockOrder.stub'); + $html = \app\common\utils\pdf\service\PdfHelper::render($tplPath, ['data' => $pdfData]); + + // 生成PDF + $driver = new \app\common\utils\pdf\service\MpdfDriver(); + $pdfBin = $driver->htmlToPdf($html); + + // 存储 + $dir = public_path('pdf').'/'; + $fileName = ($pdfData['order_no'] ?? date('YmdHis')) . '.pdf'; + + // 本地保存 + \app\common\utils\pdf\service\PdfStorage::saveBinary( + $pdfBin, + $dir, + $fileName + ); + + // // 在线预览 + // return new \support\Response(200, [ + // 'Content-Type' => 'application/pdf', + // 'Content-Disposition' => 'inline; filename="stock-order.pdf"', + // ], $pdfBin); + + // $url = [ + // 'file_name' => $fileName, + // 'file_url' => getenv('MAIN_DOMAIN').'/pdf/'.$fileName + // ]; + + // 上传云端 + $param = [ + 'path' => $dir . $fileName, + 'scene' => 'stock_orders', + 'category' => 'pdf', + 'original_name' => $fileName + ]; + $up = new \app\common\service\UploadService(); + $res = $up->uploadLocalFile($param); + + @unlink($dir . $fileName); + + // 更新文件地址 + $item->file_url = $res['file_name']; + $item->save(); + + return $res; + } + + public function servicePrint(Request $request) + { + $config = $this->buildQueryConfig($request, 'show'); + $item = $this->logicShow($config); + return $this->postProcess('Print', $item); + } + + + public function pdfData($item) + { + $vehList = []; + $index = 0; + foreach ($item->items as $k => $v) { + // 存在则数量加1 + if (count($vehList) > 0 && isset($vehList[$v->unique_id])) { + $vehList[$v->unique_id]['num'] += 1; + $vehList[$v->unique_id]['total_price'] += $vehList[$v->unique_id]['unit_price']; + $vehList[$v->unique_id]['total_price_text'] = $vehList[$v->unique_id]['total_price_symbol'].number_format($vehList[$v->unique_id]['total_price'], 2, '.', ','); + continue; + } + $index += 1; + // 处理金额 + $mv = []; + foreach ($v->moneyValues as $money) { + $mv[$money->field] = [ + 'currency' => $money->currency, + 'amount' => $money->amount, + 'rate' => $money->exchange_rate, + 'currency_symbol' => SysCurrency::where('currency_code', $money->currency)->value('currency_symbol'), + ]; + } + // 处理改装 + $mfy = ''; + foreach ($v->options as $my) { + $mfy .= $my->option_name_snapshot.' '; + } + + // 处理结果集 + $vehList[$v->unique_id] = [ + 'index' => $index, + 'model_snapshot' => $v->model_snapshot, + 'color_interior_snapshot' => $v->color_interior_snapshot, + 'color_exterior_snapshot' => $v->color_exterior_snapshot, + 'num' => 1, + 'modify' => $mfy, + 'mileage' => $v->mileage, + 'unit_price' => $mv['unit_price']['amount'], + 'total_price' => $mv['total_price']['amount'], + 'unit_price_symbol' => $mv['unit_price']['currency_symbol'], + 'total_price_symbol' => $mv['total_price']['currency_symbol'], + 'unit_price_text' => $mv['unit_price']['currency_symbol'].number_format($mv['unit_price']['amount'], 2, '.', ','), + 'total_price_text' => $mv['total_price']['currency_symbol'].number_format($mv['total_price']['amount'], 2, '.', ',') + ]; + + // 根据里程处理 新车or二手车 + if ($v->mileage > 0) { + if (isset($mv['reduction_price'])) { + $vehList[$v->unique_id]['reduction_price'] = $mv['reduction_price']['amount']; + $vehList[$v->unique_id]['reduction_price_symbol'] = $mv['reduction_price']['currency_symbol']; + $vehList[$v->unique_id]['reduction_price_text'] = $mv['reduction_price']['currency_symbol'].number_format($mv['reduction_price']['amount'], 2, '.', ','); + } + $vehList[$v->unique_id]['listing_price'] = $mv['listing_price']['amount']; + $vehList[$v->unique_id]['listing_price_symbol'] = $mv['listing_price']['currency_symbol']; + $vehList[$v->unique_id]['listing_price_text'] = $mv['listing_price']['currency_symbol'].number_format($mv['listing_price']['amount'], 2, '.', ','); + } else { + if (isset($mv['discount_price'])) { + $vehList[$v->unique_id]['discount_price'] = $mv['discount_price']['amount']; + $vehList[$v->unique_id]['discount_price_symbol'] = $mv['discount_price']['currency_symbol']; + $vehList[$v->unique_id]['discount_price_text'] = $mv['discount_price']['currency_symbol'].number_format($mv['discount_price']['amount'], 2, '.', ','); + } + $vehList[$v->unique_id]['official_price'] = $mv['official_price']['amount']; + $vehList[$v->unique_id]['official_price_symbol'] = $mv['official_price']['currency_symbol']; + $vehList[$v->unique_id]['official_price_text'] = $mv['official_price']['currency_symbol'].number_format($mv['official_price']['amount'], 2, '.', ','); + } + } + + $accList = []; + $accIndex = 1; + foreach ($item->accounts as $k => $v) { + $accList[] = [ + 'index' => '收款'.$k + 1, + 'remit_country_name_snapshot' => $v->remit_country_name_snapshot, + 'remit_date' => date('Y-m-d', $v->remit_date), + 'currency_name_snapshot' => $v->currency_name_snapshot, + 'account_name_snapshot' => $v->account_name_snapshot, + 'remitter_name' => $v->remitter_name, + 'amount' => $v->amount, + ]; + $accIndex += 1; + } + + $cifTotalAmount = 0.00; + if ($item->moneyValues) { + $cifTotalAmountSysboml = SysCurrency::where('currency_code', $item->moneyValues->currency)->value('currency_symbol'); + $cifTotalAmount = $cifTotalAmountSysboml.sprintf("%.2f", $item->moneyValues->amount, $item->moneyValues->exchange_rate); + } + + $veh = [ + 'order_no' => $item->order_no, + 'salesperson_snapshot' => $item->salesperson_snapshot, + // 'sign_img' => $item->salesperson->sign_img, + 'sign_img_url' => (!empty($item->salesperson->sign_img))?(new \app\common\service\OssService)->generatePrivateUrl($item->salesperson->sign_img):'', + 'created_at' => date('Y-m-d', strtotime($item->created_at)), + + 'pi_no' => $item->pi_no, + 'biz_date' => date('Y-m-d', $item->biz_date), + 'clearance_country_snapshot' => $item->clearance_country_snapshot, + 'customer_source_snapshot' => $item->customer_source_snapshot, + 'customer_snapshot' => $item->customer_snapshot, + 'customer_country_snapshot' => $item->customer_country_snapshot, + + // 订单项 + 'veh_list' => $vehList, + + 'contract_exchange_rate' => $item->contract_exchange_rate, + 'cif_total_amount' => $item->cif_total_amount, + + 'declarant_name' => $item->declarant_name, + 'eta_ship_date' => date('Y-m-d', $item->eta_ship_date), + 'shipping_method_snapshot' => $item->shipping_method_snapshot, + 'domestic_port_snapshot' => $item->domestic_port_snapshot, + 'trade_term_snapshot' => $item->trade_term_snapshot, + 'clearance_port_snapshot' => $item->clearance_port_snapshot, + 'latest_arrival_date' => date('Y-m-d', $item->latest_arrival_date), + + // 账户 + 'account_list' => $accList, + 'acc_index' => $accIndex, + 'cif_total_amount' => $cifTotalAmount + ]; + + return $veh; + } +} \ No newline at end of file diff --git a/config/route.php b/config/route.php index 7616ca1..064ba56 100644 --- a/config/route.php +++ b/config/route.php @@ -381,7 +381,9 @@ Route::group('/crm', function () { Route::any('/list', [app\crm\controller\StockOrdersController::class, 'index']); Route::any('/show', [app\crm\controller\StockOrdersController::class, 'show']); Route::any('/store', [app\crm\controller\StockOrdersController::class, 'store']); + Route::any('/update', [app\crm\controller\StockOrdersController::class, 'update']); Route::any('/print', [app\crm\controller\StockOrdersController::class, 'print']); + Route::any('/approval', [app\crm\controller\StockOrdersController::class, 'approval']); }); // 审批记录