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

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 (47) 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 +591 -297
  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/index.js +4 -0
  28. package/src/constants/insurance-status.js +15 -0
  29. package/src/constants/shift-type.js +5 -2
  30. package/src/errorDefinitions.js +173 -0
  31. package/src/parts/fieldDefinitions/array.js +50 -0
  32. package/src/parts/fieldDefinitions/check.js +53 -0
  33. package/src/parts/fieldDefinitions/code.js +8 -0
  34. package/src/parts/fieldDefinitions/constants.js +9 -0
  35. package/src/parts/fieldDefinitions/dateAt.js +63 -0
  36. package/src/parts/fieldDefinitions/dateTimeAt.js +8 -0
  37. package/src/parts/fieldDefinitions/defaultDefinition.js +118 -0
  38. package/src/parts/fieldDefinitions/multipleLine.js +16 -0
  39. package/src/parts/fieldDefinitions/number.js +69 -0
  40. package/src/parts/fieldDefinitions/object.js +38 -0
  41. package/src/parts/fieldDefinitions/oneLine.js +409 -0
  42. package/src/parts/fieldDefinitions/radio.js +8 -0
  43. package/src/parts/fieldDefinitions/select.js +267 -0
  44. package/src/parts/fieldDefinitions/time.js +8 -0
  45. package/src/parts/fieldDefinitions.js +46 -669
  46. package/src/utils/CutoffDate.js +11 -15
  47. package/src/utils/index.js +44 -8
