From c44a102896bf9d8eb123c6392e425d17e7757bfe Mon Sep 17 00:00:00 2001 From: toririm <59079411+toririm@users.noreply.github.com> Date: Mon, 28 Oct 2024 05:29:40 +0900 Subject: [PATCH] =?UTF-8?q?[=E3=82=B9=E3=82=AD=E3=83=BC=E3=83=9E=E5=A4=89?= =?UTF-8?q?=E6=9B=B4]=20=E3=82=B3=E3=83=A1=E3=83=B3=E3=83=88=E3=81=AB?= =?UTF-8?q?=E3=82=BF=E3=82=A4=E3=83=A0=E3=82=B9=E3=82=BF=E3=83=B3=E3=83=97?= =?UTF-8?q?=E3=82=92=E8=BF=BD=E5=8A=A0=20(#346)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit closes #338 --- common/models/order.test.ts | 11 +++---- common/models/order.ts | 62 +++++++++++++++++++++++++++---------- 2 files changed, 49 insertions(+), 24 deletions(-) diff --git a/common/models/order.test.ts b/common/models/order.test.ts index a7cf6297..d7e79af8 100644 --- a/common/models/order.test.ts +++ b/common/models/order.test.ts @@ -235,13 +235,10 @@ describe("[unit] order entity", () => { expect(order.comments).toEqual([]); order.addComment("cashier", "testAddComments"); - expect(order.comments).toEqual([ - { author: "cashier", text: "testAddComments" }, - ]); + expect(order.comments[0].author).toBe("cashier"); + expect(order.comments[0].text).toBe("testAddComments"); order.addComment("master", "2"); - expect(order.comments).toEqual([ - { author: "cashier", text: "testAddComments" }, - { author: "master", text: "2" }, - ]); + expect(order.comments[1].author).toBe("master"); + expect(order.comments[1].text).toBe("2"); }); }); diff --git a/common/models/order.ts b/common/models/order.ts index cefa1a25..f2a53519 100644 --- a/common/models/order.ts +++ b/common/models/order.ts @@ -6,6 +6,12 @@ const AUTHORS = ["cashier", "master", "serve", "others"] as const; export type Author = (typeof AUTHORS)[number]; +const commentSchema = z.object({ + author: z.enum(AUTHORS), + text: z.string(), + createdAt: z.date(), +}); + export const orderSchema = z.object({ id: z.string().optional(), // Firestore のドキュメント ID orderId: z.number(), @@ -14,12 +20,7 @@ export const orderSchema = z.object({ servedAt: z.date().nullable(), items: z.array(itemSchema.required()), total: z.number(), // sum of item.price - comments: z.array( - z.object({ - author: z.enum(AUTHORS), - text: z.string(), - }), - ), + comments: z.array(commentSchema), billingAmount: z.number(), // total - discount received: z.number(), // お預かり金額 discountOrderId: z.number().nullable(), @@ -30,9 +31,38 @@ export const orderSchema = z.object({ export type Order = z.infer; +type Comment = z.infer; + // 途中から割引額を変更する場合はこの値を変更する const STATIC_DISCOUNT_PER_CUP = 100; +class CommentEntity implements Comment { + constructor( + public readonly author: Author, + public readonly text: string, + public readonly createdAt: Date, + ) {} + + static fromComment(comment: Comment): CommentEntity { + return new CommentEntity(comment.author, comment.text, comment.createdAt); + } + + static createNew({ + author, + text, + }: Omit): CommentEntity { + return new CommentEntity(author, text, new Date()); + } + + toComment(): Comment { + return { + author: this.author, + text: this.text, + createdAt: this.createdAt, + }; + } +} + export class OrderEntity implements Order { order: ItemEntity | undefined; // 全てのプロパティを private にして外部からの直接アクセスを禁止 @@ -44,7 +74,7 @@ export class OrderEntity implements Order { private _servedAt: Date | null, private _items: WithId[], private _total: number, - private _comments: Order["comments"], + private _comments: CommentEntity[], private _billingAmount: number, private _received: number, private _discountOrderId: number | null, @@ -85,7 +115,7 @@ export class OrderEntity implements Order { order.servedAt, order.items.map((item) => ItemEntity.fromItem(item)), order.total, - order.comments, + order.comments.map((comment) => CommentEntity.fromComment(comment)), order.billingAmount, order.received, order.discountOrderId, @@ -140,13 +170,6 @@ export class OrderEntity implements Order { get comments() { return this._comments; } - // set comments(a) { - // if (description === "") { - // this._description = null; - // } else { - // this._description = description; - // } - // } get billingAmount() { this._billingAmount = this.total - this.discount; @@ -209,11 +232,16 @@ export class OrderEntity implements Order { this._readyAt = null; } + /** + * コメントを追加する + * @param author コメントの投稿者 + * @param text コメントの内容 + */ addComment(author: Author, text: string) { if (text === "") { return; } - this._comments.push({ author, text }); + this._comments.push(CommentEntity.createNew({ author, text })); } /** @@ -285,7 +313,7 @@ export class OrderEntity implements Order { servedAt: this.servedAt, items: this.items.map((item) => item.toItem()), total: this.total, - comments: this.comments, + comments: this.comments.map((comment) => comment.toComment()), billingAmount: this.billingAmount, received: this.received, discountOrderId: this.discountOrderId,