ui and bug fixers 29/09
This commit is contained in:
@@ -107,11 +107,14 @@ public sealed class AuthHexClient : IAuthHexClient
|
||||
|
||||
// ---- RecoveryManager ------------------------------------------------
|
||||
|
||||
public Task<ForgotPasswordResponse> ForgotPasswordAsync(ForgotPasswordRequest request, CancellationToken ct)
|
||||
=> CallAsync<ForgotPasswordResponse>("recovery", "forgotPassword", request, null, ct);
|
||||
// RecoveryManagerService returns its own { success, message, data } object, which the
|
||||
// function handler then wraps again as the envelope's `data` — so the payload sits one
|
||||
// level deeper than for other AuthHex calls (ERP_Auth_Service RecoveryManager.cs).
|
||||
public async Task<ForgotPasswordResponse> ForgotPasswordAsync(ForgotPasswordRequest request, CancellationToken ct)
|
||||
=> Unwrap(await CallAsync<AuthHexEnvelope<ForgotPasswordResponse>>("recovery", "forgotPassword", request, null, ct));
|
||||
|
||||
public Task<VerifyRecoveryOtpResponse> VerifyRecoveryOtpAsync(VerifyRecoveryOtpRequest request, CancellationToken ct)
|
||||
=> CallAsync<VerifyRecoveryOtpResponse>("recovery", "verifyOTP", request, null, ct);
|
||||
public async Task<VerifyRecoveryOtpResponse> VerifyRecoveryOtpAsync(VerifyRecoveryOtpRequest request, CancellationToken ct)
|
||||
=> Unwrap(await CallAsync<AuthHexEnvelope<VerifyRecoveryOtpResponse>>("recovery", "verifyOTP", request, null, ct));
|
||||
|
||||
public Task ResetPasswordAsync(ResetPasswordRequest request, CancellationToken ct)
|
||||
=> CallVoidAsync("recovery", "resetPassword", request, null, ct);
|
||||
@@ -149,6 +152,14 @@ public sealed class AuthHexClient : IAuthHexClient
|
||||
|
||||
// ---- Transport --------------------------------------------------------
|
||||
|
||||
/// <summary>Unwraps the inner result object that the recovery functions nest inside the envelope's data.</summary>
|
||||
private static T Unwrap<T>(AuthHexEnvelope<T>? inner)
|
||||
{
|
||||
if (inner is null || !inner.Success || inner.Data is null)
|
||||
throw new DomainException(ErrorCodes.AuthUpstreamError, inner?.Message ?? "Authentication request failed.", 400);
|
||||
return inner.Data;
|
||||
}
|
||||
|
||||
private async Task CallVoidAsync(string routeGroup, string functionName, object payload, string? bearerToken, CancellationToken ct)
|
||||
=> await CallAsync<JsonElement?>(routeGroup, functionName, payload, bearerToken, ct);
|
||||
|
||||
|
||||
@@ -21,6 +21,8 @@ public sealed class BranchConfigConfiguration : IEntityTypeConfiguration<BranchC
|
||||
builder.Property(c => c.ConfigId).ValueGeneratedNever();
|
||||
|
||||
builder.Property(c => c.BranchingEnabled).IsRequired().HasDefaultValue(true);
|
||||
// Defaults on so the existing row keeps today's per-branch purchase orders.
|
||||
builder.Property(c => c.PurchaseOrderBranchingEnabled).IsRequired().HasDefaultValue(true);
|
||||
|
||||
// PostgreSQL xmin system column as the optimistic concurrency token (ETag).
|
||||
builder.Property(c => c.RowVersion).IsRowVersion();
|
||||
|
||||
@@ -18,6 +18,8 @@ public sealed class VendorConfiguration : IEntityTypeConfiguration<Vendor>
|
||||
builder.Property(v => v.Name).IsRequired().HasMaxLength(200);
|
||||
builder.Property(v => v.Terms).HasMaxLength(50);
|
||||
builder.Property(v => v.TaxReg).HasMaxLength(50);
|
||||
builder.Property(v => v.Address).HasMaxLength(500);
|
||||
builder.Property(v => v.Phone).HasMaxLength(30);
|
||||
builder.Property(v => v.Currency).IsRequired().HasMaxLength(3).HasDefaultValue("LKR");
|
||||
|
||||
builder.Property(v => v.Status)
|
||||
|
||||
@@ -195,7 +195,12 @@ public class ErpDbContext : DbContext
|
||||
modelBuilder.Entity<Customer>().HasQueryFilter(e => !_currentBranch.IsActive || e.BranchId == _currentBranch.BranchId);
|
||||
modelBuilder.Entity<Requisition>().HasQueryFilter(e => !_currentBranch.IsActive || e.BranchId == _currentBranch.BranchId);
|
||||
modelBuilder.Entity<Rfq>().HasQueryFilter(e => !_currentBranch.IsActive || e.BranchId == _currentBranch.BranchId);
|
||||
modelBuilder.Entity<PurchaseOrder>().HasQueryFilter(e => !_currentBranch.IsActive || e.BranchId == _currentBranch.BranchId);
|
||||
// Purchase orders are only scoped while the "divide purchase orders by branch" toggle is
|
||||
// on — off turns them into one shared pool every branch can see.
|
||||
modelBuilder.Entity<PurchaseOrder>().HasQueryFilter(e => !_currentBranch.IsActive
|
||||
|| e.BranchId == _currentBranch.BranchId
|
||||
|| !Set<Domain.Entities.BranchConfig>().Any(c => c.ConfigId == Domain.Entities.BranchConfig.SingletonId
|
||||
&& c.BranchingEnabled && c.PurchaseOrderBranchingEnabled));
|
||||
modelBuilder.Entity<PurchaseInvoice>().HasQueryFilter(e => !_currentBranch.IsActive || e.BranchId == _currentBranch.BranchId);
|
||||
|
||||
// Npgsql requires DateTime values written to `timestamp with time zone` columns
|
||||
|
||||
Reference in New Issue
Block a user