Merge branch 'hotfix/fix-dealer-settle' into develop
commit
df124a8dc8
|
|
@ -0,0 +1,722 @@
|
|||
<?php
|
||||
|
||||
namespace App\Admin\Imports;
|
||||
|
||||
use App\Enums\DealerEarningStatus;
|
||||
use App\Enums\DealerLvl;
|
||||
use App\Enums\DealerOrderSettleState;
|
||||
use App\Exceptions\BizException;
|
||||
use App\Exceptions\ImportException;
|
||||
use App\Models\Dealer;
|
||||
use App\Models\DealerChannelSubsidyLog;
|
||||
use App\Models\DealerManagerSalesLog;
|
||||
use App\Models\DealerManageSubsidyLog;
|
||||
use App\Models\DealerOrder;
|
||||
use App\Models\DealerOrderAllocateLog;
|
||||
use App\Models\DealerProduct;
|
||||
use App\Models\DealerPurchaseLog;
|
||||
use App\Models\DealerUserProduct;
|
||||
use App\Models\User;
|
||||
use App\Services\Dealer\OrderService;
|
||||
use Illuminate\Database\QueryException;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Throwable;
|
||||
|
||||
class DealerOrderImport extends Import
|
||||
{
|
||||
public function loadRow($row)
|
||||
{
|
||||
/**校验行数据 **/
|
||||
//获取下单用户
|
||||
$phone = $row->getCellAtIndex(0)?->getValue();
|
||||
if (empty($phone)) {
|
||||
throw new ImportException('未输入下单用户手机号');
|
||||
}
|
||||
//获取下单盒数;
|
||||
$qty = $row->getCellAtIndex(1)?->getValue();
|
||||
if (empty($qty)) {
|
||||
throw new ImportException('未输入下单盒数');
|
||||
}
|
||||
//获取下单金额;
|
||||
$totalAmount = $row->getCellAtIndex(2)?->getValue();
|
||||
if (empty($totalAmount)) {
|
||||
throw new ImportException('未输入下单金额');
|
||||
}
|
||||
//获取目标等级
|
||||
$toLv = $row->getCellAtIndex(3)?->getValue();
|
||||
if (empty($toLv)) {
|
||||
throw new ImportException('未输入目标等级');
|
||||
}
|
||||
|
||||
$productId = $row->getCellAtIndex(4)?->getValue();
|
||||
if (empty($productId)) {
|
||||
$productId = 1;
|
||||
}
|
||||
|
||||
$user = User::where('phone', $phone)->first();
|
||||
dump('手机号:'.$phone.'开始执行');
|
||||
if ($user) {
|
||||
$orderService = new OrderService();
|
||||
|
||||
$product = DealerProduct::findOrFail($productId);
|
||||
$shippingAddress = $user->shippingAddresses()->orderBy('is_default', 'desc')->first();
|
||||
try {
|
||||
DB::beginTransaction();
|
||||
//执行自己升级
|
||||
if ($toLv < 4) {
|
||||
$user->dealer->upgrade(DealerLvl::from($toLv), '后台修改等级');
|
||||
//执行上级尝试升级
|
||||
foreach ($user->dealer->getDealers() as $parentDealer) {
|
||||
$parentDealer->attemptUpgrade();
|
||||
}
|
||||
} else {
|
||||
/**下单 -start **/
|
||||
//没有地址
|
||||
if (!$shippingAddress) {
|
||||
$shippingAddress = $user->shippingAddresses()->create([
|
||||
'zone_id'=>3,
|
||||
'zone'=>'北京市 北京市 东城区',
|
||||
'consignee'=>'测试',
|
||||
'telephone'=>'18888888888',
|
||||
'address'=>'1',
|
||||
'is_default'=>true,
|
||||
]);
|
||||
}
|
||||
$order = $orderService->quickCreateOrder($user, $product, $qty, $shippingAddress->id);
|
||||
//重新按新规则给一次发货人
|
||||
if ($order->consignor_id) {
|
||||
$order->update([
|
||||
'consignor_id'=>$this->getConsignor($user, $order->total_amount)?->user_id,
|
||||
]);
|
||||
$order->refresh();
|
||||
if (!($order->consignor_id > 1)) {//如果是null或者1
|
||||
//确认接单
|
||||
$order = $orderService->confirmOrder($order);
|
||||
}
|
||||
}
|
||||
/**下单 -end **/
|
||||
dump('下单:'.$order->sn);
|
||||
/**更新订单状态 -start **/
|
||||
//【金牌】,【特邀】订单需要发货人有对应的库存,否则往上丢
|
||||
if (in_array($toLv, [
|
||||
'2', '3',
|
||||
])) {
|
||||
do {
|
||||
if ($order->consignor_id > 1) {
|
||||
$userProduct = DealerUserProduct::where('user_id', $order->consignor_id)->where('stock', '>', 0)->first();
|
||||
if (!$userProduct) {
|
||||
//没找到库存商品,则继续往上丢
|
||||
$order = $this->updateOrderConsignor($order);
|
||||
$order->refresh();
|
||||
} else {
|
||||
// if ($userProduct->stock < $qty) {
|
||||
// //记录手机号
|
||||
// }
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} while (!$userProduct);
|
||||
}
|
||||
if ($order->isPending()) {
|
||||
//确认接单
|
||||
$order = $orderService->confirmOrder($order);
|
||||
}
|
||||
//确认打款
|
||||
$order = $orderService->payOrder($order, 'offline');
|
||||
//确认收款
|
||||
$order = $orderService->paidOrder($order);
|
||||
|
||||
//如果目标等级是【金牌】【特邀】则只到【待发货】。其余订单走到【已完成】
|
||||
if (!in_array($toLv, [
|
||||
'2', '3',
|
||||
])) {
|
||||
//确认发货
|
||||
$order = $orderService->shippingOrder($order);
|
||||
//确认收货
|
||||
$order = $orderService->shippingedOrder($order);
|
||||
}
|
||||
|
||||
/**更新订单状态 -end **/
|
||||
|
||||
//执行升级结算订单
|
||||
$this->handleDealerOrder($order);
|
||||
}
|
||||
DB::commit();
|
||||
} catch (QueryException $e) {
|
||||
DB::rollBack();
|
||||
if (strpos($e->getMessage(), 'Numeric value out of range') !== false) {
|
||||
$e = new BizException('当前可发货库存不足');
|
||||
}
|
||||
throw $e;
|
||||
} catch (Throwable $th) {
|
||||
DB::rollBack();
|
||||
report($th);
|
||||
throw new BizException($th->getMessage());
|
||||
}
|
||||
} else {
|
||||
throw new ImportException('未找到用户:'.$phone);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 更新订单发货人
|
||||
*
|
||||
* @return DealerOrder
|
||||
*/
|
||||
public function updateOrderConsignor(DealerOrder $order)
|
||||
{
|
||||
//只处理当前订单有发货人的情况
|
||||
if ($order->consignor) {
|
||||
$consignor = $this->getConsignor($order->user, $order->total_amount, $order->consignor);
|
||||
$oldConsignor = $order->consignor;
|
||||
$order->update([
|
||||
'allocated_at' => now(),
|
||||
'consignor_id' => $consignor?->user_id,
|
||||
]);
|
||||
//记录分配日志
|
||||
DealerOrderAllocateLog::create([
|
||||
'order_id'=>$order->id,
|
||||
'last_consignor_id'=>$oldConsignor->id,
|
||||
'new_consignor_id' =>$order->consignor_id,
|
||||
]);
|
||||
}
|
||||
return $order;
|
||||
}
|
||||
|
||||
private function getConsignor(User $user, $totalAmount, ?User $lastConsignor = null)
|
||||
{
|
||||
$rules = [
|
||||
[
|
||||
'amount' => '2640',
|
||||
'lvl' => DealerLvl::Contracted,
|
||||
],
|
||||
[
|
||||
'amount' => '860',
|
||||
'lvl' => DealerLvl::Special,
|
||||
],
|
||||
[
|
||||
'amount' => '630',
|
||||
'lvl' => DealerLvl::Gold,
|
||||
],
|
||||
];
|
||||
$lvl = $user->dealer->lvl;
|
||||
//计算通过这个订单可能升级成为的身份
|
||||
foreach ($rules as $rule) {
|
||||
if ($totalAmount >= $rule['amount'] && $lvl->value < $rule['lvl']->value) {
|
||||
$lvl = $rule['lvl'];
|
||||
}
|
||||
}
|
||||
//如果是签约单,直接抛到公司后台发货
|
||||
if ($lvl->value >= DealerLvl::Contracted->value) {
|
||||
return null;
|
||||
}
|
||||
//新逻辑
|
||||
$consignor = null;
|
||||
$_lastConsignor = $lastConsignor;
|
||||
do {
|
||||
$query = User::with(['userInfo', 'dealer']);
|
||||
if ($_lastConsignor) {
|
||||
$query->where('id', $_lastConsignor->userInfo->real_inviter_id);
|
||||
} else {
|
||||
$query->where('id', $user->userInfo->real_inviter_id);
|
||||
}
|
||||
$consignor = $query->first();
|
||||
if ($consignor) {//找到老上级
|
||||
if ($consignor->dealer->is_sale == true && $consignor->dealer->lvl->value > $lvl->value) {
|
||||
break;
|
||||
} else {
|
||||
$_lastConsignor = $consignor;
|
||||
$consignor = null;
|
||||
}
|
||||
} else {//如果找不到人了
|
||||
$consignor = $lastConsignor;
|
||||
break;
|
||||
}
|
||||
} while (empty($consignor));
|
||||
|
||||
return $consignor?->userInfo;
|
||||
}
|
||||
|
||||
/**
|
||||
* 处理经销商订单
|
||||
*
|
||||
* @param \App\Models\DealerOrder $dealerOrder
|
||||
* @return void
|
||||
*/
|
||||
protected function handleDealerOrder(DealerOrder $dealerOrder)
|
||||
{
|
||||
$tz = now()->toDateTimeString();
|
||||
|
||||
// 上级经销商
|
||||
$ancestors = $dealerOrder->dealer->getDealers();
|
||||
|
||||
// 签约经销商的进货日志
|
||||
$this->handlePurchaseLogsOfContractedDealer($dealerOrder, $tz);
|
||||
|
||||
// 一级签约经销商和二级经销商的管理津贴
|
||||
$this->handleManageSubsidyLogs($dealerOrder, $ancestors, $tz);
|
||||
|
||||
// 管理者的销售业绩
|
||||
$this->handleManagerSalesLogs($dealerOrder, $ancestors, $tz);
|
||||
|
||||
// 渠道补贴
|
||||
$this->handleChannelSubsidy($dealerOrder);
|
||||
|
||||
if ($dealerOrder->dealer->wasChanged('lvl')) {
|
||||
$dealers = [
|
||||
$dealerOrder->dealer,
|
||||
...$ancestors,
|
||||
];
|
||||
|
||||
foreach ($dealers as $dealer) {
|
||||
$dealer->attemptUpgrade();
|
||||
}
|
||||
}
|
||||
|
||||
// 将订单标记为已处理
|
||||
$dealerOrder->forceFill([
|
||||
'settle_state' => DealerOrderSettleState::Processed,
|
||||
])->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算渠道补贴
|
||||
*
|
||||
* @param \App\Models\DealerOrder $dealerOrder
|
||||
* @return void
|
||||
*/
|
||||
protected function handleChannelSubsidy(DealerOrder $dealerOrder)
|
||||
{
|
||||
$lvl = $dealerOrder->dealer->lvl;
|
||||
|
||||
$lvlValue = [
|
||||
DealerLvl::Contracted->value => '2640',
|
||||
DealerLvl::Special->value => '860',
|
||||
DealerLvl::Gold->value => '630',
|
||||
|
||||
];
|
||||
|
||||
if ($dealerOrder->total_amount >= $lvlValue[DealerLvl::Contracted->value]) {
|
||||
// 升级为签约
|
||||
if ($lvl->value < DealerLvl::Contracted->value) {
|
||||
$lvl = DealerLvl::Contracted;
|
||||
}
|
||||
} elseif ($dealerOrder->total_amount >= $lvlValue[DealerLvl::Special->value]) {
|
||||
// 升级为特约
|
||||
if ($lvl->value < DealerLvl::Special->value) {
|
||||
$lvl = DealerLvl::Special;
|
||||
}
|
||||
} elseif ($dealerOrder->total_amount >= $lvlValue[DealerLvl::Gold->value]) {
|
||||
// 升级为金牌
|
||||
if ($lvl->value < DealerLvl::Gold->value) {
|
||||
$lvl = DealerLvl::Gold;
|
||||
}
|
||||
}
|
||||
|
||||
// 如果经销商等级小于金牌,则没有渠道补贴
|
||||
if ($lvl->value < DealerLvl::Gold->value) {
|
||||
return;
|
||||
}
|
||||
|
||||
[$dealers, $rule] = $this->mapDealersAndRuleOfChannel($dealerOrder->dealer, $lvl);
|
||||
|
||||
if ($lvl->value >= DealerLvl::Contracted->value) {
|
||||
$upgradeAmount = $lvlValue[DealerLvl::Contracted->value];
|
||||
} else {
|
||||
$upgradeAmount = $lvlValue[$lvl->value];
|
||||
}
|
||||
|
||||
// 手续费比例
|
||||
$feeRate = app_settings('dealer.fee_rate');
|
||||
|
||||
foreach ($dealers as $key => $dealer) {
|
||||
$ruleKey = $dealer->lvl->value.'_'.$key;
|
||||
|
||||
if ($dealer->lvl->value >= DealerLvl::Contracted->value) {
|
||||
$ruleKey = DealerLvl::Contracted->value.'_'.$key;
|
||||
}
|
||||
|
||||
// 补贴金额
|
||||
$subsidyAmount = $rule[$ruleKey];
|
||||
|
||||
$totalAmount = bcmul($subsidyAmount, $dealerOrder->total_amount, 10);
|
||||
$totalAmount = bcdiv($totalAmount, $upgradeAmount, 3);
|
||||
$totalAmount = round($totalAmount, 2);
|
||||
|
||||
$channelSubsidyLog = DealerChannelSubsidyLog::create([
|
||||
'user_id' => $dealer->user_id,
|
||||
'lvl' => $dealer->lvl,
|
||||
'order_id' => $dealerOrder->id,
|
||||
'total_amount' => $totalAmount,
|
||||
'order_id' => $dealerOrder->id,
|
||||
'remark' => "补贴总额={$dealerOrder->total_amount}/{$upgradeAmount}*{$subsidyAmount}",
|
||||
]);
|
||||
|
||||
$fee = bcmul($channelSubsidyLog->total_amount, bcdiv($feeRate, '100', 5), 3);
|
||||
$fee = round($fee, 2);
|
||||
|
||||
$channelSubsidyLog->earning()->create([
|
||||
'user_id' => $channelSubsidyLog->user_id,
|
||||
'lvl' => $channelSubsidyLog->lvl,
|
||||
'total_amount' => $channelSubsidyLog->total_amount,
|
||||
'total_earnings' => bcsub($channelSubsidyLog->total_amount, $fee, 2),
|
||||
'fee' => $fee,
|
||||
'fee_rate' => $feeRate,
|
||||
'payer_id' => $dealerOrder->consignor_id,
|
||||
'status' => DealerEarningStatus::Pending,
|
||||
'remark' => "订单号: {$dealerOrder->sn}",
|
||||
]);
|
||||
}
|
||||
|
||||
$dealerOrder->dealer->upgrade($lvl, '进货升级');
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取渠道补贴经销商和补贴规则
|
||||
*
|
||||
* @param \App\Models\Dealer $dealer
|
||||
* @param \App\Enums\DealerLvl $lvl
|
||||
* @return array
|
||||
*/
|
||||
protected function mapDealersAndRuleOfChannel(Dealer $dealer, DealerLvl $lvl): array
|
||||
{
|
||||
// 渠道补贴经销商
|
||||
$dealers = [];
|
||||
// 渠道补贴规则
|
||||
$rule = null;
|
||||
// 是否升级
|
||||
$isUp = $lvl->value > $dealer->lvl->value;
|
||||
// 最后参与渠道补贴的经销商
|
||||
$last = null;
|
||||
// 前一个直属邀请人
|
||||
$previous = null;
|
||||
|
||||
while (true) {
|
||||
if ($previous) {
|
||||
$_dealer = $previous->userInfo->realInviterInfo?->dealer;
|
||||
$_dealer?->setRelation('userInfo', $previous->userInfo->realInviterInfo);
|
||||
} else {
|
||||
$_dealer = $dealer->userInfo->realInviterInfo?->dealer;
|
||||
$_dealer?->setRelation('userInfo', $dealer->userInfo->realInviterInfo);
|
||||
}
|
||||
|
||||
$previous = $_dealer;
|
||||
|
||||
if ($_dealer === null) {
|
||||
break;
|
||||
}
|
||||
|
||||
// 如果经销商等级小于金牌, 那么跳过
|
||||
if ($_dealer->lvl->value < DealerLvl::Gold->value) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($lvl->value >= DealerLvl::Contracted->value) {
|
||||
if ($last === null) {
|
||||
if ($_dealer->lvl->value >= DealerLvl::Contracted->value) {
|
||||
// 渠道补贴规则: 签约 -> 签约 -> 签约
|
||||
$rule = [
|
||||
DealerLvl::Contracted->value.'_0' => '396',
|
||||
DealerLvl::Contracted->value.'_1' => '79',
|
||||
];
|
||||
|
||||
$dealers[] = $_dealer;
|
||||
|
||||
$last = $_dealer;
|
||||
} elseif ($isUp && $_dealer->isSpecialDealer()) {
|
||||
// 渠道补贴规则: 签约 -> 特邀 -> 签约 -> 签约
|
||||
$rule = [
|
||||
DealerLvl::Special->value.'_0' => '264',
|
||||
DealerLvl::Contracted->value.'_1' => '132',
|
||||
DealerLvl::Contracted->value.'_2' => '79',
|
||||
];
|
||||
|
||||
$dealers[] = $_dealer;
|
||||
|
||||
$last = $_dealer;
|
||||
}
|
||||
} elseif ($_dealer->lvl->value >= DealerLvl::Contracted->value) {
|
||||
$dealers[] = $_dealer;
|
||||
|
||||
// 如果最后参与渠道补贴的经销商是签约, 那么已经找到所有参与渠道补贴的经销商
|
||||
if ($last->lvl->value >= DealerLvl::Contracted->value) {
|
||||
break;
|
||||
}
|
||||
|
||||
$last = $_dealer;
|
||||
}
|
||||
} elseif ($lvl === DealerLvl::Special) {
|
||||
if ($_dealer->lvl->value > DealerLvl::Special->value) {
|
||||
break;
|
||||
}
|
||||
|
||||
if ($last === null) {
|
||||
if ($_dealer->isSpecialDealer()) {
|
||||
// 渠道补贴规则: 特邀 -> 特邀 -> 特邀
|
||||
$rule = [
|
||||
DealerLvl::Special->value.'_0' => '80',
|
||||
DealerLvl::Special->value.'_1' => '20',
|
||||
];
|
||||
|
||||
$dealers[] = $_dealer;
|
||||
|
||||
$last = $_dealer;
|
||||
} elseif ($isUp && $_dealer->isGoldDealer()) {
|
||||
// 渠道补贴规则: 特邀 -> 金牌 -> 特邀 -> 特邀
|
||||
$rule = [
|
||||
DealerLvl::Gold->value.'_0' => '50',
|
||||
DealerLvl::Special->value.'_1' => '30',
|
||||
DealerLvl::Special->value.'_2' => '20',
|
||||
];
|
||||
|
||||
$dealers[] = $_dealer;
|
||||
|
||||
$last = $_dealer;
|
||||
}
|
||||
} elseif ($_dealer->isSpecialDealer()) {
|
||||
$dealers[] = $_dealer;
|
||||
|
||||
if ($last->isSpecialDealer()) {
|
||||
break;
|
||||
}
|
||||
|
||||
$last = $_dealer;
|
||||
}
|
||||
} elseif ($lvl === DealerLvl::Gold) {
|
||||
if ($_dealer->lvl->value >= DealerLvl::Gold->value) {
|
||||
if ($_dealer->isGoldDealer()) {
|
||||
// 渠道补贴规则: 金牌 -> 金牌
|
||||
$rule = [
|
||||
DealerLvl::Gold->value.'_0' => '75',
|
||||
];
|
||||
|
||||
$dealers[] = $_dealer;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return [$dealers, $rule];
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成签约经销商的进货日志
|
||||
*
|
||||
* @param \App\Models\DealerOrder $dealerOrder
|
||||
* @param array $dealers
|
||||
* @param string $tz
|
||||
* @return void
|
||||
*/
|
||||
protected function handlePurchaseLogsOfContractedDealer(DealerOrder $dealerOrder, string $tz)
|
||||
{
|
||||
if (! $this->isContractedDealerToPurchase($dealerOrder)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$dealer = $dealerOrder->userInfo->dealer;
|
||||
|
||||
// 采购业绩是否算自己的业绩
|
||||
$valid = $dealer->lvl->value >= DealerLvl::Contracted->value;
|
||||
|
||||
$log = new DealerPurchaseLog([
|
||||
'user_id' => $dealer->user_id,
|
||||
'lvl' => $dealer->lvl,
|
||||
'order_id' => $dealerOrder->id,
|
||||
'total_amount' => $dealerOrder->total_amount,
|
||||
'path' => $valid ? $dealerOrder->userInfo->full_path : $dealerOrder->userInfo->path,
|
||||
'remark' => $valid ? null : '升级签约',
|
||||
]);
|
||||
$log->setCreatedAt($tz);
|
||||
$log->setUpdatedAt($tz);
|
||||
$log->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* 分配一级签约经销商和二级经销商的管理津贴
|
||||
*
|
||||
* @param \App\Models\DealerOrder $dealerOrder
|
||||
* @param array $dealers
|
||||
* @param string $tz
|
||||
* @return void
|
||||
*/
|
||||
protected function handleManageSubsidyLogs(DealerOrder $dealerOrder, array $dealers, string $tz)
|
||||
{
|
||||
if (! $this->isContractedDealerToPurchase($dealerOrder)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$logs = [];
|
||||
|
||||
foreach ($dealerOrder->products as $product) {
|
||||
if ($product->productManageSubsidyRules->isEmpty()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 管理津贴分配规则
|
||||
$rules = $product->productManageSubsidyRules->keyBy('lvl');
|
||||
|
||||
$last = null;
|
||||
$ranking = 0;
|
||||
|
||||
foreach ($dealers as $dealer) {
|
||||
if (! in_array($dealer->lvl, [DealerLvl::Secondary, DealerLvl::Top])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 如果当前经销商等级没有对应的管理津贴分配规则,则忽略
|
||||
if (is_null($rule = $rules->get($dealer->lvl->value))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// 同等级管理津贴最多给三次
|
||||
if ($last === null || $dealer->lvl->value > $last->lvl->value) {
|
||||
if ($ranking < 3 && $dealer->lvl === DealerLvl::Top) {
|
||||
if ($secondarySubsidyRule = $rules->get(DealerLvl::Secondary->value)) {
|
||||
$key = 'price_'.(1 + $ranking).'st';
|
||||
|
||||
$secondarySubsidy = $secondarySubsidyRule->{$key};
|
||||
|
||||
if (bccomp($secondarySubsidy, '0') === 1) {
|
||||
$logs[] = [
|
||||
'user_id' => $dealer->user_id,
|
||||
'order_id' => $product->order_id,
|
||||
'product_id' => $product->product_id,
|
||||
'lvl' => $dealer->lvl,
|
||||
'sales_volume' => $product->qty,
|
||||
'total_amount' => bcmul($product->qty, $secondarySubsidy, 2),
|
||||
'created_at' => $tz,
|
||||
'updated_at' => $tz,
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$ranking = 1;
|
||||
} elseif ($ranking < 3 && $dealer->lvl->value === $last->lvl->value) {
|
||||
$ranking++;
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
|
||||
$subsidy = $rule->{"price_{$ranking}st"};
|
||||
|
||||
if (bccomp($subsidy, '0') === 1) {
|
||||
$logs[] = [
|
||||
'user_id' => $dealer->user_id,
|
||||
'order_id' => $product->order_id,
|
||||
'product_id' => $product->product_id,
|
||||
'lvl' => $dealer->lvl,
|
||||
'sales_volume' => $product->qty,
|
||||
'total_amount' => bcmul($product->qty, $subsidy, 2),
|
||||
'created_at' => $tz,
|
||||
'updated_at' => $tz,
|
||||
];
|
||||
}
|
||||
|
||||
$last = $dealer;
|
||||
}
|
||||
}
|
||||
|
||||
DealerManageSubsidyLog::insert($logs);
|
||||
}
|
||||
|
||||
/**
|
||||
* 过滤出可能会享受管理津贴的经销商(每个等级最多3人)
|
||||
*
|
||||
* @param array $dealers
|
||||
* @return array
|
||||
*/
|
||||
protected function mapManageSubsidyDealers(array $dealers): array
|
||||
{
|
||||
$map = [];
|
||||
$last = null;
|
||||
$ranking = 1;
|
||||
|
||||
foreach ($dealers as $dealer) {
|
||||
if ($last === null || $dealer->lvl->value > $last->lvl->value) {
|
||||
$last = $dealer;
|
||||
$map[] = $last;
|
||||
$ranking = 1;
|
||||
} elseif ($ranking < 3 && $dealer->lvl->value === $last->lvl->value) {
|
||||
$last = $dealer;
|
||||
$map[] = $last;
|
||||
$ranking++;
|
||||
}
|
||||
}
|
||||
|
||||
return $map;
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成管理者的销售业绩
|
||||
*
|
||||
* @param \App\Models\DealerOrder $dealerOrder
|
||||
* @param array $dealers
|
||||
* @param string $tz
|
||||
* @return void
|
||||
*/
|
||||
protected function handleManagerSalesLogs(DealerOrder $dealerOrder, array $dealers, string $tz): void
|
||||
{
|
||||
if (! $this->isContractedDealerToPurchase($dealerOrder)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_null($manager = $this->firstManager($dealers))) {
|
||||
return;
|
||||
}
|
||||
|
||||
$logs = [];
|
||||
|
||||
foreach ($dealerOrder->products as $product) {
|
||||
$logs[] = [
|
||||
'user_id' => $manager->user_id,
|
||||
'lvl' => $manager->lvl,
|
||||
'order_id' => $product->order_id,
|
||||
'product_id' => $product->product_id,
|
||||
'sales_volume' => $product->qty,
|
||||
'created_at' => $tz,
|
||||
'updated_at' => $tz,
|
||||
];
|
||||
}
|
||||
|
||||
DealerManagerSalesLog::insert($logs);
|
||||
}
|
||||
|
||||
/**
|
||||
* 从给定的经销商中获取第一个管理者
|
||||
*
|
||||
* @param array $dealers
|
||||
* @return \App\Models\Dealer|null
|
||||
*/
|
||||
protected function firstManager(array $dealers): ?Dealer
|
||||
{
|
||||
foreach ($dealers as $dealer) {
|
||||
if ($dealer->is_manager) {
|
||||
return $dealer;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 确认是否是签约经销商进货
|
||||
*
|
||||
* @param DealerOrder $dealerOrder
|
||||
* @return bool
|
||||
*/
|
||||
protected function isContractedDealerToPurchase(DealerOrder $dealerOrder): bool
|
||||
{
|
||||
$dealer = $dealerOrder->userInfo->dealer;
|
||||
|
||||
if ($dealer->lvl->value < DealerLvl::Contracted->value) {
|
||||
if ($dealerOrder->total_amount < '2640') {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
<?php
|
||||
|
||||
namespace App\Console\Commands\Dealer;
|
||||
|
||||
use App\Admin\Imports\DealerOrderImport;
|
||||
use App\Models\ImportJobLog;
|
||||
use Illuminate\Console\Command;
|
||||
|
||||
class ManagerSubsidySettleCommand extends Command
|
||||
{
|
||||
/**
|
||||
* The name and signature of the console command.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $signature = 'dealer:import-order {fileUri}';
|
||||
|
||||
protected $fileUri = '';
|
||||
/**
|
||||
* The console command description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $description = '导入批零订单';
|
||||
|
||||
/**
|
||||
* Execute the console command.
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
public function handle()
|
||||
{
|
||||
if ($this->hasArgument('fileUri')) {
|
||||
$this->fileUri = $this->argument('fileUri');
|
||||
}
|
||||
$import = new DealerOrderImport();
|
||||
$res = $import->readFileByUrl($this->fileUri);
|
||||
|
||||
ImportJobLog::insert(array_map(function ($value) {
|
||||
return array_merge($value, [
|
||||
'job_id'=> 0,
|
||||
'created_at' => now(),
|
||||
'updated_at' => now(),
|
||||
]);
|
||||
}, $res['errors']));
|
||||
}
|
||||
}
|
||||
|
|
@ -208,30 +208,31 @@ class OrderService
|
|||
* 确认接单
|
||||
*
|
||||
* @param DealerOrder $order
|
||||
* @return void
|
||||
* @return DealerOrder $order
|
||||
*/
|
||||
public function confirmOrder(DealerOrder $order)
|
||||
{
|
||||
if (!$order->isPending()) {
|
||||
throw new BizException('订单状态异常,请刷新后再试');
|
||||
throw new BizException('无法接单:订单状态异常,请刷新后再试');
|
||||
}
|
||||
$order->update([
|
||||
'status' => DealerOrderStatus::Paying,
|
||||
]);
|
||||
return $order;
|
||||
}
|
||||
|
||||
/**
|
||||
* 确认打款
|
||||
*
|
||||
* @return void
|
||||
* @return DealerOrder $order
|
||||
*/
|
||||
public function payOrder(DealerOrder $order, string $payWay, ?string $payImage)
|
||||
public function payOrder(DealerOrder $order, string $payWay, ?string $payImage = null)
|
||||
{
|
||||
if (empty($payWay)) {
|
||||
throw new BizException('请选择付款方式');
|
||||
}
|
||||
if (!$order->isPendinged()) {
|
||||
throw new BizException('订单状态异常,请刷新后再试');
|
||||
throw new BizException('无法付款:订单状态异常,请刷新后再试');
|
||||
}
|
||||
switch ($payWay) {
|
||||
case DealerOrder::PAY_WAY_WALLET:
|
||||
|
|
@ -260,35 +261,37 @@ class OrderService
|
|||
]);
|
||||
break;
|
||||
}
|
||||
return $order;
|
||||
}
|
||||
|
||||
/**
|
||||
* 确认收款
|
||||
*
|
||||
* @param DealerOrder $order
|
||||
* @return void
|
||||
* @return DealerOrder $order
|
||||
*/
|
||||
public function paidOrder(DealerOrder $order)
|
||||
{
|
||||
if (!$order->isPay()) {
|
||||
throw new BizException('订单状态异常,请刷新后再试');
|
||||
throw new BizException('无法收款:订单状态异常,请刷新后再试');
|
||||
}
|
||||
$order->update([
|
||||
'status' => DealerOrderStatus::Paid,
|
||||
'paied_time' => now(),
|
||||
]);
|
||||
return $order;
|
||||
}
|
||||
|
||||
/**
|
||||
* 确认发货
|
||||
*
|
||||
* @param DealerOrder $order
|
||||
* @return void
|
||||
* @return DealerOrder $order
|
||||
*/
|
||||
public function shippingOrder(DealerOrder $order)
|
||||
{
|
||||
if (!$order->isPaid()) {
|
||||
throw new BizException('订单状态异常,请刷新后再试');
|
||||
throw new BizException('无法发货:订单状态异常,请刷新后再试');
|
||||
}
|
||||
//扣减发货人库存
|
||||
if ($order->consignor) {
|
||||
|
|
@ -299,12 +302,13 @@ class OrderService
|
|||
'status' => DealerOrderStatus::Shipped,
|
||||
'shipping_time' => now(),
|
||||
]);
|
||||
return $order;
|
||||
}
|
||||
|
||||
public function shippingedOrder(DealerOrder $order)
|
||||
{
|
||||
if (!$order->isShipping()) {
|
||||
throw new BizException('订单状态异常,请刷新后再试');
|
||||
throw new BizException('无法收货:订单状态异常,请刷新后再试');
|
||||
}
|
||||
//增加自己的库存
|
||||
$this->orderInQty($order);
|
||||
|
|
@ -313,16 +317,18 @@ class OrderService
|
|||
'status' => DealerOrderStatus::Completed,
|
||||
'shippinged_time' => now(),
|
||||
]);
|
||||
return $order;
|
||||
}
|
||||
|
||||
public function cancelOrder(DealerOrder $order)
|
||||
{
|
||||
if (!($order->isPending() || $order->isPendinged() || $order->isPay())) {
|
||||
throw new BizException('订单状态异常,请刷新后再试');
|
||||
throw new BizException('无法取消:订单状态异常,请刷新后再试');
|
||||
}
|
||||
$order->update([
|
||||
'status' => DealerOrderStatus::Cancelled,
|
||||
]);
|
||||
return $order;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -334,7 +340,7 @@ class OrderService
|
|||
{
|
||||
//只处理当前订单有发货人的情况
|
||||
if ($order->consignor) {
|
||||
$consignor = $this->getConsignor($order->user, $order->totalAmount, $order->consignor);
|
||||
$consignor = $this->getConsignor($order->user, $order->total_amount, $order->consignor);
|
||||
$oldConsignor = $order->consignor;
|
||||
$order->update([
|
||||
'allocated_at' => now(),
|
||||
|
|
@ -347,6 +353,7 @@ class OrderService
|
|||
'new_consignor_id' =>$order->consignor_id,
|
||||
]);
|
||||
}
|
||||
return $order;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
Loading…
Reference in New Issue