generated from liutk/owl-admin-base
246 lines
8.5 KiB
PHP
246 lines
8.5 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Api;
|
|
|
|
use App\Exceptions\RuntimeException;
|
|
use App\Models\Keyword;
|
|
use App\Models\Ledger;
|
|
use App\Models\LedgerItem;
|
|
use App\Models\TaskLedger;
|
|
use App\Models\TaskPerformance;
|
|
use Illuminate\Http\Request;
|
|
use Illuminate\Support\Carbon;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Validator;
|
|
use Throwable;
|
|
|
|
class LedgerController extends Controller
|
|
{
|
|
public function store(Request $request)
|
|
{
|
|
/** @var \App\Models\Employee */
|
|
$user = $request->user();
|
|
|
|
if (! $user->isStoreMaster()) {
|
|
throw new RuntimeException('非店长不可上报数据');
|
|
}
|
|
|
|
$rules = [
|
|
'date' => ['bail', 'required', 'date_format:Y-m-d'],
|
|
'items' => ['bail', 'array'],
|
|
'new_customers' => ['bail', 'required', 'int', 'min:0'],
|
|
'sales' => ['bail', 'required', 'numeric', 'min:0'],
|
|
'expenditure' => ['bail', 'required', 'numeric', 'min:0'],
|
|
'handover_amount' => ['bail', 'required', 'numeric', 'min:0'],
|
|
'photos' => ['bail', 'required', 'array'],
|
|
];
|
|
|
|
// 是否是彩票店数据上报
|
|
if ($isLotteryLedger = $user->store?->isLotteryStore()) {
|
|
$rules = array_merge($rules, [
|
|
'items' => ['bail', 'required', 'array'],
|
|
// 'sales' => ['bail', 'required', 'numeric'],
|
|
// 'expenditure' => ['bail', 'required', 'numeric'],
|
|
]);
|
|
}
|
|
|
|
$validated = $request->validate(
|
|
rules: $rules,
|
|
attributes: [
|
|
'date' => '日期',
|
|
'items' => '彩种数据',
|
|
'new_customers' => '新增客户',
|
|
'sales' => '销售合计',
|
|
'expenditure' => $isLotteryLedger ? '兑奖合计' : '支出合计',
|
|
'handover_amount' => '交账金额',
|
|
'photos' => '时段报表照片',
|
|
],
|
|
);
|
|
|
|
/** @var \Illuminate\Database\Eloquent\Collection */
|
|
$lotteryTypes = Keyword::filter(['parent_key' => 'lottery_type'])
|
|
->oldest('sort')
|
|
->get();
|
|
|
|
// 上报数据项的格式:
|
|
// [
|
|
// ['id' => '上报数据类型1', 'sales' => '销售金额', 'expenditure' => '兑奖金额'],
|
|
// ['id' => '上报数据类型2', 'sales' => '销售金额', 'expenditure' => '兑奖金额'],
|
|
// ]
|
|
|
|
if ($isLotteryLedger) {
|
|
$items = collect($validated['items'])->keyBy('id');
|
|
|
|
/** @var \App\Models\Keyword */
|
|
foreach ($lotteryTypes as $lotteryType) {
|
|
$item = $items->get($lotteryType->key);
|
|
|
|
if (is_null($item)) {
|
|
continue;
|
|
}
|
|
|
|
Validator::validate(
|
|
data: $item,
|
|
rules: [
|
|
'sales' => ['bail', 'required', 'numeric', 'min:0'],
|
|
'expenditure' => ['bail', 'required', 'numeric', 'min:0'],
|
|
],
|
|
attributes: [
|
|
'sales' => "[$lotteryType->name]销售金额",
|
|
'expenditure' => "[$lotteryType->name]兑奖金额",
|
|
],
|
|
);
|
|
}
|
|
}
|
|
|
|
$date = Carbon::createFromFormat('Y-m-d', $validated['date']);
|
|
|
|
/** @var \App\Models\Ledger|null */
|
|
$ledger = Ledger::where('store_id', $user->store_id)
|
|
->where('date', $date->format('Y-m-d'))
|
|
->first();
|
|
|
|
if ($ledger && ! $ledger->allowReReport()) {
|
|
throw new RuntimeException('上报数据已更新,不可重新上传');
|
|
}
|
|
|
|
$ratio = bcdiv($user->store->profit_ratio, 100, 4);
|
|
|
|
// 计算预期佣金
|
|
$validated['expected_commission'] = bcmul($validated['sales'], $ratio, 2);
|
|
// 计算预期收益
|
|
$validated['expected_income'] = bcsub($validated['expected_commission'], $validated['expenditure'], 2);
|
|
|
|
try {
|
|
DB::beginTransaction();
|
|
|
|
if (is_null($ledger)) {
|
|
$ledger = Ledger::create(
|
|
array_merge($validated, ['store_id' => $user->store_id])
|
|
);
|
|
} else {
|
|
$ledger->update($validated);
|
|
$ledger->items()->delete();
|
|
}
|
|
|
|
LedgerItem::insert(
|
|
collect(
|
|
$isLotteryLedger ? $validated['items'] : [
|
|
[
|
|
'id' => 'ledger_item_type_other',
|
|
'sales' => $ledger->sales,
|
|
'expenditure' => $ledger->expenditure,
|
|
],
|
|
]
|
|
)->map(fn ($item) => [
|
|
'date' => $ledger->date,
|
|
'store_id' => $ledger->store_id,
|
|
'ledger_id' => $ledger->id,
|
|
'ledger_item_type_id' => $item['id'],
|
|
'sales' => $item['sales'],
|
|
'expenditure' => $item['expenditure'],
|
|
'created_at' => $ledger->updated_at,
|
|
'updated_at' => $ledger->updated_at,
|
|
])->all()
|
|
);
|
|
|
|
// 总账录入任务
|
|
/** @var \App\Models\TaskLedger */
|
|
$taskLedger = TaskLedger::where('store_id', $user->store_id)
|
|
->where('date', $ledger->date)
|
|
->first();
|
|
if ($taskLedger) {
|
|
/** @var \App\Models\Task */
|
|
$task = $taskLedger->task;
|
|
|
|
if (! $task->isSuccess()) {
|
|
$task->markAsSuccess();
|
|
}
|
|
}
|
|
|
|
// 业绩指标任务
|
|
/** @var \App\Models\TaskPerformance */
|
|
$taskPerformance = TaskPerformance::where('store_id', $ledger->store_id)
|
|
->where('month', $date->format('Y-m'))
|
|
->first();
|
|
if ($taskPerformance) {
|
|
$actualPerformance = Ledger::where('store_id', $ledger->store_id)
|
|
->whereBetween('date', [$date->copy()->startOfMonth()->format('Y-m-d'), $date->copy()->endOfMonth()->format('Y-m-d')])
|
|
->sum('sales');
|
|
|
|
$taskPerformance->update([
|
|
'actual_performance' => $actualPerformance,
|
|
]);
|
|
|
|
if ($taskPerformance->isSuccess()) {
|
|
/** @var \App\Models\Task */
|
|
$task = $taskPerformance->task;
|
|
|
|
if (! $task->isSuccess()) {
|
|
$task->markAsSuccess();
|
|
}
|
|
}
|
|
}
|
|
|
|
DB::commit();
|
|
} catch (Throwable $e) {
|
|
DB::rollBack();
|
|
|
|
throw tap($e, fn ($e) => report($e));
|
|
}
|
|
|
|
return response()->noContent();
|
|
}
|
|
|
|
public function show(string $date, Request $request)
|
|
{
|
|
/** @var \App\Models\Employee */
|
|
$user = $request->user();
|
|
|
|
$storeId = $request->whenFilled('store_id', fn ($storeId) => $storeId, fn () => $user->store_id);
|
|
|
|
/** @var \App\Models\Ledger|null */
|
|
$ledger = Ledger::with(['items'])
|
|
->where('store_id', $storeId)
|
|
->where('date', $date)
|
|
->first();
|
|
|
|
$items = [];
|
|
|
|
if ($user->store?->isLotteryStore()) {
|
|
/** @var \Illuminate\Database\Eloquent\Collection */
|
|
$lotteryTypes = Keyword::filter(['parent_key' => 'lottery_type'])
|
|
->oldest('sort')
|
|
->get();
|
|
|
|
$ledgerItems = collect();
|
|
if ($ledger) {
|
|
$ledgerItems = $ledger->items->keyBy('ledger_item_type_id');
|
|
}
|
|
|
|
$items = $lotteryTypes->map(function ($lotteryType) use ($ledgerItems) {
|
|
$ledgerItem = $ledgerItems->get($lotteryType->key);
|
|
|
|
return [
|
|
'id' => $lotteryType->key,
|
|
'name' => $lotteryType->name,
|
|
'sales' => $ledgerItem?->sales,
|
|
'expenditure' => $ledgerItem?->expenditure,
|
|
'operator' => (string) $lotteryType->value,
|
|
];
|
|
})->all();
|
|
}
|
|
|
|
return [
|
|
'date' => $date,
|
|
'items' => $items,
|
|
'new_customers' => $ledger?->new_customers,
|
|
'sales' => $ledger?->sales,
|
|
'expenditure' => $ledger?->expenditure,
|
|
'handover_amount' => $ledger?->handover_amount,
|
|
'photos' => $ledger?->photos ?: [],
|
|
'allow_rereport' => is_null($ledger) ? true : $ledger->allowReReport(),
|
|
];
|
|
}
|
|
}
|