@shisyamo4131/air-guard-v2-schemas 2.4.2-dev.8 → 2.4.2-dev.81

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (48) hide show
  1. package/index.js +12 -0
  2. package/package.json +45 -47
  3. package/src/Agreement.js +17 -24
  4. package/src/AgreementV2.js +185 -0
  5. package/src/ArrangementNotification.js +16 -8
  6. package/src/Billing.js +5 -34
  7. package/src/Company.js +162 -25
  8. package/src/Customer.js +39 -59
  9. package/src/Employee.js +590 -300
  10. package/src/FcmToken.js +73 -0
  11. package/src/Insurance.js +409 -0
  12. package/src/Notification.js +95 -0
  13. package/src/NotificationRecipient.js +68 -0
  14. package/src/Operation.js +272 -280
  15. package/src/OperationBilling.js +126 -192
  16. package/src/OperationDetail.js +115 -85
  17. package/src/OperationResult.js +257 -254
  18. package/src/OperationResultDetail.js +65 -56
  19. package/src/Site.js +160 -137
  20. package/src/SiteOperationSchedule.js +187 -247
  21. package/src/SiteOperationScheduleDetail.js +75 -65
  22. package/src/SiteOrder.js +18 -29
  23. package/src/User.js +44 -47
  24. package/src/WorkTimeBase.js +205 -0
  25. package/src/WorkingResult.js +83 -255
  26. package/src/constants/day-type.js +20 -12
  27. package/src/constants/employment-status.js +2 -2
  28. package/src/constants/index.js +4 -0
  29. package/src/constants/insurance-status.js +15 -0
  30. package/src/constants/shift-type.js +5 -2
  31. package/src/errorDefinitions.js +173 -0
  32. package/src/parts/fieldDefinitions/array.js +50 -0
  33. package/src/parts/fieldDefinitions/check.js +53 -0
  34. package/src/parts/fieldDefinitions/code.js +8 -0
  35. package/src/parts/fieldDefinitions/constants.js +9 -0
  36. package/src/parts/fieldDefinitions/dateAt.js +63 -0
  37. package/src/parts/fieldDefinitions/dateTimeAt.js +8 -0
  38. package/src/parts/fieldDefinitions/defaultDefinition.js +118 -0
  39. package/src/parts/fieldDefinitions/multipleLine.js +16 -0
  40. package/src/parts/fieldDefinitions/number.js +69 -0
  41. package/src/parts/fieldDefinitions/object.js +38 -0
  42. package/src/parts/fieldDefinitions/oneLine.js +409 -0
  43. package/src/parts/fieldDefinitions/radio.js +8 -0
  44. package/src/parts/fieldDefinitions/select.js +267 -0
  45. package/src/parts/fieldDefinitions/time.js +8 -0
  46. package/src/parts/fieldDefinitions.js +46 -669
  47. package/src/utils/CutoffDate.js +11 -15
  48. package/src/utils/index.js +44 -8
