fix(money): открытие смены на неактивной/непривязанной точке продаж → отказ

OpenShiftAsync проверяет RetailPoint.IsActive (retail-point-inactive) и привязку
кассира к точке (retail-point-not-assigned; у кого привязок нет — на любой точке).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
nns 2026-10-08 02:10:11 +05:00
parent aedcd3f83a
commit 8785fd60d1

View file

@ -181,6 +181,33 @@ public async Task<MoneyServiceResult> UnpostAsync(Guid transactionId, Guid curre
return new(MoneyServiceStatus.ShiftAlreadyOpen, null, null, return new(MoneyServiceStatus.ShiftAlreadyOpen, null, null,
"shift-already-open", "На этой точке уже открыта смена."); "shift-already-open", "На этой точке уже открыта смена.");
// Точка продаж должна существовать и быть активной — на деактивированной
// точке открывать смену (и, значит, продавать) нельзя.
var rp = await _db.RetailPoints.FirstOrDefaultAsync(r => r.Id == retailPointId, ct);
if (rp is null)
return new(MoneyServiceStatus.ValidationFailed, null, null,
"retail-point-not-found", "Точка продаж не найдена.");
if (!rp.IsActive)
return new(MoneyServiceStatus.ValidationFailed, null, null,
"retail-point-inactive", "Точка продаж деактивирована — открыть смену нельзя.");
// Привязка кассира к точкам: если у сотрудника настроены привязки к точкам
// продаж, открывать смену он может ТОЛЬКО на закреплённой точке. У кого
// привязок нет (администратор/управляющий) — на любой.
var emp = await _db.Employees.FirstOrDefaultAsync(e => e.UserId == cashierUserId, ct);
if (emp is not null)
{
var hasAnyAssignment = await _db.EmployeeRetailPointAssignments.AnyAsync(a => a.EmployeeId == emp.Id, ct);
if (hasAnyAssignment)
{
var assigned = await _db.EmployeeRetailPointAssignments
.AnyAsync(a => a.EmployeeId == emp.Id && a.RetailPointId == retailPointId, ct);
if (!assigned)
return new(MoneyServiceStatus.ValidationFailed, null, null,
"retail-point-not-assigned", "Вы не закреплены за этой точкой продаж — открыть смену нельзя.");
}
}
var cash = await _db.MoneyAccounts.FirstOrDefaultAsync(a => a.Id == cashAccountId, ct); var cash = await _db.MoneyAccounts.FirstOrDefaultAsync(a => a.Id == cashAccountId, ct);
if (cash is null || cash.Kind != MoneyAccountKind.Cash) if (cash is null || cash.Kind != MoneyAccountKind.Cash)
return new(MoneyServiceStatus.ValidationFailed, null, null, return new(MoneyServiceStatus.ValidationFailed, null, null,