feat(invoicing): connect signed estimates and verified payment receipts

Freeze invoice totals and parties, record offline receipts and verify completed PayPal transactions. Protect idempotence and concurrent balance updates; add migration, API client, documentation and tests.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
Paul Schneider 2026-10-19 20:29:08 +01:00
commit 2dcbcd35b3
Signed by: notazof
GPG key ID: AD4B9B545FBD7D12
37 changed files with 6686 additions and 12 deletions

View file

@ -154,6 +154,9 @@ public class HairCutQueryApiController : Controller
return BadRequest(ModelState);
}
if (existing.InvoiceEstimateId.HasValue && existing.PerformerId != query.PerformerId)
return Conflict(new { Error = "An invoiced command cannot change performer." });
existing.ActivityCode = query.ActivityCode;
existing.PerformerId = query.PerformerId;
existing.Consent = query.Consent;
@ -187,6 +190,8 @@ public class HairCutQueryApiController : Controller
return Forbid();
}
if (query.InvoiceEstimateId.HasValue)
return Conflict(new { Error = "An invoiced command cannot be deleted." });
_context.HairCutQueries.Remove(query);
await _context.SaveChangesAsync(User.GetUserId(), cancellationToken);