@@ -1,61 +1,70 @@
1
1
  /*****************************************************************************
2
- * OperationResultDetail Model ver 1.0.0
2
+ * @file ./src/OperationResultDetail.js
3
3
  * @author shisyamo4131
4
- * ---------------------------------------------------------------------------
5
- * - Model representing the details of an operation result.
6
- * - Extends OperationDetail.
7
- * ---------------------------------------------------------------------------
8
- * @inherited - The following properties are inherited from OperationDetail:
9
- * @props {string} id - Employee or Outsourcer document ID
10
- * @props {number} index - Identifier index for Outsourcer (always 0 for Employee)
11
- * @props {boolean} isEmployee - Employee flag (true: Employee, false: Outsourcer)
12
- * @props {number} amount - Number of placements (always fixed at 1)
13
- * @props {string} siteId - Site ID
14
- * @props {boolean} isQualified - Qualified flag
15
- * @props {boolean} isOjt - OJT flag
16
- * @props {Date} dateAt - Placement date
17
- * @props {string} dayType - Day type (e.g., `WEEKDAY`, `WEEKEND`, `HOLIDAY`)
18
- * @props {string} shiftType - `DAY` or `NIGHT`
19
- * @props {string} startTime - Start time (HH:MM format)
20
- * @props {boolean} isStartNextDay - Next day start flag
21
- * @props {string} endTime - End time (HH:MM format)
22
- * @props {number} breakMinutes - Break time (minutes)
23
- * @props {number} regulationWorkMinutes - Regulation work minutes
24
- * --------------------------------------------------------------------------
25
- * @inherited - The following computed properties are inherited from OperationDetail:
26
- * @computed {string} workerId - Worker ID
27
- * - For Employee, it's the same as `id`, for Outsourcer, it's a concatenation of `id` and `index` with ':'
28
- * @computed {string|null} employeeId - Employee ID (null if not applicable)
29
- * @computed {string|null} outsourcerId - Outsourcer ID (null if not applicable)
30
- * @computed {number} overtimeWorkMinutes - Overtime work in minutes
31
- * - Calculated as `totalWorkMinutes` minus `regulationWorkMinutes`
32
- * - Overtime work is not negative; the minimum is 0.
33
- * @computed {string} key - Unique key combining `date`, `dayType`, and `shiftType`
34
- * @computed {string} date - Date string in YYYY-MM-DD format based on `dateAt`
35
- * @computed {boolean} isSpansNextDay - Flag indicating whether the date spans from start date to end date
36
- * @computed {Date} startAt - Start date and time (Date object)
37
- * @computed {Date} endAt - End date and time (Date object)
38
- * @computed {number} totalWorkMinutes - Total working time in minutes (excluding break time)
39
- * @computed {number} regularTimeWorkMinutes - Regular working time in minutes
40
- * --------------------------------------------------------------------------
41
- * @inherited - The following accessor properties are inherited from OperationDetail:
42
- * @accessor {number} startHour - Start hour (0-23)
43
- * - Extracted from `startTime`.
44
- * @accessor {number} startMinute - Start minute (0-59)
45
- * - Extracted from `startTime`.
46
- * @accessor {number} endHour - End hour (0-23)
47
- * - Extracted from `endTime`.
48
- * @accessor {number} endMinute - End minute (0-59)
49
- * - Extracted from `endTime`.
50
- * @accessor {number} breakHours - Break time in hours (converts to/from breakMinutes)
51
- * - Accessor for break time in hours.
52
- * @accessor {number} overtimeWorkHours - Overtime work in hours (converts to/from overtimeWorkMinutes)
53
- * ---------------------------------------------------------------------------
54
- * @inherited - The following method is inherited from WorkingResult:
55
- * @method {function} setDateAtCallback - Callback method called when `dateAt` is set
56
- * - Override this method in subclasses to add custom behavior when `dateAt` changes.
57
- * - By default, updates `dayType` based on the new `dateAt` value.
58
- * - @param {Date} v - The new `dateAt` value
4
+ * @description 稼働実績明細クラス
5
+ *
6
+ * @class
7
+ * @extends OperationDetail
8
+ *
9
+ * @property {Date} dateAt - 日付 (変更されると `dayType` が自動的に更新されます)
10
+ * @property {string} shiftType - 勤務区分
11
+ * @property {string} startTime - 開始時刻 (HH:MM 形式)
12
+ * @property {string} endTime - 終了時刻 (HH:MM 形式)
13
+ * @property {boolean} isStartNextDay - 翌日開始フラグ
14
+ * - `true` の場合、実際の勤務は `dateAt` の翌日であることを意味します。
15
+ * @property {number} breakMinutes - 休憩時間 (分)
16
+ * @property {string} date - `dateAt` に基づく YYYY-MM-DD 形式の日付文字列 (読み取り専用)
17
+ * - `dateAt` に基づいて YYYY-MM-DD 形式の文字列を返します。
18
+ * @property {Date} startAt - 開始日時 (Date オブジェクト) (読み取り専用)
19
+ * - `dateAt` に基づいて `startTime` を設定した Date オブジェクトを返します。
20
+ * - `isStartNextDay` true の場合、1日加算します。
21
+ * @property {Date} endAt - 終了日時 (Date オブジェクト) (読み取り専用)
22
+ * - `startAt` を起点に、最初に現れる `endTime` Date オブジェクトを返します。
23
+ * @property {boolean} isSpansNextDay - 翌日跨ぎフラグ (読み取り専用)
24
+ * - `true` の場合、`startAt` と `endAt` の日付が異なることを意味します。
25
+ * @property {number} regulationWorkMinutes - 規定労働時間 (分)
26
+ * - `startAt` から `endAt` までの時間から `breakMinutes` を差し引いた時間のうち、
27
+ * 規定内として扱う労働時間(分)です。
28
+ * - 実際の労働時間から残業時間を算出するための基準となる値です。
29
+ * - この値があることで、取極めに柔軟な設定を行うことが可能になる他、労働基準法の 1 日の所定労働時間上限が変更された際に
30
+ * 影響を最小限に抑えることができます。
31
+ * 例) 8:00 から 17:00 までの勤務で休憩が 60 分の場合
32
+ * - 規定労働時間を 8 時間 (480 分) とし、実際の勤務が 8 時間 (480 分) を超えた分が残業時間として扱われます。
33
+ * 例) 8:00 から 16:00 までの勤務で休憩が 60 分の場合
34
+ * - 規定労働時間を 7 時間 (420 分) とすると、実際の勤務が 7 時間 (420 分) を超えた分が残業時間として扱われます。
35
+ * - 規定労働時間を 8 時間 (480 分) とすると、実際の勤務が 8 時間 (480 分) を超えた分が残業時間として扱われます。
36
+ * 例) 7:00 から 翌日 7:00 までの勤務で休憩が 60 分の場合
37
+ * - 規定労働時間を 8 時間 (480 分) とすると、実際の勤務が 8 時間 (480 ) を超えた分が残業時間として扱われます。
38
+ * この場合、最初の 8 時間までは基本単価が適用され、残りの 8 時間は残業単価が適用されるといった設定が可能になります。
39
+ * - 規定労働時間を 24 時間 (1440 分) とすると、実際の勤務が 24 時間 (1440 分) を超えた分が残業時間として扱われます。
40
+ * この場合、全ての勤務時間が基本単価で扱われるといった設定が可能になります。
41
+ * @property {string} dayType - 曜日区分
42
+ * @property {number} totalWorkMinutes - 総労働時間 (休憩時間を除く) () (読み取り専用)
43
+ * @property {number} regularTimeWorkMinutes - 所定労働時間 (分) (読み取り専用)
44
+ * @property {number} overtimeWorkMinutes - 残業時間 (分) (読み取り専用)
45
+ * @property {string} id - 従業員ID または 外注先ID
46
+ * @property {number} index - 外注先の識別用インデックス (従業員の場合は常に0)
47
+ * @property {boolean} isEmployee - 従業員フラグ (true: 従業員, false: 外注先)
48
+ * @property {number} amount - 配置人数 (常に1で固定)
49
+ * @property {string} siteId - 現場ID
50
+ * @property {boolean} isQualified - 資格者フラグ
51
+ * @property {boolean} isOjt - OJTフラグ
52
+ * @property {string} workerId - 作業者ID (読み取り専用)
53
+ * - 従業員の場合は `id` と同じ、外注先の場合は `id` と `index` を `:` で結合した文字列を返します。
54
+ * @property {string|null} employeeId - 従業員ID (該当しない場合は null) (読み取り専用)
55
+ * @property {string|null} outsourcerId - 外注先ID (該当しない場合は null) (読み取り専用)
56
+ *
57
+ * @method setDateAtCallback - `dateAt` が設定されたときに呼び出されるコールバック関数
58
+ * @method getInvalidReasons - クラス特有のエラーの有無を返すメソッド
59
+ *
60
+ * @getter {boolean} isInvalid - クラス特有のエラーが存在するかどうかを返すプロパティ
61
+ * @getter {Array<string>} invalidReasons - クラス特有のエラーコードの配列を返すプロパティ
62
+ *
63
+ * @static SHIFT_TYPE - 勤務区分を定義する定数オブジェクト
64
+ * @static INVALID_REASON - クラス特有のエラーコードを定義する定数オブジェクト
65
+ * - `BREAK_MINUTES_NEGATIVE`: `breakMinutes` が負の値である場合のエラーコード
66
+ * - `REGULATION_WORK_MINUTES_NEGATIVE`: `regulationWorkMinutes` が負の値である場合のエラーコード
67
+ * @static DAY_TYPE - 曜日区分を定義する定数オブジェクト
59
68
  *****************************************************************************/