package/src/Operation.js CHANGED
@@ -1,175 +1,108 @@
1
1
  /*****************************************************************************
2
- * Operation Model ver 1.0.0
2
+ * @file ./src/Operation.js
3
3
  * @author shisyamo4131
4
- * ---------------------------------------------------------------------------
5
- * - Base class of SiteOperationSchedule and OperationResult based on WorkingResult.
6
- * - `dateAt` property indicates the date of operation (placement date) used for billing purposes.
7
- * Actual working day may differ from this date.
8
- * - `siteId`, `dateAt`, `shiftType`, and `regulationWorkMinutes` are
9
- * automatically synchronized to all assigned employees and outsourcers
10
- * when they are changed on the Operation instance.
11
- * - `startTime`, `endTime`, and `breakMinutes` are NOT synchronized here.
12
- * They should be synchronized at `SiteOperationSchedule` level instead.
13
- * ---------------------------------------------------------------------------
14
- * @property {string} siteId
15
- * - Site document ID (trigger property)
16
- * - Automatically synchronizes to all `employees` and `outsourcers` when changed.
4
+ * @description 稼働情報クラス
5
+ * - 稼働情報を表す抽象クラスです。インスタンス化はできません。
17
6
  *
18
- * @property {number} requiredPersonnel
19
- * - Required number of personnel
7
+ * @class
8
+ * @extends WorkingResult
9
+ * @abstract
10
+ * @see OperationResult
11
+ * @see SiteOperationSchedule
20
12
  *
21
- * @property {boolean} qualificationRequired
22
- * - Qualification required flag
23
- *
24
- * @property {string} workDescription
25
- * - Work description
26
- *
27
- * @property {string} remarks
28
- * - Remarks
29
- *
30
- * @property {Array<OperationDetail>} employees
31
- * - Assigned employees
32
- * - Array of `OperationDetail` instances representing assigned employees
33
- *
34
- * @property {Array<OperationDetail>} outsourcers
35
- * - Assigned outsourcers
36
- * - Array of `OperationDetail` instances representing assigned outsourcers
37
- *
38
- * @property {Array<string>} employeeIds - Array of employee IDs from `employees` (read-only)
39
- * - Array of employee IDs from `employees` (read-only)
40
- *
41
- * @property {Array<string>} outsourcerIds
42
- * - Array of outsourcer IDs from `outsourcers` (read-only)
43
- *
44
- * @property {number} employeesCount
45
- * - Count of assigned employees (read-only)
46
- *
47
- * @property {number} outsourcersCount
48
- * - Count of assigned outsourcers (sum of amounts) (read-only)
49
- *
50
- * @property {boolean} isPersonnelShortage
51
- * - Indicates if there is a shortage of personnel (read-only)
52
- * - `true` if the sum of `employeesCount` and `outsourcersCount` is less than `requiredPersonnel`
13
+ * @property {Date} dateAt - 日付 (変更されると `dayType` が自動的に更新されます)
14
+ * @property {string} shiftType - 勤務区分 (変更されると `employees` と `outsourcers` の `shiftType` が自動的に更新されます)
15
+ * @property {string} startTime - 開始時刻 (HH:MM 形式)
16
+ * @property {string} endTime - 終了時刻 (HH:MM 形式)
17
+ * @property {boolean} isStartNextDay - 翌日開始フラグ
18
+ * - `true` の場合、実際の勤務は `dateAt` の翌日であることを意味します。
19
+ * @property {number} breakMinutes - 休憩時間 (分)
20
+ * @property {string} date - `dateAt` に基づく YYYY-MM-DD 形式の日付文字列 (読み取り専用)
21
+ * - `dateAt` に基づいて YYYY-MM-DD 形式の文字列を返します。
22
+ * @property {Date} startAt - 開始日時 (Date オブジェクト) (読み取り専用)
23
+ * - `dateAt` に基づいて `startTime` を設定した Date オブジェクトを返します。
24
+ * - `isStartNextDay` true の場合、1日加算します。
25
+ * @property {Date} endAt - 終了日時 (Date オブジェクト) (読み取り専用)
26
+ * - `startAt` を起点に、最初に現れる `endTime` の Date オブジェクトを返します。
27
+ * @property {boolean} isSpansNextDay - 翌日跨ぎフラグ (読み取り専用)
28
+ * - `true` の場合、`startAt` `endAt` の日付が異なることを意味します。
29
+ * @property {number} regulationWorkMinutes - 規定労働時間 (分) (変更されると `employees` と `outsourcers` の `regulationWorkMinutes` が自動的に更新されます)
30
+ * - `startAt` から `endAt` までの時間から `breakMinutes` を差し引いた時間のうち、
31
+ * 規定内として扱う労働時間(分)です。
32
+ * - 実際の労働時間から残業時間を算出するための基準となる値です。
33
+ * - この値があることで、取極めに柔軟な設定を行うことが可能になる他、労働基準法の 1 日の所定労働時間上限が変更された際に
34
+ * 影響を最小限に抑えることができます。
35
+ * 例) 8:00 から 17:00 までの勤務で休憩が 60 分の場合
36
+ * - 規定労働時間を 8 時間 (480 分) とし、実際の勤務が 8 時間 (480 分) を超えた分が残業時間として扱われます。
37
+ * 例) 8:00 から 16:00 までの勤務で休憩が 60 分の場合
38
+ * - 規定労働時間を 7 時間 (420 分) とすると、実際の勤務が 7 時間 (420 分) を超えた分が残業時間として扱われます。
39
+ * - 規定労働時間を 8 時間 (480 分) とすると、実際の勤務が 8 時間 (480 分) を超えた分が残業時間として扱われます。
40
+ * 例) 7:00 から 翌日 7:00 までの勤務で休憩が 60 分の場合
41
+ * - 規定労働時間を 8 時間 (480 分) とすると、実際の勤務が 8 時間 (480 分) を超えた分が残業時間として扱われます。
42
+ * この場合、最初の 8 時間までは基本単価が適用され、残りの 8 時間は残業単価が適用されるといった設定が可能になります。
43
+ * - 規定労働時間を 24 時間 (1440 分) とすると、実際の勤務が 24 時間 (1440 分) を超えた分が残業時間として扱われます。
44
+ * この場合、全ての勤務時間が基本単価で扱われるといった設定が可能になります。
45
+ * @property {string} dayType - 曜日区分
46
+ * @property {number} totalWorkMinutes - 総労働時間 (休憩時間を除く) (分) (読み取り専用)
47
+ * @property {number} regularTimeWorkMinutes - 所定労働時間 (分) (読み取り専用)
48
+ * @property {number} overtimeWorkMinutes - 残業時間 (分) (読み取り専用)
49
+ * @property {string} siteId - 現場ID (変更されると `employees` と `outsourcers` の `siteId` が自動的に更新されます)
50
+ * @property {number} requiredPersonnel - 必要人数
51
+ * @property {boolean} qualificationRequired - 資格要件フラグ
52
+ * @property {string} workDescription - 作業内容
53
+ * @property {string} remarks - 備考
54
+ * @property {Array<OperationDetail>} employees - 従業員の OperationDetail インスタンスの配列
55
+ * @property {Array<OperationDetail>} outsourcers - 外注の OperationDetail インスタンスの配列
56
+ * @property {Array<string>} employeeIds - 従業員の ID の配列 (読み取り専用)
57
+ * @property {Array<string>} outsourcerIds - 外注の ID の配列 (読み取り専用)
58
+ * @property {number} employeesCount - `employees` の要素数 (読み取り専用)
59
+ * @property {number} outsourcersCount - `outsourcers` の要素数 (読み取り専用)
60
+ * @property {boolean} isPersonnelShortage - 人員不足フラグ (読み取り専用)
61
+ * @property {Array<OperationDetail>} workers - 従業員と外注を合わせた配列
62
+ * - `employees` と `outsourcers` を結合した配列を返します。
63
+ * - Getter: `employees` と `outsourcers` を結合した配列を返します。
64
+ * - Setter: 配列を `isEmployee` プロパティに基づいて `employees` と `outsourcers` に分割します。
65
+ * @property {string} groupKey - `siteId`, `shiftType`, `date` を組み合わせたキー。(読み取り専用)
66
+ * @property {string} agreementKey - `date`, `shiftType` を組み合わせたキー。(読み取り専用)
67
+ * @property {string} orderKey - `siteId`, `shiftType` を組み合わせたキー。(読み取り専用)
53
68
  *
54
- * @property {Array<OperationDetail>} workers
55
- * - Combined array of `employees` and `outsourcers`
56
- * - Getter: Returns concatenated array of employees and outsourcers
57
- * - Setter: Splits array into employees and outsourcers based on `isEmployee` property
69
+ * @deprecated
70
+ * @property {string} key - 使用不可
58
71
  *
59
- * @property {string} key - `siteId`, `date`, `dayType`, `shiftType` を組み合わせたキー。(読み取り専用)
60
- * - `WorkingResult.key` をオーバーライドして `siteId` を含めるように定義されているが、未使用。
72
+ * @method setDateAtCallback - `dateAt` が設定されたときに呼び出されるコールバック関数
73
+ * @method addWorker - `Workers` に新しい従業員または外注先を追加します。
74
+ * @method moveWorker - 従業員または外注先の位置を移動します。
75
+ * @method changeWorker - 従業員または外注先の詳細を変更します。
76
+ * @method removeWorker - 従業員または外注先を `workers` から削除します。
77
+ * @method setSiteIdCallback - `siteId` が変更された時に呼び出されるコールバック関数
78
+ * @method setShiftTypeCallback - `shiftType` が変更された時に呼び出されるコールバック関数
79
+ * @method setRegulationWorkMinutesCallback - `regulationWorkMinutes` が変更された時に呼び出されるコールバック関数
61
80
  *
62
- * @property {string} agreementKey - `siteId`, `date`, `dayType`, `shiftType` を組み合わせたキー。(読み取り専用)
63
- * - 適用する取極めを特定するためのキーとして使用される。
81
+ * @getter {boolean} isInvalid - クラス特有のエラーが存在するかどうかを返すプロパティ
82
+ * @getter {Array<Object>} invalidReasons - エラーコード、メッセージ、多言語メッセージ、フィールド名を含む詳細情報の配列を返すプロパティ
83
+ * @getter {boolean} isGroupKeyChanged - `groupKey` プロパティが変更されたかどうかを返すプロパティ
84
+ * @getter {boolean} isAgreementKeyChanged - `agreementKey` プロパティが変更されたかどうかを返すプロパティ
85
+ * @getter {boolean} isEmployeesChanged - 従業員が変更されたかどうかを示すフラグ (読み取り専用)
86
+ * @getter {boolean} isOutsourcersChanged - 外注が変更されたかどうかを示すフラグ (読み取り専用)
87
+ * @getter {Array<OperationDetail>} addedWorkers - 追加された従業員の配列 (読み取り専用)
88
+ * @getter {Array<OperationDetail>} removedWorkers - 削除された従業員の配列 (読み取り専用)
89
+ * @getter {Array<OperationDetail>} updatedWorkers - 更新された従業員の配列 (読み取り専用)
64
90
  *
65
- * @property {string} orderKey - `siteId`, `shiftType` を組み合わせたキー。(読み取り専用)
66
- * - `siteOrder` `key` プロパティに対応するキー。稼働予測や配置管理で使用される。
91
+ * @deprecated
92
+ * @getter {boolean} isKeyChanged - 使用不可
67
93
  *
68
- * @getter {string} groupKey - Combines `siteId`, `shiftType`, and `date` to indicate operation grouping (read-only)
69
- * @getter {boolean} isEmployeesChanged - Indicates whether the employees have changed (read-only)
70
- * - Returns true if the employee IDs have changed compared to `_beforeData`
71
- * @getter {boolean} isOutsourcersChanged - Indicates whether the outsourcers have changed (read-only)
72
- * - Returns true if the outsourcer IDs have changed compared to `_beforeData`
73
- * @getter {Array<OperationDetail>} addedWorkers - An array of workers that have been added (read-only)
74
- * - Workers that exist in current data but not in `_beforeData`
75
- * @getter {Array<OperationDetail>} removedWorkers - An array of workers that have been removed (read-only)
76
- * - Workers that exist in `_beforeData` but not in current data
77
- * @getter {Array<OperationDetail>} updatedWorkers - An array of workers that have been updated (read-only)
78
- * - Workers whose `startTime`, `isStartNextDay`, `endTime`, `breakMinutes`, `isQualified`, or `isOjt` have changed
79
- * ---------------------------------------------------------------------------
80
- * @inherited - The following properties are inherited from WorkingResult:
94
+ * @static SHIFT_TYPE - 勤務区分を定義する定数オブジェクト
95
+ * @static INVALID_REASON - クラス特有のエラーコードを定義する定数オブジェクト
96
+ * - `BREAK_MINUTES_NEGATIVE`: `breakMinutes` が負の値である場合のエラーコード
97
+ * - `REGULATION_WORK_MINUTES_NEGATIVE`: `regulationWorkMinutes` が負の値である場合のエラーコード
98
+ * @static DAY_TYPE - 曜日区分を定義する定数オブジェクト
81
99
  *
82
- * @property {Date} dateAt - Date of operation (placement date) (trigger property)
83
- * - Automatically synchronizes to all `employees` and `outsourcers` when changed.
84
- * @property {string} dayType - Day type (e.g., `WEEKDAY`, `WEEKEND`, `HOLIDAY`)
85
- * @property {string} shiftType - `DAY` or `NIGHT` (trigger property)
86
- * - Automatically synchronizes to all `employees` and `outsourcers` when changed.
87
- * @property {string} startTime - Start time (HH:MM format)
88
- * @property {boolean} isStartNextDay - Next day start flag
89
- * - `true` if the actual work starts the day after the placement date `dateAt`
90
- * @property {string} endTime - End time (HH:MM format)
91
- * @property {number} breakMinutes - Break time (minutes)
92
- * @property {number} regulationWorkMinutes - Regulation work minutes (trigger property)
93
- * - Indicates the maximum working time treated as regular working hours.
94
- * - A new value will be synchronized to all `employees` and `outsourcers`.
95
- * ---------------------------------------------------------------------------
96
- * @inherited - The following computed properties are inherited from WorkingResult:
97
- * @computed {string} date - Date string in YYYY-MM-DD format based on `dateAt` (read-only)
98
- * @computed {Date} startAt - Start date and time (Date object) (read-only)
99
- * - Returns a Date object with `startTime` set based on `dateAt`.
100
- * - If `isStartNextDay` is true, add 1 day.
101
- * @computed {Date} endAt - End date and time (Date object) (read-only)
102
- * - Returns a Date object with `endTime` set based on `dateAt`.
103
- * - If `isStartNextDay` is true, add 1 day.
104
- * - If `isSpansNextDay` is true, add 1 day.
105
- * @computed {boolean} isSpansNextDay - Flag indicating whether the date spans from start date to end date (read-only)
106
- * - `true` if `startTime` is later than `endTime`
107
- * @computed {number} totalWorkMinutes - Total working time in minutes (excluding break time) (read-only)
108
- * - Calculated as the difference between `endAt` and `startAt` minus `breakMinutes`
109
- * @computed {number} regularTimeWorkMinutes - Regular working time in minutes (read-only)
110
- * - The portion of `totalWorkMinutes` that is considered within the contract's `regulationWorkMinutes`.
111
- * @computed {number} overtimeWorkMinutes - Overtime work in minutes (read-only)
112
- * - Calculated as `totalWorkMinutes` minus `regulationWorkMinutes`
113
- * ---------------------------------------------------------------------------
114
- * @inherited - The following getter properties are inherited from WorkingResult:
115
- * @getter {number} startHour - Start hour (0-23) (read-only)
116
- * - Extracted from `startTime`.
117
- * @getter {number} startMinute - Start minute (0-59) (read-only)
118
- * - Extracted from `startTime`.
119
- * @getter {number} endHour - End hour (0-23) (read-only)
120
- * - Extracted from `endTime`.
121
- * @getter {number} endMinute - End minute (0-59) (read-only)
122
- * - Extracted from `endTime`.
123
- * @getter {boolean} isKeyChanged - Flag indicating whether the key has changed compared to previous data (read-only)
124
- * - Compares the current `key` with the `key` in `_beforeData`.
125
- * ---------------------------------------------------------------------------
126
- * @method {function} addWorker - Adds a new worker (employee or outsourcer)
127
- * - @param {Object} options - Options for adding a worker
128
- * - @param {string} options.id - The worker ID (employeeId or outsourcerId)
129
- * - @param {boolean} [options.isEmployee=true] - Whether the worker is an employee
130
- * - @param {number} [index=0] - Insertion position. If -1, adds to the end
131
- * @method {function} moveWorker - Moves the position of a worker (employee or outsourcer)
132
- * - @param {Object} options - Options for changing worker position
133
- * - @param {number} options.oldIndex - The original index
134
- * - @param {number} options.newIndex - The new index
135
- * - @param {boolean} [options.isEmployee=true] - True for employee, false for outsourcer
136
- * @method {function} changeWorker - Changes the details of a worker
137
- * - @param {Object} newWorker - New worker object
138
- * @method {function} removeWorker - Removes a worker (employee or outsourcer)
139
- * - @param {Object} options - Options for removing a worker
140
- * - @param {string} options.workerId - The ID of the employee or outsourcer
141
- * - @param {boolean} [options.isEmployee=true] - True for employee, false for outsourcer
142
- * @method {function} setSiteIdCallback - Callback method called when `siteId` is set
143
- * - Override this method in subclasses to add custom behavior when `siteId` changes.
144
- * - By default, does nothing.
145
- * - @param {string} v - The new `siteId` value
146
- * @method {function} setShiftTypeCallback - Callback method called when `shiftType` is set
147
- * - Override this method in subclasses to add custom behavior when `shiftType` changes.
148
- * - By default, does nothing.
149
- * - @param {string} v - The new `shiftType` value
150
- * @method {function} setRegulationWorkMinutesCallback - Callback method called when `regulationWorkMinutes` is set
151
- * - Override this method in subclasses to add custom behavior when `regulationWorkMinutes` changes.
152
- * - By default, does nothing.
153
- * - @param {number} v - The new `regulationWorkMinutes` value
154
- * ---------------------------------------------------------------------------
155
100
  * @static
156
- * @method groupKeyDivider
157
- * Returns an array dividing the key into siteId, shiftType, and date.
158
- * @param {Object|string} key - The combined key string or object
159
- * @returns {Array<string>} - Array containing [siteId, shiftType, date]
160
- * @throws {Error} - If the key is invalid.
161
- * ---------------------------------------------------------------------------
162
- * @inherited - The following method is inherited from WorkingResult:
163
- * @method {function} setDateAtCallback - Callback method called when `dateAt` is set
164
- * - Override this method in subclasses to add custom behavior when `dateAt` changes.
165
- * - By default, updates `dayType` based on the new `dateAt` value and synchronizes to workers.
166
- * - @param {Date} v - The new `dateAt` value
101
+ * @method groupKeyDivider - `groupKey` を構成する要素を分割して返す静的メソッド
167
102
  *****************************************************************************/
168
103
  import WorkingResult from "./WorkingResult.js";
169
104
  import OperationDetail from "./OperationDetail.js";
170
105
  import { defField } from "./parts/fieldDefinitions.js";
171
- import { VALUES as DAY_TYPE } from "./constants/day-type.js";
172
- import { VALUES as SHIFT_TYPE } from "./constants/shift-type.js";
173
106
 
174
107
  const classProps = {
175
108
  siteId: defField("siteId", { required: true }),
@@ -187,23 +120,6 @@ const classProps = {
187
120
  }),
188
121
  };
189
122
 
190
- /**
191
- * Wrapper to define computed properties.
192
- * @param {*} obj
193
- * @param {*} properties
194
- */
195
- function defineComputedProperties(obj, properties) {
196
- const descriptors = {};
197
- for (const [key, descriptor] of Object.entries(properties)) {
198
- descriptors[key] = {
199
- configurable: true,
200
- enumerable: true,
201
- ...descriptor,
202
- };
203
- }
204
- Object.defineProperties(obj, descriptors);
205
- }
206
-
207
123
  export default class Operation extends WorkingResult {
208
124
  static className = "稼働ベース";
209
125
  static collectionPath = "Operations";
@@ -211,30 +127,20 @@ export default class Operation extends WorkingResult {
211
127
  static logicalDelete = false;
212
128
  static classProps = classProps;
213
129
 
214
- static DAY_TYPE = DAY_TYPE;
215
- static SHIFT_TYPE = SHIFT_TYPE;
216
-
217
130
  /**
218
131
  * Constructor
219
- * @param {*} item
132
+ * - 抽象クラスのため、直接のインスタンス化を防止します。
133
+ * @param {Object} item - 初期化オブジェクト
220
134
  */
221
135
  constructor(item = {}) {
222
136
  if (new.target == Operation) {
223
137
  throw new Error(
224
- `Operation is an abstract class and cannot be instantiated directly.`
138
+ `Operation is an abstract class and cannot be instantiated directly.`,
225
139
  );
226
140
  }
227
141
  super(item);
228
142
  }
229
143
 
230
- /**
231
- * setSiteIdCallback
232
- * - Callback method called when `siteId` is set.
233
- * - Override this method in subclasses to add custom behavior when `siteId` changes.
234
- * @param {*} v
235
- */
236
- setSiteIdCallback(v) {}
237
-
238
144
  /**
239
145
  * setDateAtCallback
240
146
  * - Callback method called when `dateAt` is set.
@@ -247,13 +153,27 @@ export default class Operation extends WorkingResult {
247
153
  this.outsourcers.forEach((out) => (out.dateAt = v));
248
154
  }
249
155
 
156
+ /**
157
+ * setSiteIdCallback
158
+ * - Callback method called when `siteId` is set.
159
+ * - Override this method in subclasses to add custom behavior when `siteId` changes.
160
+ * @param {*} v
161
+ */
162
+ setSiteIdCallback(v) {
163
+ this.employees.forEach((emp) => (emp.siteId = v));
164
+ this.outsourcers.forEach((out) => (out.siteId = v));
165
+ }
166
+
250
167
  /**
251
168
  * setShiftTypeCallback
252
169
  * - Callback method called when `shiftType` is set.
253
170
  * - Override this method in subclasses to add custom behavior when `shiftType` changes.
254
171
  * @param {*} v
255
172
  */
256
- setShiftTypeCallback(v) {}
173
+ setShiftTypeCallback(v) {
174
+ this.employees.forEach((emp) => (emp.shiftType = v));
175
+ this.outsourcers.forEach((out) => (out.shiftType = v));
176
+ }
257
177
 
258
178
  /**
259
179
  * setRegulationWorkMinutesCallback
@@ -261,39 +181,46 @@ export default class Operation extends WorkingResult {
261
181
  * - Override this method in subclasses to add custom behavior when `regulationWorkMinutes` changes.
262
182
  * @param {*} v
263
183
  */
264
- setRegulationWorkMinutesCallback(v) {}
184
+ setRegulationWorkMinutesCallback(v) {
185
+ this.employees.forEach((emp) => (emp.regulationWorkMinutes = v));
186
+ this.outsourcers.forEach((out) => (out.regulationWorkMinutes = v));
187
+ }
265
188
 
266
189
  /**
267
190
  * afterInitialize
191
+ * @param {Object} item - 初期化オブジェクト
268
192
  */
269
193
  afterInitialize(item = {}) {
270
194
  super.afterInitialize(item);
271
195
 
196
+ /***********************************************************
197
+ * KEY PROPERTIES
198
+ ***********************************************************/
272
199
  Object.defineProperties(this, {
273
200
  /**
274
- * `siteId`, `date`, `dayType`, `shiftType` を組み合わせたキー。(読み取り専用)
275
- * - `WorkingResult.key` をオーバーライド。
276
- * - 2026-01-07 現在使用していないプロパティ。
277
- * - `dayType` は請求時の単価情報を取得するために必要な情報であるため含める必要がないと思われる。
201
+ * `date`, `shiftType`, `siteId` を組み合わせたキー。(読み取り専用)
278
202
  */
279
- key: {
203
+ groupKey: {
280
204
  configurable: true,
281
- enumberable: true,
205
+ enumerable: true,
282
206
  get() {
283
- return `${this.siteId}-${this.date}-${this.dayType}-${this.shiftType}`;
207
+ const date = this.dateAt ? this.date : "null";
208
+ const shiftType = this.shiftType || "null";
209
+ const siteId = this.siteId || "null";
210
+ return `${siteId}_${shiftType}_${date}`;
284
211
  },
285
212
  set() {},
286
213
  },
287
214
 
288
215
  /**
289
- * `siteId`, `date`, `dayType`, `shiftType` を組み合わせたキー。(読み取り専用)
290
- * - 適用する取極めを特定するためのキーとして使用される。
216
+ * `date`, `shiftType` を組み合わせたキー。(読み取り専用)
217
+ * - 適用する取極めを特定するためのキーとして使用。
291
218
  */
292
219
  agreementKey: {
293
220
  configurable: true,
294
- enumberable: true,
221
+ enumerable: true,
295
222
  get() {
296
- return `${this.siteId}-${this.date}-${this.dayType}-${this.shiftType}`;
223
+ return `${this.date}_${this.shiftType}`;
297
224
  },
298
225
  set() {},
299
226
  },
@@ -304,9 +231,9 @@ export default class Operation extends WorkingResult {
304
231
  */
305
232
  orderKey: {
306
233
  configurable: true,
307
- enumberable: true,
234
+ enumerable: true,
308
235
  get() {
309
- return `${this.siteId}-${this.shiftType}`;
236
+ return `${this.siteId}_${this.shiftType}`;
310
237
  },
311
238
  set() {},
312
239
  },
@@ -326,8 +253,10 @@ export default class Operation extends WorkingResult {
326
253
  let _siteId = this.siteId;
327
254
  let _shiftType = this.shiftType;
328
255
  let _regulationWorkMinutes = this.regulationWorkMinutes;
329
- defineComputedProperties(this, {
256
+ Object.defineProperties(this, {
330
257
  siteId: {
258
+ configurable: true,
259
+ enumerable: true,
331
260
  get() {
332
261
  return _siteId;
333
262
  },
@@ -337,12 +266,12 @@ export default class Operation extends WorkingResult {
337
266
  }
338
267
  if (_siteId === v) return;
339
268
  _siteId = v;
340
- this.employees.forEach((emp) => (emp.siteId = v));
341
- this.outsourcers.forEach((out) => (out.siteId = v));
342
269
  this.setSiteIdCallback(v);
343
270
  },
344
271
  },
345
272
  shiftType: {
273
+ configurable: true,
274
+ enumerable: true,
346
275
  get() {
347
276
  return _shiftType;
348
277
  },
@@ -350,67 +279,91 @@ export default class Operation extends WorkingResult {
350
279
  if (typeof v !== "string") {
351
280
  throw new Error(`shiftType must be a string. shiftType: ${v}`);
352
281
  }
353
- if (!SHIFT_TYPE[v]) {
282
+ if (!WorkingResult.SHIFT_TYPE[v]) {
354
283
  throw new Error(`Invalid shiftType value. shiftType: ${v}`);
355
284
  }
356
285
  if (_shiftType === v) return;
357
286
  _shiftType = v;
358
- this.employees.forEach((emp) => (emp.shiftType = v));
359
- this.outsourcers.forEach((out) => (out.shiftType = v));
360
287
  this.setShiftTypeCallback(v);
361
288
  },
362
289
  },
363
290
  regulationWorkMinutes: {
291
+ configurable: true,
292
+ enumerable: true,
364
293
  get() {
365
294
  return _regulationWorkMinutes;
366
295
  },
367
296
  set(v) {
368
297
  if (typeof v !== "number" || isNaN(v) || v < 0) {
369
298
  throw new Error(
370
- `regulationWorkMinutes must be a non-negative number. regulationWorkMinutes: ${v}`
299
+ `regulationWorkMinutes must be a non-negative number. regulationWorkMinutes: ${v}`,
371
300
  );
372
301
  }
373
302
  if (_regulationWorkMinutes === v) return;
374
303
  _regulationWorkMinutes = v;
375
- this.employees.forEach((emp) => (emp.regulationWorkMinutes = v));
376
- this.outsourcers.forEach((out) => (out.regulationWorkMinutes = v));
377
304
  this.setRegulationWorkMinutesCallback(v);
378
305
  },
379
306
  },
380
307
  });
381
308
 
382
- /** define computed properies */
383
- defineComputedProperties(this, {
384
- /** Returns an array of employee IDs */
309
+ /***********************************************************
310
+ * OTHER PROPERTIES
311
+ ***********************************************************/
312
+ Object.defineProperties(this, {
313
+ /**
314
+ * `employeeId` の配列を返します。
315
+ */
385
316
  employeeIds: {
317
+ configurable: true,
318
+ enumerable: true,
386
319
  get() {
387
320
  return this.employees.map((emp) => emp.employeeId);
388
321
  },
389
322
  set(v) {},
390
323
  },
391
- /** Returns an array of outsourcer IDs */
324
+
325
+ /**
326
+ * `outsourcerId` の配列を返します。
327
+ */
392
328
  outsourcerIds: {
329
+ configurable: true,
330
+ enumerable: true,
393
331
  get() {
394
332
  return this.outsourcers.map((out) => out.outsourcerId);
395
333
  },
396
334
  set(v) {},
397
335
  },
398
- /** Returns the count of assigned employees */
336
+
337
+ /**
338
+ * `employees` に割り当てられた人数を返します。
339
+ */
399
340
  employeesCount: {
341
+ configurable: true,
342
+ enumerable: true,
400
343
  get() {
401
344
  return this.employees.length;
402
345
  },
403
346
  set(v) {},
404
347
  },
405
- /** Returns the count of assigned outsourcers (sum of amounts) */
348
+
349
+ /**
350
+ * `outsourcers` に割り当てられた人数を返します。
351
+ */
406
352
  outsourcersCount: {
353
+ configurable: true,
354
+ enumerable: true,
407
355
  get() {
408
356
  return this.outsourcers.reduce((sum, i) => sum + i.amount, 0);
409
357
  },
410
358
  set(v) {},
411
359
  },
412
- /** Returns whether there is a personnel shortage */
360
+
361
+ /**
362
+ * 必要人数に対して、割り当てられた従業員と外注先の合計人数が不足しているかどうかを返します。
363
+ */
413
364
  isPersonnelShortage: {
365
+ configurable: true,
366
+ enumerable: true,
414
367
  get() {
415
368
  const totalRequired = this.requiredPersonnel || 0;
416
369
  const totalAssigned = this.employeesCount + this.outsourcersCount;
@@ -418,8 +371,14 @@ export default class Operation extends WorkingResult {
418
371
  },
419
372
  set(v) {},
420
373
  },
421
- /** Returns a combined array of employees and outsourcers */
374
+
375
+ /**
376
+ * `employees` と `outsourcers` を組み合わせた配列を返します。
377
+ * セッターは、`isEmployee` プロパティに基づいて、従業員と外注先を分割して `employees` と `outsourcers` に設定します。
378
+ */
422
379
  workers: {
380
+ configurable: true,
381
+ enumerable: true,
423
382
  get() {
424
383
  return this.employees.concat(this.outsourcers);
425
384
  },
@@ -432,7 +391,9 @@ export default class Operation extends WorkingResult {
432
391
  },
433
392
  });
434
393
 
435
- /** Define custom methods for employees and outsourcers */
394
+ /***********************************************************
395
+ * METHODS FOR MANAGING EMPLOYEES AND OUTSOURCERS
396
+ ***********************************************************/
436
397
  const self = this;
437
398
  Object.defineProperties(this.employees, {
438
399
  /**
@@ -456,7 +417,7 @@ export default class Operation extends WorkingResult {
456
417
  const { id } = args;
457
418
  if (!id || typeof id !== "string") {
458
419
  throw new Error(
459
- `Employee ID is required and must be a string. id: ${id}`
420
+ `Employee ID is required and must be a string. id: ${id}`,
460
421
  );
461
422
  }
462
423
  if (this.some((emp) => emp.workerId === id)) {
@@ -467,7 +428,7 @@ export default class Operation extends WorkingResult {
467
428
  throw new Error("employees.customClass is not defined.");
468
429
  }
469
430
  const newEmployee = new schema({
470
- ...self.toObject(),
431
+ ...self.toObject(), // 自身のプロパティを継承(siteId, dateAt, shiftType, startTime, endTime, breakMinutes など)
471
432
  ...args,
472
433
  isEmployee: true, // Force override to true
473
434
  });
@@ -490,7 +451,7 @@ export default class Operation extends WorkingResult {
490
451
  value: function (oldIndex, newIndex) {
491
452
  if (newIndex > this.length - 1) {
492
453
  throw new Error(
493
- `Employees must be placed before outsourcers. newIndex: ${newIndex}, employees.length: ${this.length}`
454
+ `Employees must be placed before outsourcers. newIndex: ${newIndex}, employees.length: ${this.length}`,
494
455
  );
495
456
  }
496
457
  if (newIndex < 0 || newIndex >= this.length) {
@@ -510,7 +471,7 @@ export default class Operation extends WorkingResult {
510
471
  change: {
511
472
  value: function (newEmployee) {
512
473
  const index = this.findIndex(
513
- (e) => e.workerId === newEmployee.workerId
474
+ (e) => e.workerId === newEmployee.workerId,
514
475
  );
515
476
  if (index < 0) {
516
477
  throw new Error("Worker not found in employees.");
@@ -559,7 +520,7 @@ export default class Operation extends WorkingResult {
559
520
  const { id } = args;
560
521
  if (!id || typeof id !== "string") {
561
522
  throw new Error(
562
- `Outsourcer ID is required and must be a string. id: ${id}`
523
+ `Outsourcer ID is required and must be a string. id: ${id}`,
563
524
  );
564
525
  }
565
526
  const maxIndex = this.reduce((result, out) => {
@@ -600,16 +561,16 @@ export default class Operation extends WorkingResult {
600
561
  value: function (oldIndex, newIndex) {
601
562
  if (newIndex <= self.employees.length - 1) {
602
563
  throw new Error(
603
- `Outsourcers must be placed after employees. newIndex: ${newIndex}, employees.length: ${self.employees.length}`
564
+ `Outsourcers must be placed after employees. newIndex: ${newIndex}, employees.length: ${self.employees.length}`,
604
565
  );
605
566
  }
606
567
  const internalOldIndex = Math.max(
607
568
  0,
608
- oldIndex - self.employees.length
569
+ oldIndex - self.employees.length,
609
570
  );
610
571
  const internalNewIndex = Math.max(
611
572
  0,
612
- newIndex - self.employees.length
573
+ newIndex - self.employees.length,
613
574
  );
614
575
  if (internalOldIndex < 0 || internalOldIndex >= this.length) {
615
576
  throw new Error(`Invalid old index: ${internalOldIndex}`);
@@ -631,7 +592,7 @@ export default class Operation extends WorkingResult {
631
592
  change: {
632
593
  value: function (newOutsourcer) {
633
594
  const index = this.findIndex(
634
- (e) => e.workerId === newOutsourcer.workerId
595
+ (e) => e.workerId === newOutsourcer.workerId,
635
596
  );
636
597
  if (index < 0) {
637
598
  throw new Error("Worker not found in outsourcers.");
@@ -662,23 +623,41 @@ export default class Operation extends WorkingResult {
662
623
  }
663
624
 
664
625
  /***************************************************************************
665
- * STATES
626
+ * GETTERS
666
627
  ***************************************************************************/
667
628
  /**
668
- * Returns a string combining siteId, shiftType, and date.
669
- * - Indicates where this operation belongs.
670
- * @returns {string} - The group key.
629
+ * `siteId`, `shiftType`, `date` のいずれかが変更されたかどうかを返します。
630
+ * - いずれかが変更された場合は true を返します。
631
+ * - すべてが変更されていない場合は false を返します。
632
+ * @returns {boolean} - `siteId`, `shiftType`, `date` のいずれかが変更されたかどうか。
633
+ */
634
+ get isGroupKeyChanged() {
635
+ const currentKey = this.groupKey;
636
+ const beforeKey = `${this._beforeData?.siteId || ""}_${
637
+ this._beforeData?.shiftType || ""
638
+ }_${this._beforeData?.date || ""}`;
639
+ return currentKey !== beforeKey;
640
+ }
641
+
642
+ /**
643
+ * `date`, `shiftType` のいずれかが変更されたかどうかを返します。
644
+ * - いずれかが変更された場合は true を返します。
645
+ * - すべてが変更されていない場合は false を返します。
646
+ * @returns {boolean} - `date`, `shiftType` のいずれかが変更されたかどうか。
671
647
  */
672
- get groupKey() {
673
- return `${this.siteId}-${this.shiftType}-${this.date}`;
648
+ get isAgreementKeyChanged() {
649
+ const currentKey = this.agreementKey;
650
+ const beforeKey = `${this._beforeData?.date || ""}_${
651
+ this._beforeData?.shiftType || ""
652
+ }`;
653
+ return currentKey !== beforeKey;
674
654
  }
675
655
 
676
656
  /**
677
- * Returns whether the employees have changed.
678
- * - Returns true if the employee IDs have changed.
679
- * - Returns false if the employee IDs have not changed or
680
- * are the same even if the order has changed.
681
- * @returns {boolean} - Whether the employees have changed.
657
+ * 従業員が変更されたかどうかを返します。
658
+ * - 従業員IDが変更された場合は true を返します。
659
+ * - 従業員IDが変更されていない場合、または順序が変更されても同じ場合は false を返します。
660
+ * @returns {boolean} - 従業員が変更されたかどうか。
682
661
  */
683
662
  get isEmployeesChanged() {
684
663
  const current = this.employeeIds || [];
@@ -687,11 +666,10 @@ export default class Operation extends WorkingResult {
687
666
  }
688
667
 
689
668
  /**
690
- * Returns whether the outsourcers have changed.
691
- * - Returns true if the outsourcer IDs have changed.
692
- * - Returns false if the outsourcer IDs have not changed or
693
- * are the same even if the order has changed.
694
- * @returns {boolean} - Whether the outsourcers have changed.
669
+ * 外注先が変更されたかどうかを返します。
670
+ * - 外注先IDが変更された場合は true を返します。
671
+ * - 外注先IDが変更されていない場合、または順序が変更されても同じ場合は false を返します。
672
+ * @returns {boolean} - 外注先が変更されたかどうか。
695
673
  */
696
674
  get isOutsourcersChanged() {
697
675
  const current = this.outsourcerIds || [];
@@ -700,8 +678,8 @@ export default class Operation extends WorkingResult {
700
678
  }
701
679
 
702
680
  /**
703
- * Returns a filtered array of workers that have been added.
704
- * @returns {Array<OperationDetail>} - Array of added workers.
681
+ * 追加された従業員の配列を返します。
682
+ * @returns {Array<OperationDetail>} - 追加された従業員の配列。
705
683
  */
706
684
  get addedWorkers() {
707
685
  const current = this.workers || [];
@@ -712,9 +690,8 @@ export default class Operation extends WorkingResult {
712
690
  }
713
691
 
714
692
  /**
715
- * Returns a filtered array of workers that have been removed.
716
- * Note: The returned elements do not exist in this.workers.
717
- * @returns {Array<OperationDetail>} - Array of removed workers.
693
+ * 削除された従業員の配列を返します。
694
+ * @returns {Array<OperationDetail>} - 削除された従業員の配列。
718
695
  */
719
696
  get removedWorkers() {
720
697
  const before = this._beforeData?.workers || [];
@@ -726,9 +703,9 @@ export default class Operation extends WorkingResult {
726
703
  }
727
704
 
728
705
  /**
729
- * Returns a filtered array of workers that have been updated.
730
- * - Compares `startTime`, `isStartNextDay`, `endTime`, and `breakMinutes` properties.
731
- * @returns {Array<OperationDetail>} - Array of updated workers.
706
+ * 更新された従業員の配列を返します。
707
+ * - `startTime`, `isStartNextDay`, `endTime`, `breakMinutes` プロパティを比較します。
708
+ * @returns {Array<OperationDetail>} - 更新された従業員の配列。
732
709
  */
733
710
  get updatedWorkers() {
734
711
  const before = this._beforeData.workers || [];
@@ -754,12 +731,12 @@ export default class Operation extends WorkingResult {
754
731
  * METHODS
755
732
  ***************************************************************************/
756
733
  /**
757
- * Adds a new worker.
758
- * - Calls the appropriate method based on the value of `isEmployee`.
759
- * @param {Object} options - Options for adding a worker.
760
- * @param {string} options.id - The worker ID (employeeId or outsourcerId)
761
- * @param {boolean} [options.isEmployee=true] - Whether the worker is an employee
762
- * @param {number} [index=0] - Insertion position. If -1, adds to the end.
734
+ * `Workers` に新しい従業員または外注先を追加します。
735
+ * - `isEmployee` の値に応じて適切なメソッドを呼び出します。
736
+ * @param {Object} options - 従業員または外注先を追加するためのオプション。
737
+ * @param {string} options.id - 従業員IDまたは外注先ID
738
+ * @param {boolean} [options.isEmployee=true] - 従業員かどうか
739
+ * @param {number} [index=0] - 挿入位置。-1 の場合は末尾に追加。
763
740
  */
764
741
  addWorker(options = {}, index = 0) {
765
742
  const { isEmployee = true } = options;
@@ -771,17 +748,17 @@ export default class Operation extends WorkingResult {
771
748
  }
772
749
 
773
750
  /**
774
- * Moves the position of workers.
775
- * @param {Object} options - Options for changing worker position.
776
- * @param {number} options.oldIndex - The original index.
777
- * @param {number} options.newIndex - The new index.
778
- * @param {boolean} [options.isEmployee=true] - True for employee, false for outsourcer.
751
+ * 従業員または外注先の位置を移動します。
752
+ * @param {Object} options - 従業員または外注先の位置を変更するためのオプション。
753
+ * @param {number} options.oldIndex - 元のインデックス。
754
+ * @param {number} options.newIndex - 新しいインデックス。
755
+ * @param {boolean} [options.isEmployee=true] - 従業員の場合は true、外注先の場合は false
779
756
  */
780
757
  moveWorker(options) {
781
758
  const { oldIndex, newIndex, isEmployee = true } = options;
782
759
  if (typeof oldIndex !== "number" || typeof newIndex !== "number") {
783
760
  throw new Error(
784
- "oldIndex and newIndex are required and must be numbers."
761
+ "oldIndex and newIndex are required and must be numbers.",
785
762
  );
786
763
  }
787
764
  if (isEmployee) {
@@ -792,8 +769,8 @@ export default class Operation extends WorkingResult {
792
769
  }
793
770
 
794
771
  /**
795
- * Changes the details of a worker.
796
- * @param {Object} newWorker - New worker object
772
+ * 従業員または外注先の詳細を変更します。
773
+ * @param {Object} newWorker - 新しい従業員オブジェクト
797
774
  */
798
775
  changeWorker(newWorker) {
799
776
  if (newWorker.isEmployee) {
@@ -804,10 +781,10 @@ export default class Operation extends WorkingResult {
804
781
  }
805
782
 
806
783
  /**
807
- * Removes an employee or outsourcer from the schedule.
808
- * @param {Object} options - Options for removing a worker.
809
- * @param {string} options.workerId - The ID of the employee or outsourcer.
810
- * @param {boolean} [options.isEmployee=true] - True for employee, false for outsourcer.
784
+ * 従業員または外注先を `workers` から削除します。
785
+ * @param {Object} options - 従業員または外注先を削除するためのオプション。
786
+ * @param {string} options.workerId - 従業員IDまたは外注先ID。
787
+ * @param {boolean} [options.isEmployee=true] - 従業員の場合は true、外注先の場合は false
811
788
  */
812
789
  removeWorker(options) {
813
790
  const { workerId, isEmployee = true } = options;
@@ -819,10 +796,10 @@ export default class Operation extends WorkingResult {
819
796
  }
820
797
 
821
798
  /**
822
- * Returns an array dividing the key into siteId, shiftType, and date.
799
+ * キーを siteIdshiftType、date に分割した配列を返します。
823
800
  * @param {Object|string} key
824
801
  * @returns {Array<string>} - [siteId, shiftType, date]
825
- * @throws {Error} - If the key is invalid.
802
+ * @throws {Error} - キーが無効な場合。
826
803
  */
827
804
  static groupKeyDivider(key = {}) {
828
805
  if (!key) throw new Error("key is required.");
@@ -831,20 +808,35 @@ export default class Operation extends WorkingResult {
831
808
  case "object":
832
809
  if (!key.siteId || !key.shiftType || !key.date) {
833
810
  throw new Error(
834
- "key must contain siteId, shiftType, and date properties."
811
+ "key must contain siteId, shiftType, and date properties.",
835
812
  );
836
813
  }
837
814
  return [key.siteId, key.shiftType, key.date];
838
815
  case "string":
839
- const [siteId, shiftType, year, month, day] = key.split("-");
840
- if (!siteId || !shiftType || !year || !month || !day) {
841
- throw new Error(
842
- "key must be in the format 'siteId-shiftType-year-month-day'."
843
- );
816
+ const [siteId, shiftType, date] = key.split("_");
817
+ if (!siteId || !shiftType || !date) {
818
+ throw new Error("key must be in the format 'siteId_shiftType_date'.");
844
819
  }
845
- return [siteId, shiftType, `${year}-${month}-${day}`];
820
+ return [siteId, shiftType, date];
846
821
  default:
847
822
  throw new Error("Invalid key type.");
848
823
  }
849
824
  }
825
+
826
+ /***************************************************************************
827
+ * FOR DEPRECATED PROPERTIES
828
+ ***************************************************************************/
829
+ get key() {
830
+ console.warn("Operation.key is deprecated.");
831
+ return null;
832
+ }
833
+
834
+ set key(v) {
835
+ console.warn("Operation.key is deprecated.");
836
+ }
837
+
838
+ get isKeyChanged() {
839
+ console.warn("Operation.isKeyChanged is deprecated.");
840
+ return false;
841
+ }
850
842
  }