[CLAUDE] PE-Workflow: S22+5 Chunk A — Mig 30 +AllowApproverEditBudget per-Level slot

Bro clarify spec S22+4:
- KHÔNG đổi logic edit ngân sách (Drafter Nháp/TraLai vẫn duy nhất default)
- Thêm flag per-NV slot trong Designer: "Cho phép NV này edit Section ngân sách
  lúc đang duyệt" (mirror pattern F3 AllowApproverEditDetails Mig 29)

Mig 30 `AddAllowApproverEditBudgetToLevels`:
- ALTER ApprovalWorkflowLevels +AllowApproverEditBudget bit NOT NULL DEFAULT 0
- 3-file rule (mig.cs + Designer.cs + Snapshot.cs)
- Apply LocalDB Dev + Design

Domain entity ApprovalWorkflowLevel +AllowApproverEditBudget (default false).
EF config HasDefaultValue(false). DTO AwLevelDto + ApprovalWorkflowOptionsDto
+ CreateAwLevelInput all extend +AllowApproverEditBudget.

PE GET handler populate currentLevelOptions thêm AllowApproverEditBudget từ
curLevel slot. Admin Designer GET/POST handler propagate flag.

AdjustBudgetCommand handler refactor ChoDuyet branch:
- Trước: check actor match level.ApproverUserId (cho phép mặc định)
- Sau: check level.AllowApproverEditBudget=true AND actor match ApproverUserId
  → throw ConflictException nếu slot chưa được cấp quyền

Verify:
- dotnet build SolutionErp.slnx — 0 err, 2 warn DocxRenderer pre-existing
- Mig 30 applied Dev + Design DB

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
pqhuy1987
2026-05-13 23:09:48 +07:00
parent 30d51c89bb
commit b079b27343
8 changed files with 4005 additions and 9 deletions

View File

@ -28,12 +28,14 @@ public record AwLevelDto(
string? ApproverUserName,
string? ApproverEmail,
// Mig 29 (S21 t5) — 5 advanced options per slot Approver (F1 mode Trả lại
// + F3 Edit Section 2). Mỗi NV trong workflow có quyền riêng.
// + F3 Edit Section 2). Mig 30 (S22+5) — F4 +AllowApproverEditBudget.
// Mỗi NV trong workflow có quyền riêng.
bool AllowReturnOneLevel,
bool AllowReturnOneStep,
bool AllowReturnToAssignee,
bool AllowReturnToDrafter,
bool AllowApproverEditDetails);
bool AllowApproverEditDetails,
bool AllowApproverEditBudget);
public record AwStepDto(
Guid Id,
@ -152,7 +154,7 @@ public class GetAwAdminOverviewQueryHandler(
// Mig 29 (S21 t5) — 5 Allow* flag per slot Level
return new AwLevelDto(l.Id, l.Order, l.Name, l.ApproverUserId, info.FullName, info.Email,
l.AllowReturnOneLevel, l.AllowReturnOneStep, l.AllowReturnToAssignee,
l.AllowReturnToDrafter, l.AllowApproverEditDetails);
l.AllowReturnToDrafter, l.AllowApproverEditDetails, l.AllowApproverEditBudget);
}).ToList()
)).ToList());
@ -184,12 +186,13 @@ public record CreateAwLevelInput(
Guid ApproverUserId,
// Mig 29 (S21 t5) — 5 Allow* options per slot. Admin Designer tick per
// Level row. Default backward compat: AllowReturnToDrafter=true, 4 còn lại
// false (admin opt-in từng slot).
// false (admin opt-in từng slot). Mig 30 (S22+5) — F4 AllowApproverEditBudget.
bool AllowReturnOneLevel = false,
bool AllowReturnOneStep = false,
bool AllowReturnToAssignee = false,
bool AllowReturnToDrafter = true,
bool AllowApproverEditDetails = false);
bool AllowApproverEditDetails = false,
bool AllowApproverEditBudget = false);
public record CreateAwStepInput(
int Order,
@ -315,6 +318,7 @@ public class CreateAwDefinitionCommandHandler(IApplicationDbContext db)
AllowReturnToAssignee = l.AllowReturnToAssignee,
AllowReturnToDrafter = l.AllowReturnToDrafter,
AllowApproverEditDetails = l.AllowApproverEditDetails,
AllowApproverEditBudget = l.AllowApproverEditBudget,
}).ToList(),
})
.ToList(),