@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
@@ -1,68 +1,78 @@
1
1
  /*****************************************************************************
2
- * SiteOperationScheduleDetail ver 1.0.0
2
+ * @file ./src/SiteOperationScheduleDetail.js
3
3
  * @author shisyamo4131
4
- * ---------------------------------------------------------------------------
5
- * - Model representing the details of a site operation schedule.
6
- * - Inherits from OperationDetail.
7
- * ---------------------------------------------------------------------------
8
- * @prop {string} siteOperationScheduleId - Site Operation Schedule ID
9
- * @prop {boolean} hasNotification - Notification flag
10
- * ---------------------------------------------------------------------------
11
- * @computed {string} notificationKey - Notification key (read-only)
12
- * - Concatenation of `siteOperationScheduleId` and `workerId` with '-'
13
- * ---------------------------------------------------------------------------
14
- * @inherited - The following properties are inherited from OperationDetail:
15
- * @prop {string} id - Employee or Outsourcer document ID
16
- * @prop {number} index - Identifier index for Outsourcer (always 0 for Employee)
17
- * @prop {boolean} isEmployee - Employee flag (true: Employee, false: Outsourcer)
18
- * @prop {number} amount - Number of placements (always fixed at 1)
19
- * @prop {string} siteId - Site ID
20
- * @prop {boolean} isQualified - Qualified flag
21
- * @prop {boolean} isOjt - OJT flag
22
- * ---------------------------------------------------------------------------
23
- * @inherited - The following computed properties are inherited from OperationDetail:
24
- * @computed {string} workerId - Worker ID (read-only)
25
- * - For Employee, it's the same as `id`, for Outsourcer, it's a concatenation of `id` and `index` with ':'
26
- * @computed {string|null} employeeId - Employee ID (null if not applicable) (read-only)
27
- * @computed {string|null} outsourcerId - Outsourcer ID (null if not applicable) (read-only)
28
- * ---------------------------------------------------------------------------
29
- * @inherited - The following properties are inherited from WorkingResult (via OperationDetail):
30
- * @prop {Date} dateAt - Placement date (trigger property)
31
- * @prop {string} dayType - Day type (e.g., `WEEKDAY`, `WEEKEND`, `HOLIDAY`)
32
- * @prop {string} shiftType - `DAY` or `NIGHT`
33
- * @prop {string} startTime - Start time (HH:MM format)
34
- * @prop {boolean} isStartNextDay - Next day start flag
35
- * @prop {string} endTime - End time (HH:MM format)
36
- * @prop {number} breakMinutes - Break time (minutes)
37
- * @prop {number} regulationWorkMinutes - Regulation work minutes
38
- * ---------------------------------------------------------------------------
39
- * @inherited - The following computed properties are inherited from WorkingResult (via OperationDetail):
40
- * @computed {string} key - Unique key combining `date`, `dayType`, and `shiftType` (read-only)
41
- * @computed {string} date - Date string in YYYY-MM-DD format based on `dateAt` (read-only)
42
- * @computed {boolean} isSpansNextDay - Flag indicating whether the date spans from start date to end date (read-only)
43
- * @computed {Date} startAt - Start date and time (Date object) (read-only)
44
- * @computed {Date} endAt - End date and time (Date object) (read-only)
45
- * @computed {number} totalWorkMinutes - Total working time in minutes (excluding break time) (read-only)
46
- * @computed {number} regularTimeWorkMinutes - Regular working time in minutes (read-only)
47
- * @computed {number} overtimeWorkMinutes - Overtime work in minutes (read-only)
48
- * - Calculated as `totalWorkMinutes` minus `regulationWorkMinutes`
49
- * - Overtime work is not negative; the minimum is 0.
50
- * ---------------------------------------------------------------------------
51
- * @inherited - The following getter properties are inherited from WorkingResult (via OperationDetail):
52
- * @getter {number} startHour - Start hour (0-23) (read-only)
53
- * - Extracted from `startTime`.
54
- * @getter {number} startMinute - Start minute (0-59) (read-only)
55
- * - Extracted from `startTime`.
56
- * @getter {number} endHour - End hour (0-23) (read-only)
57
- * - Extracted from `endTime`.
58
- * @getter {number} endMinute - End minute (0-59) (read-only)
59
- * - Extracted from `endTime`.
60
- * ---------------------------------------------------------------------------
61
- * @inherited - The following method is inherited from WorkingResult (via OperationDetail):
62
- * @method {function} setDateAtCallback - Callback method called when `dateAt` is set
63
- * - Override this method in subclasses to add custom behavior when `dateAt` changes.
64
- * - By default, updates `dayType` based on the new `dateAt` value.
65
- * - @param {Date} v - The new `dateAt` value
4
+ * @description 現場稼働予定明細クラス
5
+ *
6
+ * @class
7
+ * @extends OperationDetail
8
+ * @abstract
9
+ * @see ArrangementNotification
10
+ *
11
+ * @property {Date} dateAt - 日付 (変更されると `dayType` が自動的に更新されます)
12
+ * @property {string} shiftType - 勤務区分
13
+ * @property {string} startTime - 開始時刻 (HH:MM 形式)
14
+ * @property {string} endTime - 終了時刻 (HH:MM 形式)
15
+ * @property {boolean} isStartNextDay - 翌日開始フラグ
16
+ * - `true` の場合、実際の勤務は `dateAt` の翌日であることを意味します。
17
+ * @property {number} breakMinutes - 休憩時間 ()
18
+ * @property {string} date - `dateAt` に基づく YYYY-MM-DD 形式の日付文字列 (読み取り専用)
19
+ * - `dateAt` に基づいて YYYY-MM-DD 形式の文字列を返します。
20
+ * @property {Date} startAt - 開始日時 (Date オブジェクト) (読み取り専用)
21
+ * - `dateAt` に基づいて `startTime` を設定した Date オブジェクトを返します。
22
+ * - `isStartNextDay` が true の場合、1日加算します。
23
+ * @property {Date} endAt - 終了日時 (Date オブジェクト) (読み取り専用)
24
+ * - `startAt` を起点に、最初に現れる `endTime` Date オブジェクトを返します。
25
+ * @property {boolean} isSpansNextDay - 翌日跨ぎフラグ (読み取り専用)
26
+ * - `true` の場合、`startAt` `endAt` の日付が異なることを意味します。
27
+ * @property {number} regulationWorkMinutes - 規定労働時間 ()
28
+ * - `startAt` から `endAt` までの時間から `breakMinutes` を差し引いた時間のうち、
29
+ * 規定内として扱う労働時間(分)です。
30
+ * - 実際の労働時間から残業時間を算出するための基準となる値です。
31
+ * - この値があることで、取極めに柔軟な設定を行うことが可能になる他、労働基準法の 1 日の所定労働時間上限が変更された際に
32
+ * 影響を最小限に抑えることができます。
33
+ * 例) 8:00 から 17:00 までの勤務で休憩が 60 分の場合
34
+ * - 規定労働時間を 8 時間 (480 分) とし、実際の勤務が 8 時間 (480 分) を超えた分が残業時間として扱われます。
35
+ * 例) 8:00 から 16:00 までの勤務で休憩が 60 分の場合
36
+ * - 規定労働時間を 7 時間 (420 分) とすると、実際の勤務が 7 時間 (420 分) を超えた分が残業時間として扱われます。
37
+ * - 規定労働時間を 8 時間 (480 分) とすると、実際の勤務が 8 時間 (480 分) を超えた分が残業時間として扱われます。
38
+ * 例) 7:00 から 翌日 7:00 までの勤務で休憩が 60 分の場合
39
+ * - 規定労働時間を 8 時間 (480 分) とすると、実際の勤務が 8 時間 (480 ) を超えた分が残業時間として扱われます。
40
+ * この場合、最初の 8 時間までは基本単価が適用され、残りの 8 時間は残業単価が適用されるといった設定が可能になります。
41
+ * - 規定労働時間を 24 時間 (1440 分) とすると、実際の勤務が 24 時間 (1440 分) を超えた分が残業時間として扱われます。
42
+ * この場合、全ての勤務時間が基本単価で扱われるといった設定が可能になります。
43
+ * @property {string} dayType - 曜日区分
44
+ * @property {number} totalWorkMinutes - 総労働時間 (休憩時間を除く) () (読み取り専用)
45
+ * @property {number} regularTimeWorkMinutes - 所定労働時間 () (読み取り専用)
46
+ * @property {number} overtimeWorkMinutes - 残業時間 (分) (読み取り専用)
47
+ * @property {string} id - 従業員ID または 外注先ID
48
+ * @property {number} index - 外注先の識別用インデックス (従業員の場合は常に0)
49
+ * @property {boolean} isEmployee - 従業員フラグ (true: 従業員, false: 外注先)
50
+ * @property {number} amount - 配置人数 (常に1で固定)
51
+ * @property {string} siteId - 現場ID
52
+ * @property {boolean} isQualified - 資格者フラグ
53
+ * @property {boolean} isOjt - OJTフラグ
54
+ * @property {string} workerId - 作業者ID (読み取り専用)
55
+ * - 従業員の場合は `id` と同じ、外注先の場合は `id` と `index` を `:` で結合した文字列を返します。
56
+ * @property {string|null} employeeId - 従業員ID (該当しない場合は null) (読み取り専用)
57
+ * @property {string|null} outsourcerId - 外注先ID (該当しない場合は null) (読み取り専用)
58
+ * @property {string} siteOperationScheduleId - 現場稼働予定ID
59
+ * @property {boolean} hasNotification - 配置通知が作成されているかどうかのフラグ
60
+ * - SiteOperationSchedule クラスから設定されます。
61
+ * @property {string} notificationKey - 通知キー (読み取り専用)
62
+ * - `siteOperationScheduleId` `workerId` `_` で連結した文字列を返します。
63
+ * - `ArrangementNotification` のドキュメント ID と一致します。
64
+ *
65
+ * @method setDateAtCallback - `dateAt` が設定されたときに呼び出されるコールバック関数
66
+ * @method getInvalidReasons - クラス特有のエラーの有無を返すメソッド
67
+ *
68
+ * @getter {boolean} isInvalid - クラス特有のエラーが存在するかどうかを返すプロパティ
69
+ * @getter {Array<string>} invalidReasons - クラス特有のエラーコードの配列を返すプロパティ
70
+ *
71
+ * @static SHIFT_TYPE - 勤務区分を定義する定数オブジェクト
72
+ * @static INVALID_REASON - クラス特有のエラーコードを定義する定数オブジェクト
73
+ * - `BREAK_MINUTES_NEGATIVE`: `breakMinutes` が負の値である場合のエラーコード
74
+ * - `REGULATION_WORK_MINUTES_NEGATIVE`: `regulationWorkMinutes` が負の値である場合のエラーコード
75
+ * @static DAY_TYPE - 曜日区分を定義する定数オブジェクト
66
76
  *****************************************************************************/
