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() ); // 自动完成总账录入任务 $taskLedger = TaskLedger::where('store_id', $user->store_id) ->where('date', $ledger->date) ->first(); if ($taskLedger) { $taskLedger->task()->update([ 'task_status' => TaskStatus::Success, 'completed_at' => $ledger->created_at, ]); } 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, ]; } }