store-manage/app/Admin/Controllers/Finance/LedgerController.php

290 lines
13 KiB
PHP

<?php
namespace App\Admin\Controllers\Finance;
use App\Admin\Controllers\AdminController;
use App\Admin\Services\Finance\LedgerService;
use App\Enums\CheckStatus;
use App\Models\Keyword;
use App\Models\Ledger;
use App\Traits\HasCheckActions;
use Illuminate\Http\Request;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\Validator;
use Slowlyo\OwlAdmin\Admin;
use Slowlyo\OwlAdmin\Renderers\DrawerAction;
use Slowlyo\OwlAdmin\Renderers\Form;
use Slowlyo\OwlAdmin\Renderers\Page;
/**
* @property LedgerService $service
*/
class LedgerController extends AdminController
{
use HasCheckActions;
protected string $serviceName = LedgerService::class;
public function show($id)
{
if ($this->actionOfGetData()) {
/** @var \App\Models\Ledger */
$ledger = Ledger::findOrFail($id);
$ledger->load(['store', 'items.type', 'workflow']);
return $this->response()->success(
array_merge($ledger->toArray(), [
'items_property' => collect($ledger->items)->map(fn ($item) => [
['label' => '类型', 'content' => $item->type?->name ?? '-'],
['label' => '销售', 'content' => $item->sales],
['label' => $item->ledger_item_type_id === 'ledger_item_type_other' ? '支出' : '兑奖', 'content' => $item->expenditure],
])->collapse()->all(),
])
);
}
$detail = amis()
->Card()
->className('base-form')
->header(['title' => __('admin.detail')])
->body($this->detail())
->toolbar([$this->backButton()]);
$page = $this->basePage()->body($detail);
return $this->response()->success($page);
}
public function list(): Page
{
$crud = $this->baseCRUD()
->headerToolbar(
collect($this->baseHeaderToolBar())
->when(Admin::user()->can('admin.finance.ledgers.export'), fn ($collection) => $collection->push($this->exportAction(true)))
)
->bulkActions([])
->filter($this->baseFilter()->body([
amis()->GroupControl()->mode('horizontal')->body([
amis()->DateRangeControl('date_range', __('finance.ledger.date'))
->valueFormat('YYYY-MM-DD'),
amis()->SelectControl('store_id', __('finance.ledger.store'))
->source(admin_url('api/stores'))
->labelField('title')
->valueField('id')
->clearable(),
amis()->SelectControl()->name('check_status')->label(__('workflow_log.check_status'))
->multiple()
->options(CheckStatus::options())
->clearable(),
]),
]))
->filterDefaultVisible()
->columns([
// amis()->TableColumn()->name('id')->label(__('finance.ledger.id')),
amis()->TableColumn()->name('date')->label(__('finance.ledger.date')),
amis()->TableColumn()->name('store.title')->label(__('finance.ledger.store')),
amis()->TableColumn()->name('sales')->label(__('finance.ledger.sales')),
amis()->TableColumn()->name('expenditure')->label(__('finance.ledger.expenditure')),
amis()->TableColumn()->name('new_customers')->label(__('finance.ledger.new_customers')),
amis()->TableColumn()->name('handover_amount')->label(__('finance.ledger.handover_amount')),
amis()->TableColumn()->name('ledger_amount')->label(__('finance.ledger.ledger_amount')),
amis()->TableColumn()->name('ledger_difference')->label(__('finance.ledger.ledger_difference')),
amis()->TableColumn()->name('expected_commission')->label(__('finance.ledger.expected_commission')),
amis()->TableColumn()->name('actual_commission')->label(__('finance.ledger.actual_commission')),
amis()->TableColumn()->name('expected_income')->label(__('finance.ledger.expected_income')),
amis()->TableColumn()->name('actual_income')->label(__('finance.ledger.actual_income')),
amis()->TableColumn('workflow.check_status', __('workflow_log.check_status'))->set('type', 'mapping')->map(CheckStatus::labelMap()),
// amis()->TableColumn()->name('created_at')->label(__('finance.ledger.created_at')),
$this->rowActions([
$this->applyAction()
->api(
amis()->BaseApi()
->url(admin_url('api/workflow/apply'))
->method('post')
->data(['id' => '${workflow.id}'])
)
->visibleOn('${actual_commission != null && actual_income != null && ARRAYINCLUDES(['.CheckStatus::None->value.','.CheckStatus::Cancel->value.','.CheckStatus::Fail->value.'], workflow.check_status)}'),
$this->cancelAction(),
$this->rowEditLedgerAmountButton()
->visible(Admin::user()->can('admin.finance.ledgers.update_ledger_amount')),
$this->rowEditTypeButton('drawer', 'lg')
->visible(Admin::user()->can('admin.finance.ledgers.update'))
->visibleOn('${ARRAYINCLUDES(['.CheckStatus::None->value.','.CheckStatus::Cancel->value.','.CheckStatus::Fail->value.'], workflow.check_status)}'),
$this->rowShowButton()
->visible(Admin::user()->can('admin.finance.ledgers.view')),
]),
]);
return $this->baseList($crud);
}
public function form(): Form
{
return $this->baseForm()->title('')->body([
amis()->NumberControl()
->name('actual_commission')
->label(__('finance.ledger.actual_commission'))
->precision(2)
->showSteps(false)
->required(),
amis()->NumberControl()
->name('actual_income')
->label(__('finance.ledger.actual_income'))
->precision(2)
->showSteps(false)
->required(),
]);
}
public function detail(): Form
{
$detailId = 'ledger-detail';
$serviceId = 'ledger-workflow-service';
return $this->baseDetail()->id($detailId)->title('')->onEvent([
'inited' => [
'actions' => [
['actionType' => 'reload', 'componentId' => $serviceId],
],
],
])->body([
amis()->Property()->items([
['label' => __('finance.ledger.date'), 'content' => '${date}'],
['label' => __('finance.ledger.store'), 'content' => '${store.title}'],
['label' => __('finance.ledger.new_customers'), 'content' => '${new_customers}'],
['label' => __('finance.ledger.sales'), 'content' => '${sales}'],
['label' => __('finance.ledger.expenditure'), 'content' => '${expenditure}'],
['label' => __('finance.ledger.handover_amount'), 'content' => '${handover_amount}'],
['label' => __('finance.ledger.ledger_amount'), 'content' => '${ledger_amount}'],
['label' => __('finance.ledger.ledger_difference'), 'content' => '${ledger_difference}'],
['label' => __('finance.ledger.expected_commission'), 'content' => '${expected_commission}'],
['label' => __('finance.ledger.actual_commission'), 'content' => '${actual_commission}'],
['label' => __('finance.ledger.expected_income'), 'content' => '${expected_income}'],
['label' => __('finance.ledger.actual_income'), 'content' => '${actual_income}'],
['label' => '上报数据', 'content' => amis()->Property()->source('${items_property}'), 'span' => 3],
['label' => __('finance.ledger.photos'), 'content' => amis()->Images()->enlargeAble()->source('${photos}')->enlargeWithGallary(), 'span' => 3],
['label' => __('workflow_log.check_status'), 'content' => amis()->Mapping()->name('workflow.check_status')->map(CheckStatus::labelMap())],
['label' => __('workflow_log.checked_at'), 'content' => '${workflow.checked_at}'],
['label' => __('workflow_log.remarks'), 'content' => '${workflow.check_remarks}'],
]),
amis()->Divider(),
$this->baseWorkflowLogList($detailId)->id($serviceId),
]);
}
/**
* 修改总账金额
*/
public function updateLedgerAmount($id, Request $request)
{
$validator = Validator::make(
data: $request->all(),
rules: [
'ledger_amount' => ['bail', 'required', 'numeric'],
],
attributes: [
'ledger_amount' => __('finance.ledger.ledger_amount'),
],
);
admin_abort_if($validator->fails(), $validator->errors()->first());
/** @var Ledger */
$ledger = Ledger::findOrFail($id);
$ledger->forceFill([
'ledger_amount' => $request->input('ledger_amount'),
])->save();
return $this->response()->success(null, '保存成功');
}
/**
* 编辑总账金额按钮
*/
protected function rowEditLedgerAmountButton(): DrawerAction
{
return amis()->DrawerAction()
->icon('fa-regular fa-pen-to-square')
->label(__('finance.ledger.ledger_amount'))
->level('link')
->drawer(
amis()->Drawer()->title(__('finance.ledger.ledger_amount'))->body([
amis()->Form()->title('')
->api('post:'.admin_url('finance/ledgers/${id}/ledger-amount'))
->body([
amis()->NumberControl()
->name('ledger_amount')
->label(__('finance.ledger.ledger_amount'))
->precision(2)
->showSteps(false)
->required(),
]),
])->size('lg')
);
}
protected function exportFileName()
{
return '上报数据';
}
protected function export()
{
admin_abort_if(!class_exists('\Rap2hpoutre\FastExcel\FastExcel'), __('admin.export.please_install_laravel_excel'));
// 默认在 storage/app/ 下
$path = sprintf('%s-%s.xlsx', $this->exportFileName(), date('YmdHis'));
// 导出本页和导出选中项都是通过 _ids 查询
$ids = request()->input('_ids');
// listQuery() 为列表查询条件,与获取列表数据一致
$data = $this->service->listQuery()
->with(['items'])
->when($ids, fn($query) => $query->whereIn($this->service->primaryKey(), explode(',', $ids)))
->get();
/** @var \Illuminate\Database\Eloquent\Collection */
$lotteryTypes = Keyword::where('parent_key', 'lottery_type')->oldest('sort')->get();
try {
fastexcel($data->loadMissing(['items']))->export(storage_path('app/' . $path), function($row) use ($lotteryTypes) {
$ledgerItems = collect($row['items'])->keyBy('ledger_item_type_id');
$data = [
__('finance.ledger.date') => $row['date'],
__('finance.ledger.store') => Arr::get($row, 'store.title'),
__('finance.ledger.sales') => $row['sales'],
__('finance.ledger.expenditure') => $row['expenditure'],
__('finance.ledger.new_customers') => $row['new_customers'],
__('finance.ledger.handover_amount') => $row['handover_amount'],
__('finance.ledger.ledger_amount') => $row['ledger_amount'],
__('finance.ledger.ledger_difference') => $row['ledger_difference'],
__('finance.ledger.expected_commission') => $row['expected_commission'],
__('finance.ledger.actual_commission') => $row['actual_commission'],
__('finance.ledger.expected_income') => $row['expected_income'],
__('finance.ledger.actual_income') => $row['actual_income'],
__('workflow_log.check_status') => CheckStatus::tryFrom(Arr::get($row, 'workflow.check_status'))?->text(),
__('finance.ledger.created_at') => $row['created_at'],
];
foreach ($lotteryTypes as $lotteryType) {
$ledgerItem = $ledgerItems->get($lotteryType->key);
$data = array_merge($data, [
"{$lotteryType->name}-销售" => $ledgerItem['sales'] ?? 0,
"{$lotteryType->name}-兑奖" => $ledgerItem['expenditure'] ?? 0,
]);
}
return $data;
});
} catch (\Throwable $e) {
admin_abort(__('admin.action_failed'));
}
return $this->response()->success(compact('path'));
}
}