generated from liutk/owl-admin-base
178 lines
6.1 KiB
PHP
178 lines
6.1 KiB
PHP
<?php
|
|
|
|
namespace App\Http\Controllers\Api;
|
|
|
|
use App\Exceptions\RuntimeException;
|
|
use App\Http\Controllers\Api\Controller;
|
|
use App\Models\Keyword;
|
|
use App\Models\Ledger;
|
|
use App\Models\LedgerItem;
|
|
use Illuminate\Http\Request;
|
|
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('非店长不可上报数据');
|
|
}
|
|
|
|
// 是否是彩票店数据上报
|
|
$isLotteryLedger = $user->store->isLotteryStore();
|
|
|
|
$validated = $request->validate(
|
|
rules: [
|
|
'date' => ['bail', 'required', 'date_format:Y-m-d'],
|
|
'items' => $isLotteryLedger ? ['bail', 'required', 'array'] : ['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'],
|
|
],
|
|
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)) {
|
|
throw new RuntimeException("{$lotteryType->name}未填写上报数据");
|
|
}
|
|
|
|
Validator::validate(
|
|
data: $item,
|
|
rules: [
|
|
'sales' => ['bail', 'required', 'numeric', 'min:0'],
|
|
'expenditure' => ['bail', 'required', 'numeric', 'min:0'],
|
|
],
|
|
attributes: [
|
|
'sales' => "[$lotteryType->name]销售金额",
|
|
'expenditure' => "[$lotteryType->name]兑奖金额",
|
|
],
|
|
);
|
|
}
|
|
}
|
|
|
|
/** @var \App\Models\Ledger|null */
|
|
$ledger = Ledger::where('store_id', $user->store_id)
|
|
->where('date', $validated['date'])
|
|
->first();
|
|
|
|
if ($ledger && ! $ledger->allowReReport()) {
|
|
throw new RuntimeException('上报数据已更新,不可重新上传');
|
|
}
|
|
|
|
$ratio = bcdiv($user->store->profit_ratio, 100, 2);
|
|
|
|
// 计算预期佣金
|
|
$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()
|
|
);
|
|
|
|
DB::commit();
|
|
} catch (Throwable $e) {
|
|
DB::rollBack();
|
|
|
|
throw tap($e, fn ($e) => report($e));
|
|
}
|
|
|
|
return $this->prepareLedger($ledger);
|
|
}
|
|
|
|
public function show(string $date, Request $request)
|
|
{
|
|
/** @var \App\Models\Employee */
|
|
$user = $request->user();
|
|
|
|
/** @var \App\Models\Ledger|null */
|
|
$ledger = Ledger::with(['items'])
|
|
->where('store_id', $user->store_id)
|
|
->where('date', $date)
|
|
->first();
|
|
|
|
return [
|
|
'data' => $ledger ? $this->prepareLedger($ledger) : null,
|
|
];
|
|
}
|
|
|
|
protected function prepareLedger(Ledger $ledger)
|
|
{
|
|
return [
|
|
'date' => $ledger->date,
|
|
'items' => $ledger->items->map(fn ($item) => [
|
|
'id' => $item->ledger_item_type_id,
|
|
'sales' => $item->sales,
|
|
'expenditure' => $item->expenditure,
|
|
]),
|
|
'new_customers' => $ledger->new_customers,
|
|
'sales' => $ledger->sales,
|
|
'expenditure' => $ledger->expenditure,
|
|
'handover_amount' => $ledger->handover_amount,
|
|
'photos' => $ledger->photos,
|
|
];
|
|
}
|
|
}
|