60
69
  import OperationDetail from "./OperationDetail.js";
61
70
 
package/src/Site.js CHANGED
@@ -1,7 +1,5 @@
1
- /**
2
- * @file src/Site.js
3
- * @author shisyamo4131
4
- *
1
+ /*****************************************************************************
2
+ * @file ./src/Site.js
5
3
  * NOTE: `customerId`, `customer` プロパティについて
6
4
  * - 仮登録
7
5
  * - 取引先未定での現場登録のシチュエーションを考慮して現場情報は仮登録を可能とする。
@@ -12,32 +10,20 @@
12
10
  * - 自身の従属先データを持たせる場合に `XxxxxMinimal` クラスを使用するが、アプリ側でオブジェクト選択を行う場合に
13
11
  * `Xxxxx` クラスにするのか `XxxxxMinimal` クラスにするのかを判断できないため、docId を持たせて
14
12
  * `beforeCreate` フックでオブジェクトを取得するようにする。
15
- */
13
+ *****************************************************************************/
16
14
  import { default as FireModel } from "@shisyamo4131/air-firebase-v2";
17
15
  import { defField } from "./parts/fieldDefinitions.js";
18
16
  import { defAccessor } from "./parts/accessorDefinitions.js";
19
17
  import Customer from "./Customer.js";
