feat: 實作應付帳款與銷售訂單權限管理與進貨單權限修正
All checks were successful
ERP-Deploy-Demo / deploy-demo (push) Successful in 1m17s

This commit is contained in:
2026-02-24 17:29:09 +08:00
parent 455f945296
commit e406ecd63d
8 changed files with 57 additions and 33 deletions

View File

@@ -193,7 +193,9 @@ class RoleController extends Controller
'production_orders' => '生產工單管理',
'utility_fees' => '公共事業費管理',
'accounting' => '會計報表',
'account_payables' => '應付帳款',
'sales_imports' => '銷售單匯入管理',
'sales_orders' => '銷售訂單管理',
'store_requisitions' => '門市叫貨申請',
'users' => '使用者管理',
'roles' => '角色與權限',

View File

@@ -9,11 +9,17 @@ use App\Modules\Finance\Controllers\AccountPayableController;
Route::middleware('auth')->group(function () {
// 應付帳款
Route::group(['prefix' => 'finance'], function () {
Route::middleware('permission:account_payables.view')->group(function () {
Route::get('/account-payables', [AccountPayableController::class, 'index'])->name('account-payables.index');
Route::get('/account-payables/{accountPayable}', [AccountPayableController::class, 'show'])->name('account-payables.show');
});
Route::middleware('permission:account_payables.edit')->group(function () {
Route::post('/account-payables/{accountPayable}/invoice', [AccountPayableController::class, 'updateInvoice'])->name('account-payables.invoice');
});
Route::middleware('permission:account_payables.pay')->group(function () {
Route::post('/account-payables/{accountPayable}/pay', [AccountPayableController::class, 'pay'])->name('account-payables.pay');
});
});
// 公共事業費管理
Route::middleware('permission:utility_fees.view')->group(function () {

View File

@@ -5,7 +5,9 @@ use Illuminate\Support\Facades\Route;
Route::middleware(['web', 'auth', 'verified'])->group(function () {
Route::prefix('integration')->name('integration.')->group(function () {
Route::middleware('permission:sales_orders.view')->group(function () {
Route::get('sales-orders', [SalesOrderController::class, 'index'])->name('sales-orders.index');
Route::get('sales-orders/{salesOrder}', [SalesOrderController::class, 'show'])->name('sales-orders.show');
});
});
});

View File

@@ -185,7 +185,7 @@ class GoodsReceiptController extends Controller
public function submit(GoodsReceipt $goodsReceipt)
{
if (!auth()->user()->can('goods_receipts.update')) {
if (!auth()->user()->can('goods_receipts.edit')) {
return back()->with('error', '您沒有權限確認點收');
}

View File

@@ -183,7 +183,7 @@ Route::middleware('auth')->group(function () {
// 點收提交路由
Route::post('/goods-receipts/{goods_receipt}/submit', [\App\Modules\Inventory\Controllers\GoodsReceiptController::class, 'submit'])
->middleware('permission:goods_receipts.update')
->middleware('permission:goods_receipts.edit')
->name('goods-receipts.submit');
Route::delete('/goods-receipts/{goods_receipt}', [\App\Modules\Inventory\Controllers\GoodsReceiptController::class, 'destroy'])

View File

@@ -65,7 +65,7 @@ class PermissionSeeder extends Seeder
// 進貨單管理
'goods_receipts.view' => '檢視',
'goods_receipts.create' => '建立',
'goods_receipts.edit' => '編輯',
'goods_receipts.edit' => '確認點收',
'goods_receipts.delete' => '刪除',
// 出貨單管理 (Delivery Notes / Shipping Orders)
@@ -126,6 +126,11 @@ class PermissionSeeder extends Seeder
'accounting.view' => '檢視',
'accounting.export' => '匯出',
// 應付帳款管理
'account_payables.view' => '檢視',
'account_payables.edit' => '登記發票',
'account_payables.pay' => '標記付款',
// 銷售匯入管理
'sales_imports.view' => '檢視',
'sales_imports.create' => '建立',
@@ -184,6 +189,7 @@ class PermissionSeeder extends Seeder
'system.view_logs',
'utility_fees.view', 'utility_fees.create', 'utility_fees.edit', 'utility_fees.delete',
'accounting.view', 'accounting.export',
'account_payables.view', 'account_payables.edit', 'account_payables.pay',
'sales_imports.view', 'sales_imports.create', 'sales_imports.confirm', 'sales_imports.delete',
'store_requisitions.view', 'store_requisitions.create', 'store_requisitions.edit',
'store_requisitions.delete', 'store_requisitions.approve', 'store_requisitions.cancel',
@@ -225,6 +231,7 @@ class PermissionSeeder extends Seeder
'utility_fees.view',
'inventory_report.view',
'accounting.view',
'account_payables.view',
'sales_orders.view',
]);

View File

@@ -10,6 +10,7 @@ import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter, DialogD
import { Input } from '@/Components/ui/input';
import { Label } from '@/Components/ui/label';
import { toast } from 'sonner';
import { Can } from '@/Components/Permission/Can';
const getStatusBadgeVariant = (status: string) => {
switch (status) {
@@ -117,6 +118,7 @@ export default function AccountPayableShow({ payable }: any) {
</div>
<div className="flex items-center gap-2">
<Can permission="account_payables.edit">
<Button
variant="outline"
className="gap-2 button-outlined-primary"
@@ -125,8 +127,10 @@ export default function AccountPayableShow({ payable }: any) {
<FileText className="h-4 w-4" />
</Button>
</Can>
{payable.status !== 'paid' && (
<Can permission="account_payables.pay">
<Button
className="gap-2 button-filled-primary"
onClick={() => setPaymentDialogOpen(true)}
@@ -134,6 +138,7 @@ export default function AccountPayableShow({ payable }: any) {
<CheckCircle className="h-4 w-4" />
</Button>
</Can>
)}
</div>
</div>
@@ -225,6 +230,7 @@ export default function AccountPayableShow({ payable }: any) {
<FileText className="h-5 w-5 text-primary-main" />
</h2>
<Can permission="account_payables.edit">
<Button
variant="ghost"
size="sm"
@@ -233,6 +239,7 @@ export default function AccountPayableShow({ payable }: any) {
>
{payable.invoice_number ? '修改' : '填寫'}
</Button>
</Can>
</div>
<div className="space-y-4">
<div>

View File

@@ -250,7 +250,7 @@ function GoodsReceiptActions({ receipt }: { receipt: GoodsReceipt }) {
// 權限判斷
const canView = isSuperAdmin || permissions.includes('goods_receipts.view');
const canEdit = isSuperAdmin || permissions.includes('goods_receipts.update');
const canEdit = isSuperAdmin || permissions.includes('goods_receipts.edit');
const canDelete = isSuperAdmin || permissions.includes('goods_receipts.delete');
const canSubmit = canEdit || canView;