Split QueryStatus.Accepted into ProAccepted/ClientAccepted
Distinguish the two parties' acceptances: ProAccepted (provider) and ClientAccepted (client) replace the single Accepted value for new acceptances. Accepted=2 is retained as a legacy value so existing DB rows keep their integer mapping. - FrontOfficeApiController.AcceptQuery sets status by ActorRole - BillingController provider-ongoing filters match the new values - FrontOfficeController (MVC) dashboard counts use ProAccepted||Accepted - PostIt: IsOngoingStatus, GetStatusRank (client-accepted ranks first for the pro), and status-badge switches (P/C glyphs) handle the new values - Tests assert ProAccepted (provider) vs ClientAccepted (client) Co-Authored-By: Claude Code <noreply@anthropic.com>
This commit is contained in:
parent
36ffe4683c
commit
827fe6b41f
8 changed files with 62 additions and 19 deletions
|
|
@ -171,5 +171,9 @@ public partial class BillingQueriesPageViewModel : ViewModelBase, IActionStatusV
|
||||||
}
|
}
|
||||||
|
|
||||||
private static bool IsOngoingStatus(QueryStatus status)
|
private static bool IsOngoingStatus(QueryStatus status)
|
||||||
=> status is QueryStatus.Inserted or QueryStatus.Accepted or QueryStatus.InProgress;
|
=> status is QueryStatus.Inserted
|
||||||
|
or QueryStatus.Accepted
|
||||||
|
or QueryStatus.ProAccepted
|
||||||
|
or QueryStatus.ClientAccepted
|
||||||
|
or QueryStatus.InProgress;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -166,6 +166,8 @@ public partial class BillingQueryDetailsPageViewModel : ViewModelBase, IActionSt
|
||||||
=> status switch
|
=> status switch
|
||||||
{
|
{
|
||||||
QueryStatus.Accepted => "#E6F7EC",
|
QueryStatus.Accepted => "#E6F7EC",
|
||||||
|
QueryStatus.ProAccepted => "#E6F7EC",
|
||||||
|
QueryStatus.ClientAccepted => "#E1F5FE",
|
||||||
QueryStatus.InProgress => "#FFF4D6",
|
QueryStatus.InProgress => "#FFF4D6",
|
||||||
QueryStatus.Rejected => "#FDECEA",
|
QueryStatus.Rejected => "#FDECEA",
|
||||||
QueryStatus.Failed => "#ECEFF1",
|
QueryStatus.Failed => "#ECEFF1",
|
||||||
|
|
@ -177,6 +179,8 @@ public partial class BillingQueryDetailsPageViewModel : ViewModelBase, IActionSt
|
||||||
=> status switch
|
=> status switch
|
||||||
{
|
{
|
||||||
QueryStatus.Accepted => "#2E7D32",
|
QueryStatus.Accepted => "#2E7D32",
|
||||||
|
QueryStatus.ProAccepted => "#2E7D32",
|
||||||
|
QueryStatus.ClientAccepted => "#1565C0",
|
||||||
QueryStatus.InProgress => "#B26A00",
|
QueryStatus.InProgress => "#B26A00",
|
||||||
QueryStatus.Rejected => "#C62828",
|
QueryStatus.Rejected => "#C62828",
|
||||||
QueryStatus.Failed => "#607D8B",
|
QueryStatus.Failed => "#607D8B",
|
||||||
|
|
@ -188,6 +192,8 @@ public partial class BillingQueryDetailsPageViewModel : ViewModelBase, IActionSt
|
||||||
=> status switch
|
=> status switch
|
||||||
{
|
{
|
||||||
QueryStatus.Accepted => "#1B5E20",
|
QueryStatus.Accepted => "#1B5E20",
|
||||||
|
QueryStatus.ProAccepted => "#1B5E20",
|
||||||
|
QueryStatus.ClientAccepted => "#0D47A1",
|
||||||
QueryStatus.InProgress => "#7A4A00",
|
QueryStatus.InProgress => "#7A4A00",
|
||||||
QueryStatus.Rejected => "#8E0000",
|
QueryStatus.Rejected => "#8E0000",
|
||||||
QueryStatus.Failed => "#37474F",
|
QueryStatus.Failed => "#37474F",
|
||||||
|
|
@ -199,6 +205,8 @@ public partial class BillingQueryDetailsPageViewModel : ViewModelBase, IActionSt
|
||||||
=> status switch
|
=> status switch
|
||||||
{
|
{
|
||||||
QueryStatus.Accepted => "OK",
|
QueryStatus.Accepted => "OK",
|
||||||
|
QueryStatus.ProAccepted => "P",
|
||||||
|
QueryStatus.ClientAccepted => "C",
|
||||||
QueryStatus.InProgress => "~",
|
QueryStatus.InProgress => "~",
|
||||||
QueryStatus.Rejected => "!",
|
QueryStatus.Rejected => "!",
|
||||||
QueryStatus.Failed => "X",
|
QueryStatus.Failed => "X",
|
||||||
|
|
|
||||||
|
|
@ -344,11 +344,13 @@ public partial class ProviderOngoingRequestsPageViewModel : ViewModelBase, IActi
|
||||||
=> status switch
|
=> status switch
|
||||||
{
|
{
|
||||||
QueryStatus.InProgress => 0,
|
QueryStatus.InProgress => 0,
|
||||||
QueryStatus.Accepted => 1,
|
QueryStatus.ClientAccepted => 1,
|
||||||
QueryStatus.Inserted => 2,
|
QueryStatus.ProAccepted => 2,
|
||||||
QueryStatus.Success => 3,
|
QueryStatus.Accepted => 2,
|
||||||
QueryStatus.Rejected => 4,
|
QueryStatus.Inserted => 3,
|
||||||
QueryStatus.Failed => 5,
|
QueryStatus.Success => 4,
|
||||||
|
QueryStatus.Rejected => 5,
|
||||||
|
QueryStatus.Failed => 6,
|
||||||
_ => 99,
|
_ => 99,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,15 +5,28 @@ namespace Yavsc
|
||||||
/// should be associated to any
|
/// should be associated to any
|
||||||
/// client user query to a provider user or
|
/// client user query to a provider user or
|
||||||
/// other external entity.
|
/// other external entity.
|
||||||
|
///
|
||||||
|
/// <para>
|
||||||
|
/// Acceptance is split by party: <see cref="ProAccepted"/> when the
|
||||||
|
/// provider accepts the client's request (and produces/submits the
|
||||||
|
/// estimate), <see cref="ClientAccepted"/> when the client accepts
|
||||||
|
/// the provider's estimate. <see cref="Accepted"/> is the legacy
|
||||||
|
/// single-value kept for rows written before the split; new writes
|
||||||
|
/// use the party-specific values. Its integer value (2) is stable
|
||||||
|
/// so existing rows still deserialize.
|
||||||
|
/// </para>
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public enum QueryStatus: int
|
public enum QueryStatus: int
|
||||||
{
|
{
|
||||||
Inserted,
|
Inserted = 0,
|
||||||
Rejected,
|
Rejected = 1,
|
||||||
Accepted,
|
Accepted = 2,
|
||||||
InProgress,
|
InProgress = 3,
|
||||||
// final states
|
// final states
|
||||||
Failed,
|
Failed = 4,
|
||||||
Success
|
Success = 5,
|
||||||
|
// party-specific acceptance (see summary)
|
||||||
|
ProAccepted = 6,
|
||||||
|
ClientAccepted = 7,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -127,7 +127,8 @@ public sealed class FrontOfficeApiControllerTests : IClassFixture<ApiWebServerFi
|
||||||
var assertDb = assertScope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
|
var assertDb = assertScope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
|
||||||
var updated = assertDb.RdvQueries.Single(q => q.Id == queryId);
|
var updated = assertDb.RdvQueries.Single(q => q.Id == queryId);
|
||||||
|
|
||||||
Assert.Equal(QueryStatus.Accepted, updated.Status);
|
// Default caller is "alice" (the provider) → ProAccepted.
|
||||||
|
Assert.Equal(QueryStatus.ProAccepted, updated.Status);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Fact]
|
[Fact]
|
||||||
|
|
@ -146,7 +147,7 @@ public sealed class FrontOfficeApiControllerTests : IClassFixture<ApiWebServerFi
|
||||||
using var assertScope = _fixture.Services.CreateScope();
|
using var assertScope = _fixture.Services.CreateScope();
|
||||||
var assertDb = assertScope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
|
var assertDb = assertScope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
|
||||||
|
|
||||||
Assert.Equal(QueryStatus.Accepted, assertDb.RdvQueries.Single(q => q.Id == queryId).Status);
|
Assert.Equal(QueryStatus.ProAccepted, assertDb.RdvQueries.Single(q => q.Id == queryId).Status);
|
||||||
|
|
||||||
var estimate = assertDb.Estimates.Single(e => e.Id == estimateId);
|
var estimate = assertDb.Estimates.Single(e => e.Id == estimateId);
|
||||||
Assert.True(estimate.ProviderValidationDate != default);
|
Assert.True(estimate.ProviderValidationDate != default);
|
||||||
|
|
@ -173,7 +174,7 @@ public sealed class FrontOfficeApiControllerTests : IClassFixture<ApiWebServerFi
|
||||||
using var assertScope = _fixture.Services.CreateScope();
|
using var assertScope = _fixture.Services.CreateScope();
|
||||||
var assertDb = assertScope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
|
var assertDb = assertScope.ServiceProvider.GetRequiredService<ApplicationDbContext>();
|
||||||
|
|
||||||
Assert.Equal(QueryStatus.Accepted, assertDb.RdvQueries.Single(q => q.Id == queryId).Status);
|
Assert.Equal(QueryStatus.ClientAccepted, assertDb.RdvQueries.Single(q => q.Id == queryId).Status);
|
||||||
|
|
||||||
var estimate = assertDb.Estimates.Single(e => e.Id == estimateId);
|
var estimate = assertDb.Estimates.Single(e => e.Id == estimateId);
|
||||||
Assert.True(estimate.ClientValidationDate != default);
|
Assert.True(estimate.ClientValidationDate != default);
|
||||||
|
|
|
||||||
|
|
@ -157,6 +157,8 @@ namespace Yavsc.ApiControllers
|
||||||
.Where(q => allowedActivityCodes.Contains(q.ActivityCode))
|
.Where(q => allowedActivityCodes.Contains(q.ActivityCode))
|
||||||
.Where(q => q.Status == QueryStatus.Inserted
|
.Where(q => q.Status == QueryStatus.Inserted
|
||||||
|| q.Status == QueryStatus.Accepted
|
|| q.Status == QueryStatus.Accepted
|
||||||
|
|| q.Status == QueryStatus.ProAccepted
|
||||||
|
|| q.Status == QueryStatus.ClientAccepted
|
||||||
|| q.Status == QueryStatus.InProgress)
|
|| q.Status == QueryStatus.InProgress)
|
||||||
.Cast<NominativeServiceCommand>()
|
.Cast<NominativeServiceCommand>()
|
||||||
.ToList()
|
.ToList()
|
||||||
|
|
@ -169,6 +171,8 @@ namespace Yavsc.ApiControllers
|
||||||
.Where(q => allowedActivityCodes.Contains(q.ActivityCode))
|
.Where(q => allowedActivityCodes.Contains(q.ActivityCode))
|
||||||
.Where(q => q.Status == QueryStatus.Inserted
|
.Where(q => q.Status == QueryStatus.Inserted
|
||||||
|| q.Status == QueryStatus.Accepted
|
|| q.Status == QueryStatus.Accepted
|
||||||
|
|| q.Status == QueryStatus.ProAccepted
|
||||||
|
|| q.Status == QueryStatus.ClientAccepted
|
||||||
|| q.Status == QueryStatus.InProgress)
|
|| q.Status == QueryStatus.InProgress)
|
||||||
.Cast<NominativeServiceCommand>()
|
.Cast<NominativeServiceCommand>()
|
||||||
.ToList()
|
.ToList()
|
||||||
|
|
@ -181,6 +185,8 @@ namespace Yavsc.ApiControllers
|
||||||
.Where(q => allowedActivityCodes.Contains(q.ActivityCode))
|
.Where(q => allowedActivityCodes.Contains(q.ActivityCode))
|
||||||
.Where(q => q.Status == QueryStatus.Inserted
|
.Where(q => q.Status == QueryStatus.Inserted
|
||||||
|| q.Status == QueryStatus.Accepted
|
|| q.Status == QueryStatus.Accepted
|
||||||
|
|| q.Status == QueryStatus.ProAccepted
|
||||||
|
|| q.Status == QueryStatus.ClientAccepted
|
||||||
|| q.Status == QueryStatus.InProgress)
|
|| q.Status == QueryStatus.InProgress)
|
||||||
.Cast<NominativeServiceCommand>()
|
.Cast<NominativeServiceCommand>()
|
||||||
.ToList()
|
.ToList()
|
||||||
|
|
|
||||||
|
|
@ -100,7 +100,16 @@ namespace Yavsc.ApiControllers
|
||||||
estimate.ClientValidationDate = DateTime.UtcNow;
|
estimate.ClientValidationDate = DateTime.UtcNow;
|
||||||
}
|
}
|
||||||
|
|
||||||
query.Status = QueryStatus.Accepted;
|
// The party-specific status records who accepted: the
|
||||||
|
// provider (ProAccepted) or the client (ClientAccepted).
|
||||||
|
// An admin accepting (neither party) falls back to the
|
||||||
|
// legacy generic Accepted.
|
||||||
|
query.Status = role switch
|
||||||
|
{
|
||||||
|
ActorRole.Provider => QueryStatus.ProAccepted,
|
||||||
|
ActorRole.Client => QueryStatus.ClientAccepted,
|
||||||
|
_ => QueryStatus.Accepted,
|
||||||
|
};
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -46,9 +46,9 @@ namespace Yavsc.Controllers
|
||||||
{
|
{
|
||||||
EstimateToProduceCount = _context.RdvQueries.Where(c => c.PerformerId == uid && c.EventDate > now && c.Status == QueryStatus.Inserted
|
EstimateToProduceCount = _context.RdvQueries.Where(c => c.PerformerId == uid && c.EventDate > now && c.Status == QueryStatus.Inserted
|
||||||
&& c.ValidationDate == null && !_context.Estimates.Any(e => e.CommandId == c.Id)).Count(),
|
&& c.ValidationDate == null && !_context.Estimates.Any(e => e.CommandId == c.Id)).Count(),
|
||||||
EstimateToHonorAsProCount = _context.RdvQueries.Where(c => c.PerformerId == uid && c.EventDate > now && c.Status == QueryStatus.Accepted
|
EstimateToHonorAsProCount = _context.RdvQueries.Where(c => c.PerformerId == uid && c.EventDate > now && (c.Status == QueryStatus.ProAccepted || c.Status == QueryStatus.Accepted)
|
||||||
&& c.ValidationDate == null && _context.Estimates.Any(e => e.CommandId == c.Id )).Count(),
|
&& c.ValidationDate == null && _context.Estimates.Any(e => e.CommandId == c.Id )).Count(),
|
||||||
EstimateToSignAsCliCount = _context.Estimates.Where(e => e.ClientId == uid && e.Query.Status == QueryStatus.Accepted).Count(),
|
EstimateToSignAsCliCount = _context.Estimates.Where(e => e.ClientId == uid && (e.Query.Status == QueryStatus.ProAccepted || e.Query.Status == QueryStatus.Accepted)).Count(),
|
||||||
|
|
||||||
BillToSignAsCliCount = 0,
|
BillToSignAsCliCount = 0,
|
||||||
NewPayementsCount = 0
|
NewPayementsCount = 0
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue