6
0
Fork 0

分配管理津贴

release
李静 2022-01-13 19:29:31 +08:00
parent c66f69e330
commit 9a57d884e7
4 changed files with 202 additions and 18 deletions

View File

@ -4,6 +4,7 @@ namespace App\Console\Commands\Dealer;
use App\Models\Dealer;
use App\Models\DealerManagerSalesLog;
use App\Models\DealerManageSubsidyLog;
use App\Models\DealerOrder;
use App\Models\UserInfo;
use Illuminate\Console\Command;
@ -34,13 +35,16 @@ class OrderProcessCommand extends Command
public function handle()
{
DealerOrder::chunkById(200, function ($orders) {
$orders->load(['userInfo.dealer', 'products']);
$orders->load([
'userInfo.dealer',
'products.productManageSubsidyRules',
]);
foreach ($orders as $order) {
try {
DB::beginTransaction();
$this->processOrder($order);
$this->handleDealerOrder($order);
DB::commit();
} catch (Throwable $e) {
@ -57,31 +61,139 @@ class OrderProcessCommand extends Command
/**
* 处理经销商订单
*
* @param \App\Models\DealerOrder $order
* @param \App\Models\DealerOrder $dealerOrder
* @return void
*/
protected function processOrder(DealerOrder $order)
protected function handleDealerOrder(DealerOrder $dealerOrder)
{
$tz = now();
$tz = date('Y-m-d H:i:s');
$dealers = $this->getDealers($userInfo = $order->userInfo);
// 获取下单经销商的所有上级经销商
$dealers = $this->getDealers($userInfo = $dealerOrder->userInfo);
// 如果当前用户的上级有管理者,则需要增加管理者的商品销售业绩
if ($manager = $this->firstManager([$userInfo->dealer, ...$dealers])) {
DealerManagerSalesLog::insert(
$order->products->map(function ($product) use ($manager, $tz) {
return [
'user_id' => $manager->user_id,
// 当前链上的全部经销商(含下单经销商)
$chainDealers = [$userInfo->dealer, ...$dealers];
// 处理管理者销售业绩
$this->handleManagerSalesLogs($dealerOrder, $chainDealers, $tz);
// 分配管理津贴
$this->handleManageSubsidyLogs($dealerOrder, $chainDealers, $tz);
}
/**
* 分配管理津贴
*
* @param \App\Models\DealerOrder $dealerOrder
* @param array $dealers
* @param string $tz
* @return void
*/
protected function handleManageSubsidyLogs(DealerOrder $dealerOrder, array $dealers, string $tz)
{
foreach ($dealerOrder->products as $product) {
if ($product->productManageSubsidyRules->isEmpty()) {
continue;
}
// 管理津贴分配规则
$rules = $product->productManageSubsidyRules->keyBy('lvl');
$last = null;
$ranking = 0;
foreach ($dealers as $dealer) {
// 如果当前经销商等级没有对应的管理津贴分配规则,则忽略
if (is_null($rule = $rules->get($dealer->lvl->value))) {
continue;
}
// 同等级管理津贴最多给三次
if ($last === null || $dealer->lvl->value > $last->lvl->value) {
$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' => $manager->lvl,
'lvl' => $dealer->lvl,
'sales_volume' => $product->qty,
'total_amount' => bcmul($product->qty, $subsidy, 2),
'created_at' => $tz,
'updated_at' => $tz,
];
})->all()
);
}
$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 (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);
}
/**
@ -105,7 +217,7 @@ class OrderProcessCommand extends Command
* @param \App\Models\UserInfo $userInfo
* @return array
*/
protected function getDealers(UserInfo $userInfo)
protected function getDealers(UserInfo $userInfo): array
{
$ancestors = [];

View File

@ -0,0 +1,25 @@
<?php
namespace App\Models;
use App\Enums\DealerLvl;
use Illuminate\Database\Eloquent\Model;
class DealerManageSubsidyLog extends Model
{
protected $casts = [
'lvl' => DealerLvl::class,
'order_completed_at' => 'datetime',
];
protected $fillable = [
'user_id',
'lvl',
'order_id',
'product_id',
'sales_volume',
'total_amount',
'order_completed_at',
'remark',
];
}

View File

@ -2,10 +2,15 @@
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class DealerOrderProduct extends Model
{
use HasFactory;
/**
* 商品管理津贴规则
*/
public function productManageSubsidyRules()
{
return $this->hasMany(DealerProductManageRule::class, 'product_id', 'product_id');
}
}

View File

@ -0,0 +1,42 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateDealerManageSubsidyLogsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('dealer_manage_subsidy_logs', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('user_id')->comment('经销商的用户ID');
$table->tinyInteger('lvl')->comment('经销商等级');
$table->unsignedBigInteger('order_id')->comment('订单ID');
$table->unsignedBigInteger('product_id')->comment('商品ID');
$table->unsignedBigInteger('sales_volume')->default(0)->comment('商品销量');
$table->unsignedDecimal('total_amount', 10, 2)->default(0)->comment('补贴总金额');
$table->timestamp('order_completed_at')->nullable()->comment('订单完成时间');
$table->timestamps();
$table->unique(['user_id', 'order_id', 'product_id']);
$table->index('order_id');
$table->index('product_id');
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('dealer_manage_subsidy_logs');
}
}