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
35c5a7f611
commit
725fd0c728
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)
|
||||
=> 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
|
||||
{
|
||||
QueryStatus.Accepted => "#E6F7EC",
|
||||
QueryStatus.ProAccepted => "#E6F7EC",
|
||||
QueryStatus.ClientAccepted => "#E1F5FE",
|
||||
QueryStatus.InProgress => "#FFF4D6",
|
||||
QueryStatus.Rejected => "#FDECEA",
|
||||
QueryStatus.Failed => "#ECEFF1",
|
||||
|
|
@ -177,6 +179,8 @@ public partial class BillingQueryDetailsPageViewModel : ViewModelBase, IActionSt
|
|||
=> status switch
|
||||
{
|
||||
QueryStatus.Accepted => "#2E7D32",
|
||||
QueryStatus.ProAccepted => "#2E7D32",
|
||||
QueryStatus.ClientAccepted => "#1565C0",
|
||||
QueryStatus.InProgress => "#B26A00",
|
||||
QueryStatus.Rejected => "#C62828",
|
||||
QueryStatus.Failed => "#607D8B",
|
||||
|
|
@ -188,6 +192,8 @@ public partial class BillingQueryDetailsPageViewModel : ViewModelBase, IActionSt
|
|||
=> status switch
|
||||
{
|
||||
QueryStatus.Accepted => "#1B5E20",
|
||||
QueryStatus.ProAccepted => "#1B5E20",
|
||||
QueryStatus.ClientAccepted => "#0D47A1",
|
||||
QueryStatus.InProgress => "#7A4A00",
|
||||
QueryStatus.Rejected => "#8E0000",
|
||||
QueryStatus.Failed => "#37474F",
|
||||
|
|
@ -199,6 +205,8 @@ public partial class BillingQueryDetailsPageViewModel : ViewModelBase, IActionSt
|
|||
=> status switch
|
||||
{
|
||||
QueryStatus.Accepted => "OK",
|
||||
QueryStatus.ProAccepted => "P",
|
||||
QueryStatus.ClientAccepted => "C",
|
||||
QueryStatus.InProgress => "~",
|
||||
QueryStatus.Rejected => "!",
|
||||
QueryStatus.Failed => "X",
|
||||
|
|
|
|||
|
|
@ -344,11 +344,13 @@ public partial class ProviderOngoingRequestsPageViewModel : ViewModelBase, IActi
|
|||
=> status switch
|
||||
{
|
||||
QueryStatus.InProgress => 0,
|
||||
QueryStatus.Accepted => 1,
|
||||
QueryStatus.Inserted => 2,
|
||||
QueryStatus.Success => 3,
|
||||
QueryStatus.Rejected => 4,
|
||||
QueryStatus.Failed => 5,
|
||||
QueryStatus.ClientAccepted => 1,
|
||||
QueryStatus.ProAccepted => 2,
|
||||
QueryStatus.Accepted => 2,
|
||||
QueryStatus.Inserted => 3,
|
||||
QueryStatus.Success => 4,
|
||||
QueryStatus.Rejected => 5,
|
||||
QueryStatus.Failed => 6,
|
||||
_ => 99,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -5,15 +5,28 @@ namespace Yavsc
|
|||
/// should be associated to any
|
||||
/// client user query to a provider user or
|
||||
/// 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>
|
||||
public enum QueryStatus: int
|
||||
{
|
||||
Inserted,
|
||||
Rejected,
|
||||
Accepted,
|
||||
InProgress,
|
||||
Inserted = 0,
|
||||
Rejected = 1,
|
||||
Accepted = 2,
|
||||
InProgress = 3,
|
||||
// final states
|
||||
Failed,
|
||||
Success
|
||||
Failed = 4,
|
||||
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 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]
|
||||
|
|
@ -146,7 +147,7 @@ public sealed class FrontOfficeApiControllerTests : IClassFixture<ApiWebServerFi
|
|||
using var assertScope = _fixture.Services.CreateScope();
|
||||
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);
|
||||
Assert.True(estimate.ProviderValidationDate != default);
|
||||
|
|
@ -173,7 +174,7 @@ public sealed class FrontOfficeApiControllerTests : IClassFixture<ApiWebServerFi
|
|||
using var assertScope = _fixture.Services.CreateScope();
|
||||
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);
|
||||
Assert.True(estimate.ClientValidationDate != default);
|
||||
|
|
|
|||
|
|
@ -157,6 +157,8 @@ namespace Yavsc.ApiControllers
|
|||
.Where(q => allowedActivityCodes.Contains(q.ActivityCode))
|
||||
.Where(q => q.Status == QueryStatus.Inserted
|
||||
|| q.Status == QueryStatus.Accepted
|
||||
|| q.Status == QueryStatus.ProAccepted
|
||||
|| q.Status == QueryStatus.ClientAccepted
|
||||
|| q.Status == QueryStatus.InProgress)
|
||||
.Cast<NominativeServiceCommand>()
|
||||
.ToList()
|
||||
|
|
@ -169,6 +171,8 @@ namespace Yavsc.ApiControllers
|
|||
.Where(q => allowedActivityCodes.Contains(q.ActivityCode))
|
||||
.Where(q => q.Status == QueryStatus.Inserted
|
||||
|| q.Status == QueryStatus.Accepted
|
||||
|| q.Status == QueryStatus.ProAccepted
|
||||
|| q.Status == QueryStatus.ClientAccepted
|
||||
|| q.Status == QueryStatus.InProgress)
|
||||
.Cast<NominativeServiceCommand>()
|
||||
.ToList()
|
||||
|
|
@ -181,6 +185,8 @@ namespace Yavsc.ApiControllers
|
|||
.Where(q => allowedActivityCodes.Contains(q.ActivityCode))
|
||||
.Where(q => q.Status == QueryStatus.Inserted
|
||||
|| q.Status == QueryStatus.Accepted
|
||||
|| q.Status == QueryStatus.ProAccepted
|
||||
|| q.Status == QueryStatus.ClientAccepted
|
||||
|| q.Status == QueryStatus.InProgress)
|
||||
.Cast<NominativeServiceCommand>()
|
||||
.ToList()
|
||||
|
|
|
|||
|
|
@ -100,7 +100,16 @@ namespace Yavsc.ApiControllers
|
|||
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
|
||||
{
|
||||
|
|
|
|||
|
|
@ -46,9 +46,9 @@ namespace Yavsc.Controllers
|
|||
{
|
||||
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(),
|
||||
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(),
|
||||
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,
|
||||
NewPayementsCount = 0
|
||||
|
|
|
|||
Loading…
Reference in a new issue