feat: manage owner usage history records
This commit is contained in:
@@ -166,6 +166,7 @@ export class ImportSnapshotRepository {
|
||||
));
|
||||
this.ownerById = new Map(this.owners.map(owner => [owner.id, owner]));
|
||||
this.periodBalances = new Map();
|
||||
this.periodInitialBalances = new Map();
|
||||
this.periodYears = new Set();
|
||||
this.idempotentResponses = new Map();
|
||||
|
||||
@@ -183,6 +184,7 @@ export class ImportSnapshotRepository {
|
||||
const rows2025 = usageByRoomAndYear.get(`${room}|2025`) ?? [];
|
||||
const carryForward = rows2025.length > 0 ? Number(rows2025.at(-1).balance) : 0;
|
||||
this.periodYears.add(periodKey(owner.id, 2026));
|
||||
this.periodInitialBalances.set(periodKey(owner.id, 2026), 15 + carryForward);
|
||||
const used2026 = (usageByRoomAndYear.get(`${room}|2026`) ?? [])
|
||||
.reduce((sum, record) => sum + Number(record.use), 0);
|
||||
this.periodBalances.set(periodKey(owner.id, 2026), 15 + carryForward - used2026);
|
||||
@@ -195,6 +197,7 @@ export class ImportSnapshotRepository {
|
||||
for (const year of otherYears) {
|
||||
const rows = usageByRoomAndYear.get(`${room}|${year}`) ?? [];
|
||||
this.periodYears.add(periodKey(owner.id, year));
|
||||
this.periodInitialBalances.set(periodKey(owner.id, year), 15);
|
||||
this.periodBalances.set(
|
||||
periodKey(owner.id, year),
|
||||
15 - rows.reduce((sum, record) => sum + Number(record.use), 0)
|
||||
@@ -252,7 +255,7 @@ export class ImportSnapshotRepository {
|
||||
status: "ok",
|
||||
database: "booking_test",
|
||||
schema: "condon",
|
||||
migrationVersion: "002_legacy_import_and_bookings:snapshot"
|
||||
migrationVersion: "003_delete_usage_record:snapshot"
|
||||
};
|
||||
}
|
||||
|
||||
@@ -303,6 +306,38 @@ export class ImportSnapshotRepository {
|
||||
return paginate(filtered.map(entry => ({ ...entry.publicRecord })), query);
|
||||
}
|
||||
|
||||
rebuildPeriodBalance(ownerAccountId, periodYear) {
|
||||
const key = periodKey(ownerAccountId, periodYear);
|
||||
const entries = this.usageEntries
|
||||
.filter(entry => entry.publicRecord.ownerAccountId === ownerAccountId && entry.periodYear === periodYear)
|
||||
.sort((left, right) => {
|
||||
const leftImported = left.sourceSheet !== null;
|
||||
const rightImported = right.sourceSheet !== null;
|
||||
if (leftImported !== rightImported) return leftImported ? -1 : 1;
|
||||
if (leftImported) return sourceOrder(left, right);
|
||||
return String(left.publicRecord.createdAt).localeCompare(String(right.publicRecord.createdAt))
|
||||
|| left.publicRecord.id.localeCompare(right.publicRecord.id);
|
||||
});
|
||||
let balance = this.periodInitialBalances.get(key) ?? 15;
|
||||
for (const entry of entries) {
|
||||
balance -= entry.publicRecord.use;
|
||||
entry.publicRecord.balance = balance;
|
||||
}
|
||||
this.periodBalances.set(key, balance);
|
||||
}
|
||||
|
||||
async deleteUsageRecord(id) {
|
||||
const index = this.usageEntries.findIndex(entry => entry.publicRecord.id === id);
|
||||
if (index < 0) {
|
||||
throw new ApiError(404, "NOT_FOUND", "The requested business record was not found");
|
||||
}
|
||||
const [removed] = this.usageEntries.splice(index, 1);
|
||||
for (const [key, value] of this.idempotentResponses) {
|
||||
if (value.response.id === id) this.idempotentResponses.delete(key);
|
||||
}
|
||||
this.rebuildPeriodBalance(removed.publicRecord.ownerAccountId, removed.periodYear);
|
||||
}
|
||||
|
||||
async createUsageRecord(input) {
|
||||
const previous = this.idempotentResponses.get(input.idempotencyKey);
|
||||
if (previous) {
|
||||
|
||||
Reference in New Issue
Block a user