branch crud and intergration

This commit is contained in:
2026-09-08 12:13:49 +05:30
parent bebec10eb3
commit f664961fce
113 changed files with 41598 additions and 174 deletions
@@ -0,0 +1,20 @@
using System.ComponentModel.DataAnnotations;
namespace ERPCore.Dtos.Config;
/// <summary>Branch configuration resource — the singleton toggle for whether this deployment
/// requires a branch on Employee/Warehouse records at all.</summary>
public sealed record BranchConfigDto(bool BranchingEnabled, DateTime? UpdatedAt, int? UpdatedBy);
/// <summary>
/// Full replacement of the flag. <c>UpdatedBy</c> is derived from the token, never posted.
/// <para>
/// <see cref="BranchingEnabled"/> is <see cref="bool"/>? deliberately: <c>[Required]</c> on a
/// non-nullable bool is a no-op, so an omitted flag would otherwise silently bind to
/// <c>false</c>. Nullable makes the requirement actually bind — an omitted flag is a 400.
/// </para>
/// </summary>
public sealed class UpdateBranchConfigRequest
{
[Required] public bool? BranchingEnabled { get; set; }
}
+4 -4
View File
@@ -6,7 +6,7 @@ namespace ERPCore.Dtos.Hrm;
public sealed record EmployeeListItemDto(
int EmployeeId, string EmployeeCode, string FullName, string? Email,
int DepartmentId, string? DepartmentName, int DesignationId, string? DesignationName,
int EmploymentTypeId, string? EmploymentTypeName, int? BranchId, string? BranchName,
int EmploymentTypeId, string? EmploymentTypeName, int BranchId, string? BranchName,
EmployeeStatus Status, bool HasUserLink, DateTime HireDate);
public sealed record EmployeeDetailDto(
@@ -16,7 +16,7 @@ public sealed record EmployeeDetailDto(
string? City, string? PostalCode, string? Country,
string? EmergencyContactName, string? EmergencyContactRelationship, string? EmergencyContactPhone,
DateTime HireDate, DateTime? ConfirmationDate, DateTime? LastWorkingDate,
int DepartmentId, int DesignationId, int EmploymentTypeId, int? BranchId, int WorkShiftId,
int DepartmentId, int DesignationId, int EmploymentTypeId, int BranchId, int WorkShiftId,
int? ReportingManagerId, string? EpfNumber, string? EtfNumber, string? TaxIdentificationNumber,
int? UserId, EmployeeStatus Status, DateTime CreatedAt, DateTime? UpdatedAt);
@@ -45,7 +45,7 @@ public sealed class CreateEmployeeRequest
[Required] public int DepartmentId { get; set; }
[Required] public int DesignationId { get; set; }
[Required] public int EmploymentTypeId { get; set; }
public int? BranchId { get; set; }
[Required] public int BranchId { get; set; }
[Required] public int WorkShiftId { get; set; }
public int? ReportingManagerId { get; set; }
@@ -82,7 +82,7 @@ public sealed class UpdateEmployeeRequest
[Required] public int DepartmentId { get; set; }
[Required] public int DesignationId { get; set; }
[Required] public int EmploymentTypeId { get; set; }
public int? BranchId { get; set; }
[Required] public int BranchId { get; set; }
[Required] public int WorkShiftId { get; set; }
public int? ReportingManagerId { get; set; }
+4 -2
View File
@@ -7,20 +7,22 @@ namespace ERPCore.Dtos.Hrm;
// ids, timestamps) excluded from create/update requests (02-SECURITY B.6/C.1).
public sealed record BranchDto(
int BranchId, string Code, string Name, string? Address, EntityStatus Status,
int BranchId, string Code, string Name, string? Address, string? PhoneNumber, EntityStatus Status,
DateTime CreatedAt, DateTime? UpdatedAt);
// Code is server-generated (BranchService.GenerateCodeAsync) — never accepted from the client.
public sealed class CreateBranchRequest
{
[Required, StringLength(20)] public string Code { get; set; } = string.Empty;
[Required, StringLength(200)] public string Name { get; set; } = string.Empty;
[StringLength(500)] public string? Address { get; set; }
[StringLength(30)] public string? PhoneNumber { get; set; }
}
public sealed class UpdateBranchRequest
{
[Required, StringLength(200)] public string Name { get; set; } = string.Empty;
[StringLength(500)] public string? Address { get; set; }
[StringLength(30)] public string? PhoneNumber { get; set; }
}
public sealed record DepartmentDto(
+10 -2
View File
@@ -2,5 +2,13 @@ namespace ERPCore.Dtos.Rbac;
/// <summary>Response for `GET /api/v1/auth/me` — the frontend's authoritative source
/// for the current user's role and permitted sidebar nav codes (replaces trusting
/// the stale, client-only `roleId` cached in localStorage).</summary>
public sealed record MeResponseDto(string? RoleCode, string? RoleName, IReadOnlyList<string> NavCodes);
/// the stale, client-only `roleId` cached in localStorage). <see cref="BranchId"/>/
/// <see cref="BranchName"/> come from the caller's linked <c>Employee</c> record, when
/// one exists — null for a login with no Employee link. <see cref="IsAdmin"/> gates
/// branch pickers client-side only (no server-side branch enforcement exists yet,
/// see docs/BRANCH_ISOLATION_PLAN.md). <see cref="BranchingEnabled"/> mirrors the
/// singleton <c>BranchConfig</c> toggle — when false the frontend hides branch pickers
/// entirely rather than merely restricting them by role.</summary>
public sealed record MeResponseDto(
string? RoleCode, string? RoleName, IReadOnlyList<string> NavCodes,
bool IsAdmin, int? BranchId, string? BranchName, bool BranchingEnabled);
+16
View File
@@ -30,6 +30,22 @@ public sealed class CreateUserRequest
/// email-lookup — never automatic, even on an exact email match (docs/12-BACKEND-HRM.md A.5).
/// </summary>
public int? LinkEmployeeId { get; set; }
/// <summary>
/// Required, together with <see cref="DepartmentId"/>/<see cref="DesignationId"/>/
/// <see cref="EmploymentTypeId"/>/<see cref="WorkShiftId"/>/<see cref="BranchId"/>, whenever
/// the assigned Role is not Admin and <see cref="LinkEmployeeId"/> is not supplied: creates
/// the linked Employee record whose BranchId is what actually scopes this account to one
/// branch (see BranchAccessService.EnsureBranchVisibleAsync).
/// </summary>
public string? EmployeeCode { get; set; }
public int? BranchId { get; set; }
public int? DepartmentId { get; set; }
public int? DesignationId { get; set; }
public int? EmploymentTypeId { get; set; }
public int? WorkShiftId { get; set; }
/// <summary>Defaults to today when omitted.</summary>
public DateTime? HireDate { get; set; }
}
public sealed class UpdateUserRoleRequest
@@ -2,8 +2,10 @@ using System.ComponentModel.DataAnnotations;
namespace ERPCore.Dtos.Warehouses;
/// <summary>Warehouse resource (docs/11-BACKEND-PHASE1.md §2.5).</summary>
public sealed record WarehouseDto(int WarehouseId, string Code, string Name);
/// <summary>Warehouse resource (docs/11-BACKEND-PHASE1.md §2.5). <see cref="BranchId"/> is
/// the anchor `docs/BRANCH_ISOLATION_PLAN.md` uses to branch-scope everything that carries
/// a `warehouseId` (Sales, GRN, stock, ...) without a column on every one of those entities.</summary>
public sealed record WarehouseDto(int WarehouseId, string Code, string Name, int BranchId, string? BranchName);
/// <summary>Bin/location resource (docs/11 §2.5).</summary>
public sealed record BinDto(int BinId, int WarehouseId, string Code, string? BinType);
@@ -12,6 +14,7 @@ public sealed class CreateWarehouseRequest
{
[Required, StringLength(50)] public string Code { get; set; } = string.Empty;
[Required, StringLength(200)] public string Name { get; set; } = string.Empty;
[Required] public int BranchId { get; set; }
}
public sealed class CreateBinRequest