From cf972448a3bc1b0107df1e6cc7b103cfebe56e3a Mon Sep 17 00:00:00 2001 From: Jing Li Date: Thu, 4 Apr 2024 16:58:10 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B4=A2=E5=8A=A1=E6=8A=A5=E8=A1=A8=E7=9B=B8?= =?UTF-8?q?=E5=85=B3=E5=AE=A1=E6=A0=B8=E6=B5=81=E7=A8=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/Finance/LedgerController.php | 183 ++++++++++++++---- .../Finance/ReimbursementController.php | 34 +++- .../StoreMasterCommissionController.php | 10 +- app/Admin/Filters/LedgerFilter.php | 7 + app/Admin/Filters/ReimbursementFilter.php | 6 +- .../Filters/StoreMasterCommissionFilter.php | 6 +- app/Admin/Services/Finance/LedgerService.php | 34 +++- .../Services/Finance/ReimbursementService.php | 2 +- app/Admin/routes.php | 2 + app/Models/Ledger.php | 3 +- app/Models/Reimbursement.php | 3 +- app/Providers/AppServiceProvider.php | 1 + database/seeders/AdminPermissionSeeder.php | 2 + database/seeders/WorkflowSeeder.php | 1 + 14 files changed, 239 insertions(+), 55 deletions(-) diff --git a/app/Admin/Controllers/Finance/LedgerController.php b/app/Admin/Controllers/Finance/LedgerController.php index 716caaa..346dff7 100644 --- a/app/Admin/Controllers/Finance/LedgerController.php +++ b/app/Admin/Controllers/Finance/LedgerController.php @@ -4,7 +4,9 @@ namespace App\Admin\Controllers\Finance; use App\Admin\Controllers\AdminController; use App\Admin\Services\Finance\LedgerService; +use App\Enums\CheckStatus; use App\Models\Ledger; +use App\Traits\HasCheckActions; use Illuminate\Http\Request; use Illuminate\Support\Facades\Validator; use Slowlyo\OwlAdmin\Admin; @@ -17,6 +19,8 @@ use Slowlyo\OwlAdmin\Renderers\Page; */ class LedgerController extends AdminController { + use HasCheckActions; + protected string $serviceName = LedgerService::class; public function show($id) @@ -24,7 +28,7 @@ class LedgerController extends AdminController if ($this->actionOfGetData()) { /** @var \App\Models\Ledger */ $ledger = Ledger::findOrFail($id); - $ledger->load(['store', 'items.type']); + $ledger->load(['store', 'items.type', 'workflow']); return $this->response()->success( array_merge($ledger->toArray(), [ @@ -49,51 +53,26 @@ class LedgerController extends AdminController return $this->response()->success($page); } - /** - * 修改总账金额 - */ - 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, '修改成功'); - } - public function list(): Page { $crud = $this->baseCRUD() - ->tableLayout('fixed') ->headerToolbar([ ...$this->baseHeaderToolBar(), ]) ->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() - ->columnRatio(4), - amis()->DateRangeControl('date_range', __('finance.ledger.date')) - ->valueFormat('YYYY-MM-DD') - ->columnRatio(4), + ->clearable(), + amis()->SelectControl()->name('check_status')->label(__('workflow_log.check_status')) + ->multiple() + ->options(CheckStatus::options()) + ->clearable(), ]), ])) ->columns([ @@ -110,10 +89,25 @@ class LedgerController extends AdminController 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()->name('created_at')->label(__('finance.ledger.created_at')), + 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}']) + ), + $this->cancelAction(), $this->rowEditLedgerAmountButton() ->visible(Admin::user()->can('admin.finance.ledgers.update_ledger_amount')), + $this->rowEditActualCommissionButton() + ->visible(Admin::user()->can('admin.finance.ledgers.update_actual_commission')) + ->visibleOn('${OR(workflow.check_status == '.CheckStatus::None->value.', workflow.check_status == '.CheckStatus::Cancel->value.', workflow.check_status == '.CheckStatus::Fail->value.')}'), + $this->rowEditActualIncomeButton() + ->visible(Admin::user()->can('admin.finance.ledgers.update_actual_income')) + ->visibleOn('${OR(workflow.check_status == '.CheckStatus::None->value.', workflow.check_status == '.CheckStatus::Cancel->value.', workflow.check_status == '.CheckStatus::Fail->value.')}'), $this->rowShowButton() ->visible(Admin::user()->can('admin.finance.ledgers.view')), ]), @@ -143,7 +137,16 @@ class LedgerController extends AdminController public function detail(): Form { - return $this->baseDetail()->title()->body([ + $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}'], @@ -157,16 +160,66 @@ class LedgerController extends AdminController ['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' => '上报数据', '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->baseWorkflowLogService($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, '保存成功'); + } + + /** + * 修改实际佣金 + */ + public function updateActualCommission($id, Request $request) + { + $this->service->update($id, $request->only(['actual_commission'])); + + return $this->response()->success(null, '保存成功'); + } + + /** + * 修改实际收益 + */ + public function updateActualIncome($id, Request $request) + { + $this->service->update($id, $request->only(['actual_income'])); + + return $this->response()->success(null, '保存成功'); + } + + /** + * 编辑总账金额按钮 + */ protected function rowEditLedgerAmountButton(): DrawerAction { return amis()->DrawerAction() @@ -188,4 +241,54 @@ class LedgerController extends AdminController ])->size('lg') ); } + + /** + * 编辑实际佣金按钮 + */ + protected function rowEditActualCommissionButton(): DrawerAction + { + return amis()->DrawerAction() + ->icon('fa-regular fa-pen-to-square') + ->label(__('finance.ledger.actual_commission')) + ->level('link') + ->drawer( + amis()->Drawer()->title(__('finance.ledger.actual_commission'))->body([ + amis()->Form()->title('') + ->api('post:'.admin_url('finance/ledgers/${id}/actual-commission')) + ->body([ + amis()->NumberControl() + ->name('actual_commission') + ->label(__('finance.ledger.actual_commission')) + ->precision(2) + ->showSteps(false) + ->required(), + ]), + ])->size('lg') + ); + } + + /** + * 编辑实际收益按钮 + */ + protected function rowEditActualIncomeButton(): DrawerAction + { + return amis()->DrawerAction() + ->icon('fa-regular fa-pen-to-square') + ->label(__('finance.ledger.actual_income')) + ->level('link') + ->drawer( + amis()->Drawer()->title(__('finance.ledger.actual_income'))->body([ + amis()->Form()->title('') + ->api('post:'.admin_url('finance/ledgers/${id}/actual-income')) + ->body([ + amis()->NumberControl() + ->name('actual_income') + ->label(__('finance.ledger.actual_income')) + ->precision(2) + ->showSteps(false) + ->required(), + ]), + ])->size('lg') + ); + } } diff --git a/app/Admin/Controllers/Finance/ReimbursementController.php b/app/Admin/Controllers/Finance/ReimbursementController.php index 09d6965..320c018 100644 --- a/app/Admin/Controllers/Finance/ReimbursementController.php +++ b/app/Admin/Controllers/Finance/ReimbursementController.php @@ -4,6 +4,8 @@ namespace App\Admin\Controllers\Finance; use App\Admin\Controllers\AdminController; use App\Admin\Services\Finance\ReimbursementService; +use App\Enums\CheckStatus; +use App\Traits\HasCheckActions; use Slowlyo\OwlAdmin\Admin; use Slowlyo\OwlAdmin\Renderers\Form; use Slowlyo\OwlAdmin\Renderers\Page; @@ -13,6 +15,8 @@ use Slowlyo\OwlAdmin\Renderers\Page; */ class ReimbursementController extends AdminController { + use HasCheckActions; + protected string $serviceName = ReimbursementService::class; public function list(): Page @@ -31,10 +35,17 @@ class ReimbursementController extends AdminController ->source(admin_url('api/keywords/tree-list?parent_key=reimbursement_type')) ->labelField('name') ->valueField('key'), + amis()->SelectControl()->name('check_status')->label(__('workflow_log.check_status')) + ->multiple() + ->options(CheckStatus::options()) + ->clearable(), + ]), + amis()->GroupControl()->mode('horizontal')->body([ amis()->InputDatetimeRange() ->name('created_at') ->label(__('finance.reimbursement.created_at')) - ->format('YYYY-MM-DD HH:mm:ss'), + ->format('YYYY-MM-DD HH:mm:ss') + ->columnRatio(4), ]), ])) ->columns([ @@ -43,9 +54,12 @@ class ReimbursementController extends AdminController amis()->TableColumn()->name('expense')->label(__('finance.reimbursement.expense')), amis()->TableColumn()->name('reason')->label(__('finance.reimbursement.reason')), amis()->TableColumn()->name('type.name')->label(__('finance.reimbursement.type')), + amis()->TableColumn('workflow.check_status', __('workflow_log.check_status'))->set('type', 'mapping')->map(CheckStatus::labelMap()), amis()->TableColumn()->name('created_at')->label(__('finance.reimbursement.created_at')), $this->rowActions([ - $this->rowShowButton()->visible(Admin::user()->can('admin.finance.reimbursements.view')), + $this->applyAction(), + $this->cancelAction(), + $this->rowShowButton()->visible(Admin::user()->can('admin.finance.reimbursements.view')), ]), ]); @@ -54,7 +68,16 @@ class ReimbursementController extends AdminController public function detail(): Form { - return $this->baseDetail()->title()->body([ + $detailId = 'reimbursement-detail'; + $serviceId = 'reimbursement-workflow-service'; + + return $this->baseDetail()->id($detailId)->title('')->onEvent([ + 'inited' => [ + 'actions' => [ + ['actionType' => 'reload', 'componentId' => $serviceId], + ], + ], + ])->body([ amis()->Property()->items([ ['label' => __('finance.reimbursement.employee'), 'content' => '${employee.name}'], ['label' => __('finance.reimbursement.expense'), 'content' => '${expense}'], @@ -62,7 +85,12 @@ class ReimbursementController extends AdminController ['label' => __('finance.reimbursement.type'), 'content' => '${type.name}'], ['label' => __('finance.reimbursement.created_at'), 'content' => '${created_at}'], ['label' => __('finance.reimbursement.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->baseWorkflowLogService($detailId)->id($serviceId), ]); } } diff --git a/app/Admin/Controllers/Finance/StoreMasterCommissionController.php b/app/Admin/Controllers/Finance/StoreMasterCommissionController.php index 5c28ba6..4b1649c 100644 --- a/app/Admin/Controllers/Finance/StoreMasterCommissionController.php +++ b/app/Admin/Controllers/Finance/StoreMasterCommissionController.php @@ -33,14 +33,16 @@ class StoreMasterCommissionController extends AdminController amis()->MonthControl() ->name('month') ->label(__('finance.store_master_commission.month')) - ->valueFormat('YYYY-MM') - ->columnRatio(3), + ->valueFormat('YYYY-MM'), amis()->SelectControl('store_id', __('finance.ledger.store')) ->source(admin_url('api/stores')) ->labelField('title') ->valueField('id') - ->clearable() - ->columnRatio(3), + ->clearable(), + amis()->SelectControl()->name('check_status')->label(__('workflow_log.check_status')) + ->multiple() + ->options(CheckStatus::options()) + ->clearable(), ]), ])) ->columns([ diff --git a/app/Admin/Filters/LedgerFilter.php b/app/Admin/Filters/LedgerFilter.php index 91b08d7..e646139 100644 --- a/app/Admin/Filters/LedgerFilter.php +++ b/app/Admin/Filters/LedgerFilter.php @@ -36,4 +36,11 @@ class LedgerFilter extends ModelFilter ->when($cityCode, fn ($query) => $query->where('region->cityCode', $cityCode)); }); } + + public function checkStatus($checkStatus) + { + $this->related('workflow', function ($query) use ($checkStatus) { + $query->whereIn('check_status', explode(',', $checkStatus)); + }); + } } diff --git a/app/Admin/Filters/ReimbursementFilter.php b/app/Admin/Filters/ReimbursementFilter.php index 1f53c3e..0cd2abf 100644 --- a/app/Admin/Filters/ReimbursementFilter.php +++ b/app/Admin/Filters/ReimbursementFilter.php @@ -21,8 +21,10 @@ class ReimbursementFilter extends ModelFilter $this->whereBetween('created_at', explode(',', $createdAt)); } - public function status($status) + public function checkStatus($checkStatus) { - $this->whereIn('reimbursement_status', explode(',', $status)); + $this->related('workflow', function ($query) use ($checkStatus) { + $query->whereIn('check_status', explode(',', $checkStatus)); + }); } } diff --git a/app/Admin/Filters/StoreMasterCommissionFilter.php b/app/Admin/Filters/StoreMasterCommissionFilter.php index 48865d6..ead5f53 100644 --- a/app/Admin/Filters/StoreMasterCommissionFilter.php +++ b/app/Admin/Filters/StoreMasterCommissionFilter.php @@ -16,8 +16,10 @@ class StoreMasterCommissionFilter extends ModelFilter $this->where('store_id', $id); } - public function status($status) + public function checkStatus($checkStatus) { - $this->whereIn('approval_status', explode(',', $status)); + $this->related('workflow', function ($query) use ($checkStatus) { + $query->whereIn('check_status', explode(',', $checkStatus)); + }); } } diff --git a/app/Admin/Services/Finance/LedgerService.php b/app/Admin/Services/Finance/LedgerService.php index a2294b9..09ee263 100644 --- a/app/Admin/Services/Finance/LedgerService.php +++ b/app/Admin/Services/Finance/LedgerService.php @@ -4,7 +4,9 @@ namespace App\Admin\Services\Finance; use App\Admin\Filters\LedgerFilter; use App\Admin\Services\BaseService; +use App\Enums\CheckStatus; use App\Models\Ledger; +use Illuminate\Support\Facades\Validator; class LedgerService extends BaseService { @@ -12,7 +14,37 @@ class LedgerService extends BaseService protected string $modelFilterName = LedgerFilter::class; - protected array $withRelationships = ['store']; + protected array $withRelationships = ['store', 'workflow']; + + public function update($primaryKey, $data): bool + { + Validator::validate( + data: $data, + rules: [ + 'actual_commission' => ['filled', 'numeric'], + 'actual_income' => ['filled', 'numeric'], + ], + attributes: [ + 'actual_commission' => __('finance.ledger.actual_commission'), + 'actual_income' => __('finance.ledger.actual_income'), + ], + ); + + $model = $this->query()->whereKey($primaryKey)->firstOrFail(); + + switch ($model->workflow->check_status) { + case CheckStatus::Processing: + admin_abort('不能修改审核中的上报数据'); + break; + case CheckStatus::Success: + admin_abort('不能修改审核通过的报数据'); + break; + } + + $model->update($data); + + return true; + } public function sortColumn() { diff --git a/app/Admin/Services/Finance/ReimbursementService.php b/app/Admin/Services/Finance/ReimbursementService.php index 661d5e6..6825777 100644 --- a/app/Admin/Services/Finance/ReimbursementService.php +++ b/app/Admin/Services/Finance/ReimbursementService.php @@ -12,7 +12,7 @@ class ReimbursementService extends BaseService protected string $modelFilterName = ReimbursementFilter::class; - protected array $withRelationships = ['employee', 'type']; + protected array $withRelationships = ['employee', 'type', 'workflow']; public function sortColumn() { diff --git a/app/Admin/routes.php b/app/Admin/routes.php index e518e9c..339034a 100644 --- a/app/Admin/routes.php +++ b/app/Admin/routes.php @@ -124,6 +124,8 @@ Route::group([ // 上报数据 $router->resource('ledgers', LedgerController::class); $router->post('ledgers/{ledger}/ledger-amount', [LedgerController::class, 'updateLedgerAmount'])->name('ledgers.update_ledger_amount'); + $router->post('ledgers/{ledger}/actual-commission', [LedgerController::class, 'updateActualCommission'])->name('ledgers.update_actual_commission'); + $router->post('ledgers/{ledger}/actual-income', [LedgerController::class, 'updateActualIncome'])->name('ledgers.update_actual_income'); // 佣金收入 $router->get('commission-incomes', [CommissionIncomeController::class, 'index'])->name('commission_incomes.index'); // 收支报销 diff --git a/app/Models/Ledger.php b/app/Models/Ledger.php index aad9820..b35e039 100644 --- a/app/Models/Ledger.php +++ b/app/Models/Ledger.php @@ -3,6 +3,7 @@ namespace App\Models; use App\Enums\LedgerStatus; +use App\Traits\HasCheckable; use App\Traits\HasDateTimeFormatter; use EloquentFilter\Filterable; use Illuminate\Database\Eloquent\Casts\Attribute; @@ -13,7 +14,7 @@ use Illuminate\Database\Eloquent\Relations\HasMany; class Ledger extends Model { - use Filterable, HasDateTimeFormatter, HasFactory; + use Filterable, HasDateTimeFormatter, HasFactory, HasCheckable; protected $appends = ['ledger_difference']; diff --git a/app/Models/Reimbursement.php b/app/Models/Reimbursement.php index 6460850..c54a4b4 100644 --- a/app/Models/Reimbursement.php +++ b/app/Models/Reimbursement.php @@ -2,6 +2,7 @@ namespace App\Models; +use App\Traits\HasCheckable; use App\Traits\HasDateTimeFormatter; use EloquentFilter\Filterable; use Illuminate\Database\Eloquent\Casts\Attribute; @@ -11,7 +12,7 @@ use Illuminate\Database\Eloquent\Relations\BelongsTo; class Reimbursement extends Model { - use Filterable, HasDateTimeFormatter, HasFactory; + use Filterable, HasDateTimeFormatter, HasFactory, HasCheckable; protected $fillable = [ 'employee_id', diff --git a/app/Providers/AppServiceProvider.php b/app/Providers/AppServiceProvider.php index 7eef056..c543c18 100644 --- a/app/Providers/AppServiceProvider.php +++ b/app/Providers/AppServiceProvider.php @@ -35,6 +35,7 @@ class AppServiceProvider extends ServiceProvider \App\Models\HolidayApply::class, \App\Models\OvertimeApply::class, \App\Models\OfficalBusiness::class, + \App\Models\Ledger::class, \App\Models\Reimbursement::class, \App\Models\StoreMasterCommission::class, ])->mapWithKeys(fn ($model) => [(new $model)->getTable() => $model])->all() diff --git a/database/seeders/AdminPermissionSeeder.php b/database/seeders/AdminPermissionSeeder.php index 7d895da..9ffd7fa 100644 --- a/database/seeders/AdminPermissionSeeder.php +++ b/database/seeders/AdminPermissionSeeder.php @@ -195,6 +195,8 @@ class AdminPermissionSeeder extends Seeder 'uri' => '/finance/ledgers', 'resource' => ['list', 'update', 'view'], 'children' => [ + 'update_actual_commission' => '编辑实际佣金', + 'update_actual_income' => '编辑实际收益', 'update_ledger_amount' => '编辑总账金额', ], ], diff --git a/database/seeders/WorkflowSeeder.php b/database/seeders/WorkflowSeeder.php index 57ef3a8..36f48e3 100644 --- a/database/seeders/WorkflowSeeder.php +++ b/database/seeders/WorkflowSeeder.php @@ -22,6 +22,7 @@ class WorkflowSeeder extends Seeder ['key' => 'holiday_apply', 'name' => '请假申请', 'config' => $config, 'created_at' => now(), 'updated_at' => now()], ['key' => 'overtime_apply', 'name' => '加班申请', 'config' => $config, 'created_at' => now(), 'updated_at' => now()], ['key' => 'offical_business', 'name' => '出差报备', 'config' => $config, 'created_at' => now(), 'updated_at' => now()], + ['key' => 'ledger', 'name' => '上报数据', 'config' => $config, 'created_at' => now(), 'updated_at' => now()], ['key' => 'reimbursement', 'name' => '收支报销', 'config' => $config, 'created_at' => now(), 'updated_at' => now()], ['key' => 'store_master_commission', 'name' => '店长提成', 'config' => $config, 'created_at' => now(), 'updated_at' => now()], ]);