20
- import Agreement from "./Agreement.js";
18
+ import AgreementV2 from "./AgreementV2.js";
21
19
  import { VALUES } from "./constants/site-status.js";
22
20
  import { GeocodableMixin } from "./mixins/GeocodableMixin.js";
23
21
 
24
22
  const classProps = {
25
- // customerId: defField("customerId", {
26
- // required: true,
27
- // component: {
28
- // attrs: {
29
- // disabled: ({ editMode }) => {
30
- // return editMode !== "CREATE";
31
- // },
32
- // },
33
- // },
34
- // }),
35
23
  customerId: defField("customerId", {
36
24
  component: {
37
25
  attrs: {
38
- /**
39
- * `_beforeData.customerId` が存在する場合(本登録後の編集時を表す)には `customerId` を必須とする。
40
- */
26
+ /** `_beforeData.customerId` が存在する場合(本登録後の編集時を表す)には `customerId` を必須とする。 */
41
27
  required: ({ item }) => {
42
28
  return !!item._beforeData.customerId;
43
29
  },
@@ -45,17 +31,12 @@ const classProps = {
45
31
  },
46
32
  }),
47
33
  customer: defField("customer", { hidden: true, customClass: Customer }),
48
- customerName: defField("name", {
49
- label: "取引先名",
50
- required: ({ item }) => {
51
- return !item.customerId; // isTemporary プロパティでの判定でも良いか?
52
- },
53
- component: {
54
- attrs: {
55
- minLength: 2,
56
- },
57
- },
58
- }),
34
+
35
+ /**
36
+ * 取引先名
37
+ * - `customerId` が未設定の場合に必須(仮登録状態で取引先の名前だけ登録したい場合を想定)
38
+ */
39
+ customerName: defField("customerName"),
59
40
  code: defField("code", { label: "現場コード" }),
60
41
  name: defField("name", {
61
42
  label: "現場名",
@@ -74,38 +55,37 @@ const classProps = {
74
55
  building: defField("building"),
75
56
  location: defField("location"),
76
57
  remarks: defField("multipleLine", { label: "備考" }),
77
- agreements: defField("array", { label: "取極め", customClass: Agreement }),
58
+ // agreements: defField("array", { label: "取極め", customClass: Agreement }),
59
+ agreementsV2: defField("array", {
60
+ label: "取極め",
61
+ customClass: AgreementV2,
62
+ }),
78
63
  status: defField("siteStatus", { required: true }),
79
64
  };
80
65
 
81
66
  /*****************************************************************************
67
+ * @class Site
68
+ * @author shisyamo4131
69
+ *
82
70
  * @property {string} customerId - 取引先ドキュメントID
83
71
  *
84
72
  * @property {object} customer - 取引先オブジェクト
85
- * - `beforeCreate`, `beforeUpdate` `customerId` に該当する `Customer` オブジェクトと自動的に同期されます。
86
- * - `Customer` が更新された場合は Cloud Functions で同期される必要があります。
87
- *
88
- * @property {string} code - Site code.
89
- * @property {string} name - Site name.
90
- * @property {string} nameKana - Site name in Kana.
73
+ * @property {string} customerName - 取引先名
74
+ * @property {string} code - 現場コード
75
+ * @property {string} name - 現場名
76
+ * @property {string} nameKana - 現場名カナ
91
77
  * @property {string} zipcode - Postal code.
92
78
  * @property {string} prefCode - Prefecture code.
93
- *
94
79
  * @property {string} prefecture - Prefecture name derived from `prefCode` (read-only)
95
- *
96
80
  * @property {string} city - City name.
97
81
  * @property {string} address - Address details.
98
82
  * @property {string} building - Building name.
99
- *
100
83
  * @property {string} fullAddress - Full address combining prefecture, city, and address (read-only)
101
- *
102
84
  * @property {object} location - Geographical location.
103
85
  * @property {string} remarks - Additional remarks.
104
- * @property {array} agreements - List of agreements (Agreement).
105
- * - Enhanced with custom methods: `add()`, `change()`, `remove()`
86
+ * @property {array} agreementsV2 - 取極めの配列(バージョン2)。`AgreementV2` クラスのインスタンスを要素とする。
106
87
  *
107
88
  * @property {string} status - Site status.
108
- *
109
89
  * @property {boolean} isTemporary - 仮登録状態かどうかを表すフラグ
110
90
  *
111
91
  * @function getAgreement
@@ -115,24 +95,6 @@ const classProps = {
115
95
  * @param {string} args.dayType - Day type (e.g., "WEEKDAY", "SATURDAY").
116
96
  * @param {string} args.shiftType - Shift type (e.g., "DAY", "NIGHT").
117
97
  * @returns {Agreement|null} - Matching agreement or null if not found.
118
- *
119
- * @memberof agreements
120
- * @function add
121
- * Adds Agreement instance to agreements array.
122
- * @param {Agreement} agreement - Agreement instance to add.
123
- * @throws {Error} If argument is not an Agreement instance.
124
- *
125
- * @memberof agreements
126
- * @function change
127
- * Replaces existing agreement by key matching.
128
- * @param {Agreement} newAgreement - New Agreement instance to replace existing one.
129
- * @throws {Error} If argument is not an Agreement instance or if agreement not found.
130
- *
131
- * @memberof agreements
132
- * @function remove
133
- * Removes agreement from array by key matching.
134
- * @param {Agreement} agreement - Agreement instance to remove.
135
- * @throws {Error} If agreement not found.
136
98
  *****************************************************************************/
137
99
  export default class Site extends GeocodableMixin(FireModel) {
138
100
  static className = "現場";
@@ -181,6 +143,8 @@ export default class Site extends GeocodableMixin(FireModel) {
181
143
  /**
182
144
  * ドキュメント作成直前の処理です。
183
145
  * - `customerId` に該当する `Customer` インスタンスを取得して `customer` プロパティにセットします。
146
+ * - 取引先が未設定のまま現場を仮登録することを許容しますが、その場合は `customerName` プロパティに取引先名を入力する必要があります。
147
+ * - `customerId` と `customerName` の両方が未設定の場合はエラーをスローします。
184
148
  * @param {Object} args - Creation options.
185
149
  * @param {string} [args.docId] - Document ID to use (optional).
186
150
  * @param {boolean} [args.useAutonumber=true] - Whether to use auto-numbering.
@@ -188,26 +152,29 @@ export default class Site extends GeocodableMixin(FireModel) {
188
152
  * @param {Function} [args.callBack] - Callback function.
189
153
  * @param {string} [args.prefix] - Path prefix.
190
154
  * @returns {Promise<void>}
155
+ * @throws {Error} `customerId` と `customerName` の両方が未設定の場合にスローされます。
191
156
  */
192
157
  async beforeCreate(args = {}) {
193
158
  await super.beforeCreate(args);
194
- // if (!this.customerId) return;
195
- // const customerInstance = new Customer();
196
- // const isExist = await customerInstance.fetch({
197
- // ...args,
198
- // docId: this.customerId,
199
- // });
200
- // if (!isExist) {
201
- // return Promise.reject(
202
- // new Error("Invalid customerId: Customer does not exist.")
203
- // );
204
- // }
205
- // this.customer = customerInstance;
159
+
160
+ /**
161
+ * 取引先IDが指定されておらず、かつ取引先名が指定されていない場合はエラーをスロー
162
+ */
163
+ if (!this.customerId && !this.customerName) {
164
+ throw new Error(
165
+ "Either customerId or customerName must be provided for temporary registration.",
166
+ );
167
+ }
168
+
206
169
  await this._setCustomer();
207
170
  }
208
171
 
209
172
  /**
210
- * Override beforeUpdate to prevent changing customer reference.
173
+ * ドキュメント更新直前の処理です。
174
+ * - `customerId` に該当する `Customer` インスタンスを取得して `customer` プロパティにセットします。
175
+ * - 一度設定した取引先を未設定に戻すことはできません。
176
+ * - 取引先が変更されていた場合は `customer` プロパティを更新します。
177
+ * - `customerId` と `customerName` の両方が未設定の場合はエラーをスローします。
211
178
  * @param {Object} args - Creation options.
212
179
  * @param {Object} [args.transaction] - Firestore transaction.
213
180
  * @param {Function} [args.callBack] - Callback function.
@@ -217,13 +184,7 @@ export default class Site extends GeocodableMixin(FireModel) {
217
184
  async beforeUpdate(args = {}) {
218
185
  await super.beforeUpdate(args);
219
186
 
220
- // if (this.customer.docId !== this._beforeData.customer.docId) {
221
- // return Promise.reject(
222
- // new Error("Not allowed to change customer reference.")
223
- // );
224
- // }
225
-
226
- // 取引先を未設定に戻すことはできない。
187
+ // 一度設定した取引先を未設定に戻すことはできない。
227
188
  if (this._beforeData.customerId && !this.customerId) {
228
189
  throw new Error("Cannot unset customerId once it is set.");
229
190
  }
@@ -232,11 +193,28 @@ export default class Site extends GeocodableMixin(FireModel) {
232
193
  if (this.customerId !== this._beforeData.customerId) {
233
194
  await this._setCustomer();
234
195
  }
196
+
197
+ /**
198
+ * 取引先IDが指定されておらず、かつ取引先名が指定されていない場合はエラーをスロー
199
+ */
200
+ if (!this.customerId && !this.customerName) {
201
+ throw new Error(
202
+ "Either customerId or customerName must be provided for temporary registration.",
203
+ );
204
+ }
235
205
  }
236
206
 
207
+ /**
208
+ * Override `afterInitialize` to define custom accessors and methods.
209
+ * - Defines `fullAddress`, `prefecture`, and `isTemporary` accessors.
210
+ * - Enhances `agreements` array with `add`, `change`, and `remove` methods.
211
+ * @param {Object} item - Initial data item.
212
+ * @return {void}
213
+ */
237
214
  afterInitialize(item = {}) {
238
215
  super.afterInitialize(item);
239
216
 
217
+ /** Define `fullAddress`, `prefecture`, and `isTemporary` accessors. */
240
218
  Object.defineProperties(this, {
241
219
  fullAddress: defAccessor("fullAddress"),
242
220
  prefecture: defAccessor("prefecture"),
@@ -244,64 +222,105 @@ export default class Site extends GeocodableMixin(FireModel) {
244
222
  configurable: true,
245
223
  enumerable: true,
246
224
  get() {
247
- return !!this.customerId;
225
+ return !this.customerId;
248
226
  },
249
227
  set() {},
250
228
  },
251
229
  });
252
230
 
253
- const self = this;
231
+ /** 2026-03-31 Deprecated */
232
+ // /**
233
+ // * `Agreement` プロパティに対するカスタムメソッドを定義します。
234
+ // * - add(agreement): `Agreement` インスタンスを追加します。
235
+ // * - change(newAgreement): `key` プロパティを基に既存の `Agreement` を置き換えます。
236
+ // * - remove(agreement): `key` プロパティを基に `Agreement` を削除します。
237
+ // */
238
+ // const self = this;
239
+ // Object.defineProperties(this.agreements, {
240
+ // add: {
241
+ // value: function (agreement) {
242
+ // if (!(agreement instanceof Agreement)) {
243
+ // throw new Error("Argument must be an instance of Agreement");
244
+ // }
245
+ // self.agreements.push(agreement);
246
+ // },
247
+ // writable: false,
248
+ // enumerable: false,
249
+ // },
250
+ // change: {
251
+ // value: function (newAgreement) {
252
+ // if (!(newAgreement instanceof Agreement)) {
253
+ // throw new Error("Argument must be an instance of Agreement");
254
+ // }
255
+ // const index = self.agreements.findIndex(
256
+ // (agr) => agr.key === newAgreement._beforeData.key,
257
+ // );
258
+ // if (index !== -1) {
259
+ // self.agreements[index] = newAgreement;
260
+ // } else {
261
+ // throw new Error("Agreement not found");
262
+ // }
263
+ // },
264
+ // writable: false,
265
+ // enumerable: false,
266
+ // },
267
+ // remove: {
268
+ // value: function (agreement) {
269
+ // const index = self.agreements.findIndex(
270
+ // (agr) => agr.key === agreement._beforeData.key,
271
+ // );
272
+ // if (index !== -1) {
273
+ // self.agreements.splice(index, 1);
274
+ // } else {
275
+ // throw new Error("Agreement not found");
276
+ // }
277
+ // },
278
+ // },
279
+ // });
280
+ }
254
281
 
255
- /**
256
- * `Agreement` プロパティに対するカスタムメソッドを定義します。
257
- * - add(agreement): `Agreement` インスタンスを追加します。
258
- * - change(newAgreement): `key` プロパティを基に既存の `Agreement` を置き換えます。
259
- * - remove(agreement): `key` プロパティを基に `Agreement` を削除します。
260
- */
261
- Object.defineProperties(this.agreements, {
262
- add: {
263
- value: function (agreement) {
264
- if (!(agreement instanceof Agreement)) {
265
- throw new Error("Argument must be an instance of Agreement");
266
- }
267
- self.agreements.push(agreement);
268
- },
269
- writable: false,
270
- enumerable: false,
271
- },
272
- change: {
273
- value: function (newAgreement) {
274
- if (!(newAgreement instanceof Agreement)) {
275
- throw new Error("Argument must be an instance of Agreement");
276
- }
277
- const index = self.agreements.findIndex(
278
- (agr) => agr.key === newAgreement._beforeData.key
279
- );
280
- if (index !== -1) {
281
- self.agreements[index] = newAgreement;
282
- } else {
283
- throw new Error("Agreement not found");
284
- }
285
- },
286
- writable: false,
287
- enumerable: false,
288
- },
289
- remove: {
290
- value: function (agreement) {
291
- const index = self.agreements.findIndex(
292
- (agr) => agr.key === agreement._beforeData.key
293
- );
294
- if (index !== -1) {
295
- self.agreements.splice(index, 1);
296
- } else {
297
- throw new Error("Agreement not found");
298
- }
299
- },
300
- },
282
+ /**
283
+ * 指定された日付、勤務区分で有効な取極めオブジェクトを返します。
284
+ * - 日付が指定されなかった場合は、登録されている最新の取極めオブジェクトを返します。
285
+ * - 条件に合致する取極めオブジェクトが存在しない場合は `null` を返します。
286
+ * @param {string} date - 日付 (YYYY-MM-DD形式)
287
+ * @param {string} shiftType - 勤務区分
288
+ * @returns {Object|null} - 有効な取極めオブジェクトまたは `null`
289
+ */
290
+ getValidAgreement({ date = null, shiftType = null } = {}) {
291
+ const filtered = this.agreementsV2.filter((agr) => {
292
+ return agr.shiftType === shiftType;
301
293
  });
294
+ if (filtered.length === 0) return null;
295
+ filtered.sort((a, b) => b.date.localeCompare(a.date));
296
+ if (!date) return filtered[0];
297
+ return filtered.find((agr) => agr.date <= date) || null;
298
+ }
299
+
300
+ /***************************************************************************
301
+ * FOR DEPRECATED PROPERTIES
302
+ ***************************************************************************/
303
+ /**
304
+ * @deprecated `agreements` property is deprecated. Use `agreementsV2` instead.
305
+ */
306
+ get agreements() {
307
+ console.warn(
308
+ "Warning: `agreements` is deprecated. Use `agreementsV2` instead.",
309
+ );
310
+ return [];
311
+ }
312
+
313
+ /**
314
+ * @deprecated `agreements` property is deprecated. Use `agreementsV2` instead.
315
+ */
316
+ set agreements(newValue) {
317
+ console.warn(
318
+ "Warning: `agreements` is deprecated. Use `agreementsV2` instead.",
319
+ );
302
320
  }
303
321
 
304
322
  /**
323
+ * @deprecated `getAgreement` method is deprecated. Use `getValidAgreement` instead.
305
324
  * Returns the applicable agreement based on the given date, dayType, and shiftType.
306
325
  * Filters agreements by dayType and shiftType, sorts them by startDate in descending order,
307
326
  * and returns the first agreement where date is less than or equal to the given date.
@@ -313,13 +332,17 @@ export default class Site extends GeocodableMixin(FireModel) {
313
332
  * @returns {Object|null} - The matching agreement object or null if not found.
314
333
  */
315
334
  getAgreement(args = {}) {
316
- const { date, dayType, shiftType } = args;
317
- if (!date || !dayType || !shiftType) return null;
318
- return (
319
- this.agreements
320
- .filter((agr) => agr.dayType === dayType && agr.shiftType === shiftType)
321
- .sort((a, b) => b.date.localeCompare(a.date))
322
- .find((agr) => agr.date <= date) || null
335
+ // const { date, dayType, shiftType } = args;
336
+ // if (!date || !dayType || !shiftType) return null;
337
+ // return (
338
+ // this.agreements
339
+ // .filter((agr) => agr.dayType === dayType && agr.shiftType === shiftType)
340
+ // .sort((a, b) => b.date.localeCompare(a.date))
341
+ // .find((agr) => agr.date <= date) || null
342
+ // );
343
+ console.warn(
344
+ "Warning: `getAgreement` is deprecated. Use `getValidAgreement` instead.",
323
345
  );
346
+ return null;
324
347
  }
325
348
  }