67
77
  import OperationDetail from "./OperationDetail.js";
68
78
  import { defField } from "./parts/fieldDefinitions.js";
@@ -79,7 +89,7 @@ export default class SiteOperationScheduleDetail extends OperationDetail {
79
89
 
80
90
  /**
81
91
  * afterInitialize
82
- * @param {*} item
92
+ * @param {Object} item - 初期化オブジェクト
83
93
  */
84
94
  afterInitialize(item = {}) {
85
95
  super.afterInitialize(item);
@@ -90,7 +100,7 @@ export default class SiteOperationScheduleDetail extends OperationDetail {
90
100
  configurable: true,
91
101
  enumerable: true,
92
102
  get() {
93
- return `${this.siteOperationScheduleId}-${this.workerId}`;
103
+ return `${this.siteOperationScheduleId}_${this.workerId}`;
94
104
  },
95
105
  set() {},
96
106
  },
package/src/SiteOrder.js CHANGED
@@ -1,33 +1,26 @@
1
1
  /**
2
- * Represents the order of site-shift type pairs for placement management.
2
+ * @file ./src/SiteOrder.js
3
+ * @description 現場配置順序を表すクラス
4
+ * - 現場と勤務区分の組み合わせの順序を管理するためのクラスです。
5
+ * @author shisyamo4131
3
6
  *
4
- * @class SiteOrder
7
+ * @class
5
8
  * @extends BaseClass
6
9
  *
7
10
  * @property {string} siteId - The unique identifier for the site. Required.
8
11
  * @property {string} shiftType - The type of shift associated with the site. Required.
9
12
  *
10
- * @property {string} key - A computed property that returns a unique key in the format `${siteId}-${shiftType}` for identifying the site-shift pair.
13
+ * @getter {string} key - `siteId` `shiftType` をアンダースコアで結合した文字列を返します。
14
+ * @setter key - `siteId` と `shiftType` をアンダースコアで結合した文字列を受け取り、両方の値を分割して `siteId` と `shiftType` に設定します。
15
+ * - 受け取る値は文字列である必要があり、フォーマットは "siteId-shiftType" でなければなりません。
16
+ * - フォーマットが正しくない場合や、値が文字列でない場合は、プロパティの値は変更されません。
11
17
  */
12
18
  import { BaseClass } from "@shisyamo4131/air-firebase-v2";
13
19
  import { defField } from "./parts/fieldDefinitions.js";
14
20
 
15
- /**
16
- * Represents the order configuration for a site and shift type.
17
- *
18
- * @class SiteOrder
19
- * @extends BaseClass
20
- *
21
- * @property {string} siteId - The unique identifier for the site.
22
- * @property {string} shiftType - The type of shift associated with the site.
23
- * @property {string} key - A composite key in the format "siteId-shiftType".
24
- *
25
- * @getter
26
- * Returns the composite key for the site and shift type in the format "siteId-shiftType".
27
- *
28
- * @setter
29
- * Sets the `siteId` and `shiftType` properties from a composite key string in the format "siteId-shiftType".
30
- */
21
+ /*****************************************************************************
22
+ * SiteOrder
23
+ *****************************************************************************/
31
24
  export default class SiteOrder extends BaseClass {
32
25
  static className = "現場配置順序";
33
26
  static classProps = {
@@ -36,24 +29,20 @@ export default class SiteOrder extends BaseClass {
36
29
  };
37
30
 
38
31
  /**
39
- * Gets the composite key for this site and shift type.
40
- * @returns {string} The key in the format "siteId-shiftType".
32
+ * `siteId` `shiftType` を結合したキーを返すゲッター
33
+ * @returns {string} The key in the format "siteId_shiftType".
41
34
  */
42
35
  get key() {
43
- return `${this.siteId}-${this.shiftType}`;
36
+ return `${this.siteId}_${this.shiftType}`;
44
37
  }
45
38
 
46
39
  /**
47
- * Setter for the `key` property.
48
- * Expects a string in the format "siteId-shiftType".
49
- * Splits the input string and assigns the values to `siteId` and `shiftType` properties if both are present.
50
- * Ignores the value if it is not a string.
51
- *
52
- * @param {string} value - The key string in the format "siteId-shiftType".
40
+ * `siteId` `shiftType` を結合したキーを受け取り、両方の値を分割して `siteId` と `shiftType` に設定するセッター
41
+ * @param {string} value - The key string in the format "siteId_shiftType".
53
42
  */
54
43
  set key(value) {
55
44
  if (typeof value !== "string") return;
56
- const [siteId, shiftType] = value.split("-");
45
+ const [siteId, shiftType] = value.split("_");
57
46
  if (siteId && shiftType) {
58
47
  this.siteId = siteId;
59
48
  this.shiftType = shiftType;
package/src/User.js CHANGED
@@ -1,57 +1,51 @@
1
- /**
2
- * User Model
3
- * @version 1.1.0
4
- * @author shisyamo4131
5
- * @update 2025-12-25 Added `tagSize` property.
6
- * Added `updateProperties` method for updating multiple properties.
7
- * @update 2025-11-24 Added `companyId`, `isAdmin`, `isTemporary` property.
8
- * Changed to prevent deletion of admin users.
9
- *
10
- * @prop {string} email - User's email address.
11
- * @prop {string} displayName - User's display name.
12
- * @prop {string} [employeeId] - Employee ID (not required as some users may not be employees).
13
- * @prop {Array<string>} roles - User roles/permissions.
14
- * @prop {boolean} disabled - Indicates if the user is disabled.
15
- * @prop {string} companyId - ID of the associated company.
16
- * @prop {boolean} isAdmin - Indicates if the user is an administrator.
17
- * @prop {boolean} isTemporary - Indicates if the user is temporary.
18
- * @prop {string} tagSize - Size of the tag associated with the user.
19
- */
1
+ /*****************************************************************************
2
+ * @file src/User.js
3
+ *****************************************************************************/
20
4
  import FireModel from "@shisyamo4131/air-firebase-v2";
21
5
  import { defField } from "./parts/fieldDefinitions.js";
22
6
  import { TAG_SIZE_VALUES, TAG_SIZE_OPTIONS } from "./constants/index.js";
23
7
 
24
- const classProps = {
25
- email: defField("email", { required: true }),
26
- displayName: defField("displayName", { required: true }),
27
- employeeId: defField("oneLine", { label: "従業員ID", hidden: true }),
28
- roles: {
29
- type: Array,
30
- default: () => [],
31
- label: "権限",
32
- required: false,
33
- hidden: false,
34
- },
35
- disabled: defField("check", {
36
- label: "使用不可",
37
- default: false,
38
- required: false,
39
- hidden: true,
40
- }),
41
- companyId: defField("oneLine", { hidden: true, required: true }),
42
- isAdmin: defField("check", { hidden: true, default: false }),
43
- isTemporary: defField("check", { hidden: true, default: true }),
44
- tagSize: defField("select", {
45
- label: "タグサイズ",
46
- default: TAG_SIZE_VALUES.MEDIUM.value,
47
- options: TAG_SIZE_OPTIONS,
48
- }),
49
- };
50
-
8
+ /*****************************************************************************
9
+ * @class User
10
+ * @extends FireModel
11
+ *
12
+ * @property {string} email - メールアドレス
13
+ * @property {string} displayName - 表示名
14
+ * @property {string} [employeeId] - 従業員ID(非従業員を許容するために必須とはしない)
15
+ * @property {Array<string>} roles - アプリケーション利用権限
16
+ * @property {boolean} disabled - 有効/無効
17
+ * @property {string} companyId - 会社ID
18
+ * @property {boolean} isAdmin - 管理者であるかどうか
19
+ * @property {boolean} isTemporary - 仮登録状態であるかどうか
20
+ * @property {string} tagSize - 配置管理機能におけるタグコンポーネントの表示サイズ
21
+ *****************************************************************************/
51
22
  export default class User extends FireModel {
52
23
  static className = "ユーザー";
53
24
  static collectionPath = "Users";
54
- static classProps = classProps;
25
+ static classProps = {
26
+ /**
27
+ * email
28
+ * - 登録時以外編集不可。
29
+ * - ユーザーアカウントのメールアドレスの変更は Cloud Functions 経由とする。
30
+ * - ユーザーアカウントのグローバル重複チェックは Cloud Functions 経由とする。
31
+ */
32
+ email: defField("email", {
33
+ required: true,
34
+ component: {
35
+ attrs: {
36
+ disabled: ({ editMode, item }) => editMode !== "CREATE",
37
+ },
38
+ },
39
+ }),
40
+ displayName: defField("displayName", { required: true }),
41
+ employeeId: defField("oneLine", { label: "従業員ID", hidden: true }),
42
+ roles: defField("roles"),
43
+ disabled: defField("disabled", { hidden: true }),
44
+ companyId: defField("companyId", { hidden: true, required: true }),
45
+ isAdmin: defField("isAdmin", { hidden: true }),
46
+ isTemporary: defField("isTemporary", { hidden: true, default: true }),
47
+ tagSize: defField("tagSize", { required: true }),
48
+ };
55
49
 
56
50
  /**
57
51
  * Deletes the user document.
@@ -82,6 +76,9 @@ export default class User extends FireModel {
82
76
  * @returns {Promise<DocumentReference>} Reference to the updated document.
83
77
  * @throws {Error} If `updateData` is not a valid object.
84
78
  * @throws {Error} If `docId` is not set, or if `updateOptions.callback` is not a function.
79
+ *
80
+ * Note: このメソッドは複数のプロパティを一括更新するためのヘルパーメソッド。BaseClass に移設しても良いかもしれない。
81
+ * なお、`useAuthStore` で使用中のようだ。
85
82
  */
86
83
  async updateProperties(updateData = null, updateOptions = {}) {
87
84
  if (!updateData || typeof updateData !== "object") {
@@ -0,0 +1,205 @@
1
+ /*****************************************************************************
2
+ * @file ./src/WorkTimeBase.js
3
+ * @author shisyamo4131
4
+ * @description 勤務実績情報の基底クラス
5
+ * - 日付や時間に関するプロパティを持つ抽象クラスです。インスタンス化はできません。
6
+ * - 24時間を超える勤務は管理できません。`startTime` と `endTime` に同時刻が設定された場合は、24時間勤務と見做されます。
7
+ *
8
+ * @class
9
+ * @extends FireModel
10
+ * @abstract
11
+ * @see AgreementV2
12
+ * @see WorkingResult
13
+ *
14
+ * @property {Date} dateAt - 日付
15
+ * @property {string} shiftType - 勤務区分
16
+ * @property {string} startTime - 開始時刻 (HH:MM 形式)
17
+ * @property {string} endTime - 終了時刻 (HH:MM 形式)
18
+ * @property {boolean} isStartNextDay - 翌日開始フラグ
19
+ * - `true` の場合、実際の勤務は `dateAt` の翌日であることを意味します。
20
+ * @property {number} breakMinutes - 休憩時間 (分)
21
+ * @property {string} date - `dateAt` に基づく YYYY-MM-DD 形式の日付文字列 (読み取り専用)
22
+ * - `dateAt` に基づいて YYYY-MM-DD 形式の文字列を返します。
23
+ * @property {Date} startAt - 開始日時 (Date オブジェクト) (読み取り専用)
24
+ * - `dateAt` に基づいて `startTime` を設定した Date オブジェクトを返します。
25
+ * - `isStartNextDay` が true の場合、1日加算します。
26
+ * @property {Date} endAt - 終了日時 (Date オブジェクト) (読み取り専用)
27
+ * - `startAt` を起点に、最初に現れる `endTime` の Date オブジェクトを返します。
28
+ * @property {boolean} isSpansNextDay - 翌日跨ぎフラグ (読み取り専用)
29
+ * - `true` の場合、`startAt` と `endAt` の日付が異なることを意味します。
30
+ * @property {number} regulationWorkMinutes - 規定労働時間 (分)
31
+ * - `startAt` から `endAt` までの時間から `breakMinutes` を差し引いた時間のうち、
32
+ * 規定内として扱う労働時間(分)です。
33
+ * - 実際の労働時間から残業時間を算出するための基準となる値です。
34
+ * - この値があることで、取極めに柔軟な設定を行うことが可能になる他、労働基準法の 1 日の所定労働時間上限が変更された際に
35
+ * 影響を最小限に抑えることができます。
36
+ * 例) 8:00 から 17:00 までの勤務で休憩が 60 分の場合
37
+ * - 規定労働時間を 8 時間 (480 分) とし、実際の勤務が 8 時間 (480 分) を超えた分が残業時間として扱われます。
38
+ * 例) 8:00 から 16:00 までの勤務で休憩が 60 分の場合
39
+ * - 規定労働時間を 7 時間 (420 分) とすると、実際の勤務が 7 時間 (420 分) を超えた分が残業時間として扱われます。
40
+ * - 規定労働時間を 8 時間 (480 分) とすると、実際の勤務が 8 時間 (480 分) を超えた分が残業時間として扱われます。
41
+ * 例) 7:00 から 翌日 7:00 までの勤務で休憩が 60 分の場合
42
+ * - 規定労働時間を 8 時間 (480 分) とすると、実際の勤務が 8 時間 (480 分) を超えた分が残業時間として扱われます。
43
+ * この場合、最初の 8 時間までは基本単価が適用され、残りの 8 時間は残業単価が適用されるといった設定が可能になります。
44
+ * - 規定労働時間を 24 時間 (1440 分) とすると、実際の勤務が 24 時間 (1440 分) を超えた分が残業時間として扱われます。
45
+ * この場合、全ての勤務時間が基本単価で扱われるといった設定が可能になります。
46
+ *
47
+ * @method setDateAtCallback - `dateAt` が設定されたときに呼び出されるコールバック関数
48
+ *
49
+ * @getter {boolean} isInvalid - クラス特有のエラーが存在するかどうかを返すプロパティ
50
+ * @getter {Array<string>} invalidReasons - クラス特有のエラーコードの配列を返すプロパティ
51
+ *
52
+ * @static SHIFT_TYPE - 勤務区分を定義する定数オブジェクト
53
+ *****************************************************************************/
54
+ import FireModel from "@shisyamo4131/air-firebase-v2";
55
+ import { defField } from "./parts/fieldDefinitions.js";
56
+ import { getDateAt, formatJstDate } from "./utils/index.js";
57
+ import { VALUES as SHIFT_TYPE } from "./constants/shift-type.js";
58
+
59
+ const classProps = {
60
+ dateAt: defField("dateAt", { required: true }),
61
+ shiftType: defField("shiftType", { required: true }),
62
+ startTime: defField("time", { label: "開始時刻", required: true }),
63
+ isStartNextDay: defField("check", { label: "翌日開始" }),
64
+ endTime: defField("time", { label: "終了時刻", required: true }),
65
+ breakMinutes: defField("breakMinutes", { required: true }),
66
+ regulationWorkMinutes: defField("regulationWorkMinutes", { required: true }),
67
+ };
68
+
69
+ /*****************************************************************************
70
+ * WorkTimeBase
71
+ *****************************************************************************/
72
+ export default class WorkTimeBase extends FireModel {
73
+ static className = "WorkTimeBase";
74
+ static collectionPath = "WorkTimeBases";
75
+ static useAutonumber = false;
76
+ static logicalDelete = false;
77
+ static classProps = classProps;
78
+
79
+ static SHIFT_TYPE = SHIFT_TYPE;
80
+
81
+ /**
82
+ * Constructor
83
+ * - 抽象クラスのため、直接のインスタンス化を防止します。
84
+ * @param {Object} item - 初期化オブジェクト
85
+ */
86
+ constructor(item = {}) {
87
+ if (new.target === WorkTimeBase) {
88
+ throw new Error(
89
+ "WorkTimeBase is an abstract class and cannot be instantiated directly.",
90
+ );
91
+ }
92
+ super(item);
93
+ }
94
+
95
+ /**
96
+ * afterInitialize
97
+ * @param {Object} item - 初期化オブジェクト
98
+ */
99
+ afterInitialize(item = {}) {
100
+ super.afterInitialize(item);
101
+
102
+ let _dateAt = this.dateAt;
103
+ Object.defineProperties(this, {
104
+ /**
105
+ * `dateAt` プロパティの変更に伴った処理を実現するため、`dateAt` を getter/setter で再定義します。
106
+ * - `setDateAtCallback` メソッドを使用して `dateAt` の変更に伴うカスタム処理を実装可能です。
107
+ */
108
+ dateAt: {
109
+ configurable: true,
110
+ enumerable: true,
111
+ get() {
112
+ return _dateAt;
113
+ },
114
+ set(v) {
115
+ if (_dateAt && v.getTime() === _dateAt.getTime()) {
116
+ return;
117
+ }
118
+ const newDate = new Date(v);
119
+ newDate.setHours(0, 0, 0, 0); // 時刻部分をクリア
120
+ _dateAt = newDate;
121
+ this.setDateAtCallback(newDate);
122
+ },
123
+ },
124
+
125
+ /**
126
+ * date - `dateAt` に基づく YYYY-MM-DD 形式の日付文字列 (読み取り専用)
127
+ */
128
+ date: {
129
+ configurable: true,
130
+ enumerable: true,
131
+ get() {
132
+ return formatJstDate(this.dateAt) || "";
133
+ },
134
+ set(v) {},
135
+ },
136
+
137
+ /**
138
+ * isSpansNextDay - 翌日跨ぎフラグ (読み取り専用)
139
+ * - `startAt` の日付よりも `endAt` の日付が後である場合に `true` を返します。
140
+ */
141
+ isSpansNextDay: {
142
+ configurable: true,
143
+ enumerable: true,
144
+ get() {
145
+ if (!this.startAt || !this.endAt) return false;
146
+ const startDate = new Date(this.startAt);
147
+ const endDate = new Date(this.endAt);
148
+ startDate.setHours(0, 0, 0, 0);
149
+ endDate.setHours(0, 0, 0, 0);
150
+ return endDate.getTime() > startDate.getTime();
151
+ },
152
+ set(v) {},
153
+ },
154
+
155
+ /**
156
+ * startAt - 開始日時 (Date オブジェクト) (読み取り専用)
157
+ * - `dateAt` に基づいて `startTime` を設定した Date オブジェクトを返します。
158
+ * - `isStartNextDay` が true の場合、1日加算します。
159
+ */
160
+ startAt: {
161
+ configurable: true,
162
+ enumerable: true,
163
+ get() {
164
+ if (!this.startTime) return null;
165
+ const dateOffset = this.isStartNextDay ? 1 : 0;
166
+ return getDateAt(this.dateAt, this.startTime, dateOffset);
167
+ },
168
+ set(v) {},
169
+ },
170
+
171
+ /**
172
+ * endAt - 終了日時 (Date オブジェクト) (読み取り専用)
173
+ * - `startAt` を起点に、最初に現れる `endTime` の Date オブジェクトを返します。
174
+ * - `startTime` と `endTime` が同時刻の場合は 24時間勤務と見做し、`endAt` は翌日の同時刻になります。
175
+ */
176
+ endAt: {
177
+ configurable: true,
178
+ enumerable: true,
179
+ get() {
180
+ if (!this.startAt || !this.endTime) return null;
181
+
182
+ const baseDate = new Date(this.startAt);
183
+ baseDate.setHours(0, 0, 0, 0);
184
+ const endAt = getDateAt(baseDate, this.endTime, 0);
185
+
186
+ if (endAt.getTime() <= this.startAt.getTime()) {
187
+ endAt.setDate(endAt.getDate() + 1);
188
+ }
189
+
190
+ return endAt;
191
+ },
192
+ set(v) {},
193
+ },
194
+ });
195
+ }
196
+
197
+ /**
198
+ * `dateAt` が変更されたときに呼び出されるコールバック関数
199
+ * - サブクラスでこのメソッドをオーバーライドして、`dateAt` の変更に伴うカスタム処理を実装できます。
200
+ * - `dateAt` をこの関数内で更新してはいけません。
201
+ * @param {Date} v - 新しい `dateAt` 値
202
+ * @returns {void}
203
+ */
204
+ setDateAtCallback(v) {}
205
+ }