Changes
3 changed files (+97/-34)
-
-
@@ -44,11 +44,6 @@export interface WriteInput { getPaidLeaveProvisions(): Promise<YamoriDB["paidLeaveProvision"]["value"][]>; consumePaidLeave( provision: YamoriDB["paidLeaveProvision"]["value"], amountDays: number, ): Promise<void>; mask?: proto.MessageInitShape<typeof WorkRecordBatchWriteMaskSchema>; }
-
@@ -57,7 +52,6 @@ base: YamoriDB["workRecords"]["value"],message: proto.MessageShape<typeof WorkRecordBatchWriteInputSchema>, { getPaidLeaveProvisions, consumePaidLeave, mask: { fields = WorkRecordBatchWriteInputSchema.fields.map((field) => field.number), } = {},
-
@@ -126,16 +120,12 @@switch (timeOff.kind.case) { case "hourlyPaidLeave": // TODO: 時間単位年休に対応 await consumePaidLeave(provision, 1); return { type: "hourly_paid_leave", hours: timeOff.kind.value.hours, providedAtPacked: provision.providedAtPacked, }; case "halvedPaidLeave": await consumePaidLeave(provision, 0.5); return { type: "halved_paid_leave", providedAtPacked: provision.providedAtPacked,
-
@@ -178,8 +168,6 @@ }throw new NoPaidLeaveAvailableError(unpackDate(value.datePacked)); } await consumePaidLeave(provision, 1); value.record = { type: "paid_leave",
-
-
-
@@ -15,6 +15,7 @@ import { type IDBPObjectStore, type StoreNames } from "idb";import { packDate, unpackDate, jst, toProtoDate, TZ } from "../../../helpers"; import { type YamoriDB } from "../../../types"; import * as workRecord from "../../work_record/v1/work_record"; // TODO: 閏年の 2/29 の 2 年後がどうなるのか確認する function defaultExpiresAt(
-
@@ -183,6 +184,84 @@return value; } export interface SyncRemainingsInput { workspaceID: string; workerID: string; paidLeaveProvisions: IDBPObjectStore< YamoriDB, ArrayLike<StoreNames<YamoriDB>>, "paidLeaveProvision", "readwrite" >; workRecords: IDBPObjectStore< YamoriDB, ArrayLike<StoreNames<YamoriDB>>, "workRecords", "readonly" | "readwrite" >; } export async function syncRemainings({ paidLeaveProvisions, workspaceID, workerID, workRecords, }: SyncRemainingsInput): Promise<void> { const provisions = await paidLeaveProvisions .index("workspaceId,workerId") .getAll([workspaceID, workerID]); for (const provision of provisions) { const records = await workRecord.getAllForWorker( { workerID, workspaceID, filter: { since: unpackDate(provision.providedAtPacked), until: unpackDate(provision.expiresAtPacked), }, }, workRecords, ); let remainings = provision.amountDays; for (const record of records) { switch (record.record?.type) { case "paid_leave": if (record.record.providedAtPacked === provision.providedAtPacked) { remainings -= 1; } break; case "working_day": for (const timeOff of record.record.timeOffs) { // TODO: 時間単位年休の対応 switch (timeOff.type) { case "halved_paid_leave": if (timeOff.providedAtPacked === provision.providedAtPacked) { remainings -= 0.5; } break; } } break; } } if (remainings === provision.remainingDays) { continue; } await paidLeaveProvisions.put({ ...provision, remainingDays: remainings, updatedAt: Date.now(), }); } } export interface GetOneByProvidedAtInput { workspaceID: string;
-
@@ -240,14 +319,16 @@ const entries = await store.index("workspaceId,workerId") .getAll([workspaceID, workerID]); return entries.filter((entry) => { return ( entry.providedAtPacked >= providedAtSince && entry.providedAtPacked <= providedAtUntil && entry.expiresAtPacked >= expiresAtSince && entry.expiresAtPacked <= expiresAtUntil ); }); return entries .filter((entry) => { return ( entry.providedAtPacked >= providedAtSince && entry.providedAtPacked <= providedAtUntil && entry.expiresAtPacked >= expiresAtSince && entry.expiresAtPacked <= expiresAtUntil ); }) .sort((a, b) => a.expiresAtPacked - b.expiresAtPacked); } export interface BuildInput {
-
-
-
@@ -221,25 +221,19 @@ },paidLeaveProvisions, ); }, async consumePaidLeave(provision, amountDays) { if (provision.remainingDays < amountDays) { throw new workRecord.InsufficientPaidLeaveRemainingsError( provision.remainingDays, amountDays, ); } await paidLeaveProvisions.put({ ...provision, remainingDays: Math.max(0, provision.remainingDays - amountDays), }); }, mask: req.writeMask, }, ); store.put(payload); await store.put(payload); added.push(payload); await paidLeaveProvision.syncRemainings({ workerID: req.workerId!.value, workspaceID: req.workspaceId!.value, paidLeaveProvisions, workRecords: store, }); } const value = added.map((entry) =>
-