[CLAUDE] PurchaseEvaluation: Mig 56 ngan sach MA TRAN 3 cot (Du an|PRO|CCM) + badge quyen NS theo role
All checks were successful
Deploy SOLUTION_ERP / build-deploy (push) Successful in 4m57s

S76 (anh Kiet FDC + chi Tra Sol) — form ngan sach + hien thi quyen nhap NS trong flow:
- Part 1: form ngan sach -> MA TRAN 3 cot, moi phong nhap+dieu chinh cot minh
  (PRO canEditPro / CCM canEditCcm / Du an FE hien-thi-only). Mig 56
  +ProInitialAmount/ProAdjustmentAmount (additive-nullable + data-migrate
  ProEstimate->ProInitial). full moi cot = ban hanh + hieu chinh.
- Part 2: Workflow Designer (fe-admin) +badge "NS PRO/CCM" canh approver
  (suy tu role Admin|Procurement / Admin|CostControl, hien-thi-only no-authz).
- Part 3: flow quy trinh fe-user/fe-admin (Duyet NCC) +badge tuong tu.
- Fix race mat-du-lieu Part 1 (useIsFetching khoa Luu khi refetch — dong
  cua-so stale-echo, reviewer Part2/3 bat).
- Test 339->344 (+5). 2 workflow review (Part 1 PASS + Part 2/3 PASS).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
pqhuy1987
2026-06-19 11:02:47 +07:00
parent 70c13d4ac8
commit e33481efb6
19 changed files with 6974 additions and 325 deletions

View File

@ -37,7 +37,12 @@ public record AwLevelDto(
bool AllowReturnToDrafter,
bool AllowApproverEditDetails,
bool AllowApproverEditBudget,
bool AllowApproverSkipToFinal);
bool AllowApproverSkipToFinal,
// [S76] Hiển thị-only: approver này được nhập/điều chỉnh ngân sách cột nào (suy
// từ ROLE — KHÔNG đổi quyền). CanEditProBudget = Admin|Procurement (cột PRO);
// CanEditCcmBudget = Admin|CostControl (cột CCM). Badge "✎ NS PRO/CCM" trong Designer.
bool CanEditProBudget,
bool CanEditCcmBudget);
public record AwStepDto(
Guid Id,
@ -146,6 +151,13 @@ public class GetAwAdminOverviewQueryHandler(
.Select(u => new { u.Id, u.FullName, u.Email })
.ToDictionaryAsync(u => u.Id, u => (u.FullName, u.Email), ct);
// [S76] Hiển thị-only: tập user được nhập/điều chỉnh ngân sách (đảo chiều
// GetUsersInRoleAsync → set-lookup, no N+1). Khớp gate canEditPro/canEditCcm
// (PurchaseEvaluationFeatures.cs:800-801): PRO = Admin|Procurement, CCM = Admin|CostControl.
var adminUserIds = (await userManager.GetUsersInRoleAsync(AppRoles.Admin)).Select(u => u.Id).ToHashSet();
var proBudgetEditors = (await userManager.GetUsersInRoleAsync(AppRoles.Procurement)).Select(u => u.Id).Concat(adminUserIds).ToHashSet();
var ccmBudgetEditors = (await userManager.GetUsersInRoleAsync(AppRoles.CostControl)).Select(u => u.Id).Concat(adminUserIds).ToHashSet();
AwDefinitionDto ToDto(ApprovalWorkflow d) => new(
d.Id,
d.Code,
@ -172,7 +184,8 @@ public class GetAwAdminOverviewQueryHandler(
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.AllowApproverEditBudget,
l.AllowApproverSkipToFinal);
l.AllowApproverSkipToFinal,
proBudgetEditors.Contains(l.ApproverUserId), ccmBudgetEditors.Contains(l.ApproverUserId));
}).ToList()
)).ToList());