@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.
- package/index.js +12 -0
- package/package.json +45 -47
- package/src/Agreement.js +17 -24
- package/src/AgreementV2.js +185 -0
- package/src/ArrangementNotification.js +16 -8
- package/src/Billing.js +5 -34
- package/src/Company.js +162 -25
- package/src/Customer.js +39 -59
- package/src/Employee.js +590 -300
- package/src/FcmToken.js +73 -0
- package/src/Insurance.js +409 -0
- package/src/Notification.js +95 -0
- package/src/NotificationRecipient.js +68 -0
- package/src/Operation.js +272 -280
- package/src/OperationBilling.js +126 -192
- package/src/OperationDetail.js +115 -85
- package/src/OperationResult.js +257 -254
- package/src/OperationResultDetail.js +65 -56
- package/src/Site.js +160 -137
- package/src/SiteOperationSchedule.js +187 -247
- package/src/SiteOperationScheduleDetail.js +75 -65
- package/src/SiteOrder.js +18 -29
- package/src/User.js +44 -47
- package/src/WorkTimeBase.js +205 -0
- package/src/WorkingResult.js +83 -255
- package/src/constants/day-type.js +20 -12
- package/src/constants/employment-status.js +2 -2
- package/src/constants/index.js +4 -0
- package/src/constants/insurance-status.js +15 -0
- package/src/constants/shift-type.js +5 -2
- package/src/errorDefinitions.js +173 -0
- package/src/parts/fieldDefinitions/array.js +50 -0
- package/src/parts/fieldDefinitions/check.js +53 -0
- package/src/parts/fieldDefinitions/code.js +8 -0
- package/src/parts/fieldDefinitions/constants.js +9 -0
- package/src/parts/fieldDefinitions/dateAt.js +63 -0
- package/src/parts/fieldDefinitions/dateTimeAt.js +8 -0
- package/src/parts/fieldDefinitions/defaultDefinition.js +118 -0
- package/src/parts/fieldDefinitions/multipleLine.js +16 -0
- package/src/parts/fieldDefinitions/number.js +69 -0
- package/src/parts/fieldDefinitions/object.js +38 -0
- package/src/parts/fieldDefinitions/oneLine.js +409 -0
- package/src/parts/fieldDefinitions/radio.js +8 -0
- package/src/parts/fieldDefinitions/select.js +267 -0
- package/src/parts/fieldDefinitions/time.js +8 -0
- package/src/parts/fieldDefinitions.js +46 -669
- package/src/utils/CutoffDate.js +11 -15
- package/src/utils/index.js +44 -8
package/src/OperationResult.js
CHANGED
|
@@ -1,191 +1,153 @@
|
|
|
1
1
|
/*****************************************************************************
|
|
2
|
-
* OperationResult
|
|
2
|
+
* @file ./src/OperationResult.js
|
|
3
3
|
* @author shisyamo4131
|
|
4
|
+
* @description 稼働実績クラス
|
|
5
|
+
* ### ドキュメント作成前処理
|
|
6
|
+
* - `siteId` から `customerId` を同期し、関連する `agreement` を適用します。
|
|
4
7
|
*
|
|
5
|
-
*
|
|
6
|
-
* -
|
|
7
|
-
* -
|
|
8
|
-
* - Supports both daily and hourly billing with adjusted quantities.
|
|
9
|
-
* - Automatically updates `billingDateAt` based on `dateAt` and `cutoffDate`.
|
|
10
|
-
* - Introduces a lock mechanism (`isLocked`) to prevent edits when necessary.
|
|
8
|
+
* ### ドキュメント更新前処理
|
|
9
|
+
* - 更新前および更新後の `isLocked` が true の場合は編集不可とします。(`isLocked` は `OperationBilling` クラスで更新されます。)
|
|
10
|
+
* - `groupKey` が変更された場合は `customerId` の同期と `agreement` の適用を行います。
|
|
11
11
|
*
|
|
12
|
-
* @
|
|
12
|
+
* @class
|
|
13
|
+
* @extends Operation
|
|
14
|
+
* @abstract
|
|
15
|
+
* @see OperationDetail
|
|
13
16
|
*
|
|
14
|
-
* @property {
|
|
15
|
-
*
|
|
16
|
-
* @property {string}
|
|
17
|
-
*
|
|
18
|
-
* @property {
|
|
19
|
-
* -
|
|
20
|
-
*
|
|
21
|
-
* @property {
|
|
22
|
-
* -
|
|
23
|
-
* -
|
|
24
|
-
* -
|
|
25
|
-
*
|
|
26
|
-
* @property {
|
|
27
|
-
* -
|
|
28
|
-
* @property {
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
* -
|
|
35
|
-
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
46
|
-
*
|
|
47
|
-
* @property {
|
|
48
|
-
*
|
|
49
|
-
* @property {
|
|
50
|
-
* @property {
|
|
51
|
-
*
|
|
52
|
-
* @property {
|
|
53
|
-
*
|
|
54
|
-
* @property {
|
|
55
|
-
*
|
|
56
|
-
* @property {
|
|
57
|
-
*
|
|
58
|
-
* @property {
|
|
59
|
-
*
|
|
60
|
-
* @property {
|
|
61
|
-
*
|
|
62
|
-
* @property {
|
|
63
|
-
* -
|
|
64
|
-
* -
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
* @
|
|
68
|
-
* @property {string}
|
|
69
|
-
*
|
|
70
|
-
*
|
|
71
|
-
*
|
|
72
|
-
*
|
|
73
|
-
*
|
|
74
|
-
*
|
|
75
|
-
* -
|
|
76
|
-
*
|
|
77
|
-
*
|
|
78
|
-
*
|
|
79
|
-
*
|
|
80
|
-
*
|
|
81
|
-
*
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
* -
|
|
87
|
-
* @property {
|
|
88
|
-
* -
|
|
89
|
-
*
|
|
90
|
-
*
|
|
91
|
-
*
|
|
92
|
-
*
|
|
93
|
-
* -
|
|
94
|
-
* -
|
|
95
|
-
* -
|
|
96
|
-
*
|
|
97
|
-
*
|
|
98
|
-
* -
|
|
99
|
-
* -
|
|
100
|
-
* -
|
|
101
|
-
*
|
|
102
|
-
*
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
106
|
-
*
|
|
107
|
-
* -
|
|
108
|
-
*
|
|
109
|
-
*
|
|
110
|
-
* @property {string} billingMonth - Billing month in YYYY-MM format (read-only)
|
|
111
|
-
* @property {Array<string>} employeeIds - Array of employee IDs from `employees` (read-only)
|
|
112
|
-
* @property {Array<string>} outsourcerIds - Array of outsourcer IDs from `outsourcers` (read-only)
|
|
113
|
-
* @property {number} employeesCount - Count of assigned employees (read-only)
|
|
114
|
-
* @property {number} outsourcersCount - Count of assigned outsourcers (sum of amounts) (read-only)
|
|
115
|
-
* @property {boolean} isPersonnelShortage - Indicates if there is a shortage of personnel (read-only)
|
|
116
|
-
* - `true` if the sum of `employeesCount` and `outsourcersCount` is less than `requiredPersonnel`
|
|
117
|
-
*
|
|
118
|
-
* @getter {string} groupKey - Combines `siteId`, `shiftType`, and `date` to indicate operation grouping (read-only)
|
|
119
|
-
* @getter {boolean} isEmployeesChanged - Indicates whether the employees have changed (read-only)
|
|
120
|
-
* - Returns true if the employee IDs have changed compared to `_beforeData`
|
|
121
|
-
* @getter {boolean} isOutsourcersChanged - Indicates whether the outsourcers have changed (read-only)
|
|
122
|
-
* - Returns true if the outsourcer IDs have changed compared to `_beforeData`
|
|
123
|
-
* @getter {Array<OperationResultDetail>} addedWorkers - An array of workers that have been added (read-only)
|
|
124
|
-
* - Workers that exist in current data but not in `_beforeData`
|
|
125
|
-
* @getter {Array<OperationResultDetail>} removedWorkers - An array of workers that have been removed (read-only)
|
|
126
|
-
* - Workers that exist in `_beforeData` but not in current data
|
|
127
|
-
* @getter {Array<OperationResultDetail>} updatedWorkers - An array of workers that have been updated (read-only)
|
|
128
|
-
* - Workers whose `startTime`, `isStartNextDay`, `endTime`, `breakMinutes`, `isQualified`, or `isOjt` have changed
|
|
129
|
-
* @getter {number} startHour - Start hour (0-23) (read-only)
|
|
130
|
-
* - Extracted from `startTime`.
|
|
131
|
-
* @getter {number} startMinute - Start minute (0-59) (read-only)
|
|
132
|
-
* - Extracted from `startTime`.
|
|
133
|
-
* @getter {number} endHour - End hour (0-23) (read-only)
|
|
134
|
-
* - Extracted from `endTime`.
|
|
135
|
-
* @getter {number} endMinute - End minute (0-59) (read-only)
|
|
136
|
-
* - Extracted from `endTime`.
|
|
137
|
-
* @getter {boolean} isKeyChanged - Flag indicating whether the key has changed compared to previous data (read-only)
|
|
138
|
-
* - Compares the current `key` with the `key` in `_beforeData`.
|
|
17
|
+
* @property {Date} dateAt - 日付 (変更されると `dayType` が自動的に更新されます)
|
|
18
|
+
* @property {string} shiftType - 勤務区分 (変更されると `employees` と `outsourcers` の `shiftType` が自動的に更新されます)
|
|
19
|
+
* @property {string} startTime - 開始時刻 (HH:MM 形式)
|
|
20
|
+
* @property {string} endTime - 終了時刻 (HH:MM 形式)
|
|
21
|
+
* @property {boolean} isStartNextDay - 翌日開始フラグ
|
|
22
|
+
* - `true` の場合、実際の勤務は `dateAt` の翌日であることを意味します。
|
|
23
|
+
* @property {number} breakMinutes - 休憩時間 (分)
|
|
24
|
+
* @property {string} date - `dateAt` に基づく YYYY-MM-DD 形式の日付文字列 (読み取り専用)
|
|
25
|
+
* - `dateAt` に基づいて YYYY-MM-DD 形式の文字列を返します。
|
|
26
|
+
* @property {Date} startAt - 開始日時 (Date オブジェクト) (読み取り専用)
|
|
27
|
+
* - `dateAt` に基づいて `startTime` を設定した Date オブジェクトを返します。
|
|
28
|
+
* - `isStartNextDay` が true の場合、1日加算します。
|
|
29
|
+
* @property {Date} endAt - 終了日時 (Date オブジェクト) (読み取り専用)
|
|
30
|
+
* - `startAt` を起点に、最初に現れる `endTime` の Date オブジェクトを返します。
|
|
31
|
+
* @property {boolean} isSpansNextDay - 翌日跨ぎフラグ (読み取り専用)
|
|
32
|
+
* - `true` の場合、`startAt` と `endAt` の日付が異なることを意味します。
|
|
33
|
+
* @property {number} regulationWorkMinutes - 規定労働時間 (分) (変更されると `employees` と `outsourcers` の `regulationWorkMinutes` が自動的に更新されます)
|
|
34
|
+
* - `startAt` から `endAt` までの時間から `breakMinutes` を差し引いた時間のうち、
|
|
35
|
+
* 規定内として扱う労働時間(分)です。
|
|
36
|
+
* - 実際の労働時間から残業時間を算出するための基準となる値です。
|
|
37
|
+
* - この値があることで、取極めに柔軟な設定を行うことが可能になる他、労働基準法の 1 日の所定労働時間上限が変更された際に
|
|
38
|
+
* 影響を最小限に抑えることができます。
|
|
39
|
+
* 例) 8:00 から 17:00 までの勤務で休憩が 60 分の場合
|
|
40
|
+
* - 規定労働時間を 8 時間 (480 分) とし、実際の勤務が 8 時間 (480 分) を超えた分が残業時間として扱われます。
|
|
41
|
+
* 例) 8:00 から 16:00 までの勤務で休憩が 60 分の場合
|
|
42
|
+
* - 規定労働時間を 7 時間 (420 分) とすると、実際の勤務が 7 時間 (420 分) を超えた分が残業時間として扱われます。
|
|
43
|
+
* - 規定労働時間を 8 時間 (480 分) とすると、実際の勤務が 8 時間 (480 分) を超えた分が残業時間として扱われます。
|
|
44
|
+
* 例) 7:00 から 翌日 7:00 までの勤務で休憩が 60 分の場合
|
|
45
|
+
* - 規定労働時間を 8 時間 (480 分) とすると、実際の勤務が 8 時間 (480 分) を超えた分が残業時間として扱われます。
|
|
46
|
+
* この場合、最初の 8 時間までは基本単価が適用され、残りの 8 時間は残業単価が適用されるといった設定が可能になります。
|
|
47
|
+
* - 規定労働時間を 24 時間 (1440 分) とすると、実際の勤務が 24 時間 (1440 分) を超えた分が残業時間として扱われます。
|
|
48
|
+
* この場合、全ての勤務時間が基本単価で扱われるといった設定が可能になります。
|
|
49
|
+
* @property {string} dayType - 曜日区分
|
|
50
|
+
* @property {number} totalWorkMinutes - 総労働時間 (休憩時間を除く) (分) (読み取り専用)
|
|
51
|
+
* @property {number} regularTimeWorkMinutes - 所定労働時間 (分) (読み取り専用)
|
|
52
|
+
* @property {number} overtimeWorkMinutes - 残業時間 (分) (読み取り専用)
|
|
53
|
+
* @property {string} siteId - 現場ID (変更されると `employees` と `outsourcers` の `siteId` が自動的に更新されます)
|
|
54
|
+
* @property {number} requiredPersonnel - 必要人数
|
|
55
|
+
* @property {boolean} qualificationRequired - 資格要件フラグ
|
|
56
|
+
* @property {string} workDescription - 作業内容
|
|
57
|
+
* @property {string} remarks - 備考
|
|
58
|
+
* @property {Array<OperationDetail>} employees - 従業員の OperationDetail インスタンスの配列
|
|
59
|
+
* @property {Array<OperationDetail>} outsourcers - 外注の OperationDetail インスタンスの配列
|
|
60
|
+
* @property {Array<string>} employeeIds - 従業員の ID の配列 (読み取り専用)
|
|
61
|
+
* @property {Array<string>} outsourcerIds - 外注の ID の配列 (読み取り専用)
|
|
62
|
+
* @property {number} employeesCount - `employees` の要素数 (読み取り専用)
|
|
63
|
+
* @property {number} outsourcersCount - `outsourcers` の要素数 (読み取り専用)
|
|
64
|
+
* @property {boolean} isPersonnelShortage - 人員不足フラグ (読み取り専用)
|
|
65
|
+
* @property {Array<OperationDetail>} workers - 従業員と外注を合わせた配列
|
|
66
|
+
* - `employees` と `outsourcers` を結合した配列を返します。
|
|
67
|
+
* - Getter: `employees` と `outsourcers` を結合した配列を返します。
|
|
68
|
+
* - Setter: 配列を `isEmployee` プロパティに基づいて `employees` と `outsourcers` に分割します。
|
|
69
|
+
* @property {string} groupKey - `siteId`, `shiftType`, `date` を組み合わせたキー。(読み取り専用)
|
|
70
|
+
* @property {string} agreementKey - `date`, `shiftType` を組み合わせたキー。(読み取り専用)
|
|
71
|
+
* @property {string} orderKey - `siteId`, `shiftType` を組み合わせたキー。(読み取り専用)
|
|
72
|
+
* @property {string|null} siteOperationScheduleId - 現場稼働予定ID
|
|
73
|
+
* - このプロパティは、OperationResult が現場稼働予定に紐づいている場合に、その現場稼働予定の ID を保持します。
|
|
74
|
+
* @property {boolean} useAdjustedQuantity - 請求に調整済み数量を使用するかどうかのフラグ
|
|
75
|
+
* @property {number} adjustedQuantityBase - 基本従業員の調整済み数量
|
|
76
|
+
* - `useAdjustedQuantity` が true の場合、基本従業員の請求に使用される数量です。
|
|
77
|
+
* @property {number} adjustedOvertimeBase - 基本従業員の調整済み残業時間
|
|
78
|
+
* - `useAdjustedQuantity` が true の場合、基本従業員の請求に使用される残業時間です。
|
|
79
|
+
* @property {number} adjustedQuantityQualified - 資格者の調整済み数量
|
|
80
|
+
* - `useAdjustedQuantity` が true の場合、資格者の請求に使用される数量です。
|
|
81
|
+
* @property {number} adjustedOvertimeQualified - 資格者の調整済み残業時間
|
|
82
|
+
* - `useAdjustedQuantity` が true の場合、資格者の請求に使用される残業時間です。
|
|
83
|
+
* @property {Date} billingDateAt - 請求日
|
|
84
|
+
* - 請求に使用される日付です。
|
|
85
|
+
* @property {boolean} isLocked - ロックフラグ
|
|
86
|
+
* - true の場合、OperationResult は OperationBilling として編集する場合を除き、編集できません。
|
|
87
|
+
* @property {Agreement|null} agreement - 関連する取極めオブジェクト
|
|
88
|
+
* - この OperationResult に関連付けられた取極めインスタンスで、価格設定や請求情報に使用されます。
|
|
89
|
+
* - 設定されている場合、単価や請求日などの計算に影響を与えます。
|
|
90
|
+
* @property {boolean} allowEmptyAgreement - 取極めが存在しない場合を許可するフラグ
|
|
91
|
+
* - true に設定されている場合、取極めが関連付けられていなくても OperationResult は有効と見なされます。
|
|
92
|
+
* @property {boolean} hasAgreement - 取極めが関連付けられているかどうかを示すフラグ (読み取り専用)
|
|
93
|
+
* - `agreement` が設定されている場合は `true`、それ以外の場合は `false`。
|
|
94
|
+
* @property {Object} statistics - 従業員の統計情報 (読み取り専用)
|
|
95
|
+
* - 基本従業員と資格者のカウントおよび総労働時間を含む統計情報。
|
|
96
|
+
* - 構造: { base: {...}, qualified: {...}, total: {...} }
|
|
97
|
+
* - 各カテゴリには以下が含まれます: quantity, regularTimeWorkMinutes, overtimeWorkMinutes, totalWorkMinutes, breakMinutes
|
|
98
|
+
* - 各カテゴリには 'ojt' サブカテゴリも同様の構造で含まれます。
|
|
99
|
+
* @property {Object} sales - 売上金額 (読み取り専用)
|
|
100
|
+
* - 基本従業員と資格者の売上計算を含む。
|
|
101
|
+
* - 構造: { base: {...}, qualified: {...} }
|
|
102
|
+
* - 各カテゴリには以下が含まれます: unitPrice, quantity, regularAmount, overtimeUnitPrice, overtimeMinutes, overtimeAmount, total
|
|
103
|
+
* - 計算は `useAdjustedQuantity`, `billingUnitType`, `includeBreakInBilling` の設定を考慮します。
|
|
104
|
+
* @property {number} salesAmount - 売上合計金額 (読み取り専用)
|
|
105
|
+
* - 基本従業員と資格者の売上金額の合計を返します。
|
|
106
|
+
* @property {number} tax - 計算された税額 (読み取り専用)
|
|
107
|
+
* - `salesAmount` と `date` に基づいて `Tax` ユーティリティを使用して計算されます。
|
|
108
|
+
* @property {number} billingAmount - 税込の請求金額 (読み取り専用)
|
|
109
|
+
* - `salesAmount` と `tax` の合計を返します。
|
|
110
|
+
* @property {string|null} billingDate - 請求日 (YYYY-MM-DD 形式) (読み取り専用)
|
|
111
|
+
* - `billingDateAt` に基づいて YYYY-MM-DD 形式の文字列を返します。
|
|
112
|
+
* @property {string} billingMonth - 請求月 (YYYY-MM 形式) (読み取り専用)
|
|
139
113
|
*
|
|
114
|
+
* @method setDateAtCallback - `dateAt` が設定されたときに呼び出されるコールバック関数
|
|
115
|
+
* @method addWorker - `Workers` に新しい従業員または外注先を追加します。
|
|
116
|
+
* @method moveWorker - 従業員または外注先の位置を移動します。
|
|
117
|
+
* @method changeWorker - 従業員または外注先の詳細を変更します。
|
|
118
|
+
* @method removeWorker - 従業員または外注先を `workers` から削除します。
|
|
119
|
+
* @method setSiteIdCallback - `siteId` が変更された時に呼び出されるコールバック関数
|
|
120
|
+
* @method setShiftTypeCallback - `shiftType` が変更された時に呼び出されるコールバック関数
|
|
121
|
+
* @method setRegulationWorkMinutesCallback - `regulationWorkMinutes` が変更された時に呼び出されるコールバック関数
|
|
140
122
|
* @method refreshBillingDateAt - Refresh billingDateAt based on dateAt and cutoffDate
|
|
141
123
|
* - Updates `billingDateAt` based on the current `dateAt` and `cutoffDate` values.
|
|
142
|
-
* @method addWorker - Adds a new worker (employee or outsourcer)
|
|
143
|
-
* - @param {Object} options - Options for adding a worker
|
|
144
|
-
* - @param {string} options.id - The worker ID (employeeId or outsourcerId)
|
|
145
|
-
* - @param {boolean} [options.isEmployee=true] - Whether the worker is an employee
|
|
146
|
-
* - @param {number} [index=0] - Insertion position. If -1, adds to the end
|
|
147
|
-
* @method moveWorker - Moves the position of a worker (employee or outsourcer)
|
|
148
|
-
* - @param {Object} options - Options for changing worker position
|
|
149
|
-
* - @param {number} options.oldIndex - The original index
|
|
150
|
-
* - @param {number} options.newIndex - The new index
|
|
151
|
-
* - @param {boolean} [options.isEmployee=true] - True for employee, false for outsourcer
|
|
152
|
-
* @method changeWorker - Changes the details of a worker
|
|
153
|
-
* - @param {Object} newWorker - New worker object
|
|
154
|
-
* @method removeWorker - Removes a worker (employee or outsourcer)
|
|
155
|
-
* - @param {Object} options - Options for removing a worker
|
|
156
|
-
* - @param {string} options.workerId - The ID of the employee or outsourcer
|
|
157
|
-
* - @param {boolean} [options.isEmployee=true] - True for employee, false for outsourcer
|
|
158
|
-
* @method setSiteIdCallback - Callback method called when `siteId` is set
|
|
159
|
-
* - Override this method in subclasses to add custom behavior when `siteId` changes.
|
|
160
|
-
* - By default, does nothing.
|
|
161
|
-
* - @param {string} v - The new `siteId` value
|
|
162
|
-
* @method setShiftTypeCallback - Callback method called when `shiftType` is set
|
|
163
|
-
* - Override this method in subclasses to add custom behavior when `shiftType` changes.
|
|
164
|
-
* - By default, does nothing.
|
|
165
|
-
* - @param {string} v - The new `shiftType` value
|
|
166
|
-
* @method setRegulationWorkMinutesCallback - Callback method called when `regulationWorkMinutes` is set
|
|
167
|
-
* - Override this method in subclasses to add custom behavior when `regulationWorkMinutes` changes.
|
|
168
|
-
* - By default, does nothing.
|
|
169
|
-
* - @param {number} v - The new `regulationWorkMinutes` value
|
|
170
124
|
*
|
|
171
|
-
* @
|
|
172
|
-
* @
|
|
173
|
-
*
|
|
174
|
-
*
|
|
175
|
-
*
|
|
176
|
-
*
|
|
125
|
+
* @getter {boolean} isInvalid - クラス特有のエラーが存在するかどうかを返すプロパティ
|
|
126
|
+
* @getter {Array<Object>} invalidReasons - エラーコード、メッセージ、多言語メッセージ、フィールド名を含む詳細情報の配列を返すプロパティ
|
|
127
|
+
* @getter {boolean} isGroupKeyChanged - `groupKey` プロパティが変更されたかどうかを返すプロパティ
|
|
128
|
+
* @getter {boolean} isAgreementKeyChanged - `agreementKey` プロパティが変更されたかどうかを返すプロパティ
|
|
129
|
+
* @getter {boolean} isEmployeesChanged - 従業員が変更されたかどうかを示すフラグ (読み取り専用)
|
|
130
|
+
* @getter {boolean} isOutsourcersChanged - 外注が変更されたかどうかを示すフラグ (読み取り専用)
|
|
131
|
+
* @getter {Array<OperationDetail>} addedWorkers - 追加された従業員の配列 (読み取り専用)
|
|
132
|
+
* @getter {Array<OperationDetail>} removedWorkers - 削除された従業員の配列 (読み取り専用)
|
|
133
|
+
* @getter {Array<OperationDetail>} updatedWorkers - 更新された従業員の配列 (読み取り専用)
|
|
177
134
|
*
|
|
178
|
-
* @
|
|
179
|
-
* @
|
|
180
|
-
*
|
|
181
|
-
*
|
|
182
|
-
* @
|
|
135
|
+
* @static SHIFT_TYPE - 勤務区分を定義する定数オブジェクト
|
|
136
|
+
* @static INVALID_REASON - クラス特有のエラーコードを定義する定数オブジェクト
|
|
137
|
+
* - `EMPTY_AGREEMENT`: 取極めが存在せず、`allowEmptyAgreement` が false の場合のエラーコード
|
|
138
|
+
* - `EMPTY_BILLING_DATE`: 請求日が存在しない場合のエラーコード
|
|
139
|
+
* @static DAY_TYPE - 曜日区分を定義する定数オブジェクト
|
|
140
|
+
* @static BILLING_UNIT_TYPE - 請求単位区分を定義する定数オブジェクト
|
|
141
|
+
*
|
|
142
|
+
* @static
|
|
143
|
+
* @method groupKeyDivider - `groupKey` を構成する要素を分割して返す静的メソッド
|
|
183
144
|
*****************************************************************************/
|
|
184
145
|
import Operation from "./Operation.js";
|
|
185
|
-
import
|
|
146
|
+
import AgreementV2 from "./AgreementV2.js";
|
|
186
147
|
import { ContextualError } from "./utils/ContextualError.js";
|
|
187
148
|
import OperationResultDetail from "./OperationResultDetail.js";
|
|
188
149
|
import { defField } from "./parts/fieldDefinitions.js";
|
|
150
|
+
import { formatJstDate } from "./utils/index.js";
|
|
189
151
|
import Tax from "./Tax.js";
|
|
190
152
|
import { VALUES as BILLING_UNIT_TYPE } from "./constants/billing-unit-type.js";
|
|
191
153
|
import RoundSetting from "./RoundSetting.js";
|
|
@@ -195,6 +157,14 @@ import Site from "./Site.js";
|
|
|
195
157
|
const classProps = {
|
|
196
158
|
...Operation.classProps,
|
|
197
159
|
siteOperationScheduleId: defField("oneLine", { hidden: true }),
|
|
160
|
+
/**
|
|
161
|
+
* `employees`, `outsourcers` は 継承元である `Operation` クラスで定義されているが、
|
|
162
|
+
* customClass が `OperationDetail` になっているため、`OperationResultDetail` で再定義する。
|
|
163
|
+
*/
|
|
164
|
+
employees: defField("array", { customClass: OperationResultDetail }),
|
|
165
|
+
outsourcers: defField("array", {
|
|
166
|
+
customClass: OperationResultDetail,
|
|
167
|
+
}),
|
|
198
168
|
useAdjustedQuantity: defField("check", {
|
|
199
169
|
label: "調整数量を使用",
|
|
200
170
|
default: false,
|
|
@@ -216,15 +186,11 @@ const classProps = {
|
|
|
216
186
|
default: 0,
|
|
217
187
|
}),
|
|
218
188
|
billingDateAt: defField("dateAt", { label: "請求締日" }),
|
|
219
|
-
employees: defField("array", { customClass: OperationResultDetail }),
|
|
220
|
-
outsourcers: defField("array", {
|
|
221
|
-
customClass: OperationResultDetail,
|
|
222
|
-
}),
|
|
223
189
|
isLocked: defField("check", {
|
|
224
190
|
label: "実績確定",
|
|
225
191
|
default: false,
|
|
226
192
|
}),
|
|
227
|
-
agreement: defField("object", { label: "取極め", customClass:
|
|
193
|
+
agreement: defField("object", { label: "取極め", customClass: AgreementV2 }),
|
|
228
194
|
allowEmptyAgreement: defField("check", {
|
|
229
195
|
label: "取極めなしを許容",
|
|
230
196
|
default: false,
|
|
@@ -238,11 +204,6 @@ const classProps = {
|
|
|
238
204
|
customerId: defField("customerId", { required: true, hidden: true }),
|
|
239
205
|
};
|
|
240
206
|
|
|
241
|
-
const INVALID_REASON = {
|
|
242
|
-
EMPTY_BILLING_DATE: "EMPTY_BILLING_DATE",
|
|
243
|
-
EMPTY_AGREEMENT: "EMPTY_AGREEMENT",
|
|
244
|
-
};
|
|
245
|
-
|
|
246
207
|
export default class OperationResult extends Operation {
|
|
247
208
|
static className = "稼働実績";
|
|
248
209
|
static collectionPath = "OperationResults";
|
|
@@ -250,12 +211,38 @@ export default class OperationResult extends Operation {
|
|
|
250
211
|
static logicalDelete = false;
|
|
251
212
|
static classProps = classProps;
|
|
252
213
|
|
|
214
|
+
static BILLING_UNIT_TYPE = BILLING_UNIT_TYPE;
|
|
215
|
+
|
|
216
|
+
/**
|
|
217
|
+
* INVALID_REASON
|
|
218
|
+
* - Operation クラスの INVALID_REASON を継承しています。
|
|
219
|
+
* - 以下のエラーコードを追加
|
|
220
|
+
* - `EMPTY_AGREEMENT`: 取極めが存在せず、`allowEmptyAgreement` が false の場合のエラーコード
|
|
221
|
+
* - `EMPTY_BILLING_DATE`: 請求日が存在しない場合のエラーコード
|
|
222
|
+
*/
|
|
223
|
+
static INVALID_REASON = {
|
|
224
|
+
...Operation.INVALID_REASON,
|
|
225
|
+
EMPTY_BILLING_DATE: {
|
|
226
|
+
code: "EMPTY_BILLING_DATE",
|
|
227
|
+
message: "Billing date is required.",
|
|
228
|
+
messages: {
|
|
229
|
+
ja: "請求締日は必須です。",
|
|
230
|
+
},
|
|
231
|
+
},
|
|
232
|
+
EMPTY_AGREEMENT: {
|
|
233
|
+
code: "EMPTY_AGREEMENT",
|
|
234
|
+
message: "Agreement is required.",
|
|
235
|
+
messages: {
|
|
236
|
+
ja: "取極めは必須です。",
|
|
237
|
+
},
|
|
238
|
+
},
|
|
239
|
+
};
|
|
240
|
+
|
|
253
241
|
static headers = [
|
|
254
242
|
{ title: "日付", key: "dateAt" },
|
|
255
243
|
{ title: "現場", key: "siteId", value: "siteId" },
|
|
256
244
|
];
|
|
257
245
|
|
|
258
|
-
static BILLING_UNIT_TYPE = BILLING_UNIT_TYPE;
|
|
259
246
|
/**
|
|
260
247
|
* afterInitialize
|
|
261
248
|
*/
|
|
@@ -264,6 +251,19 @@ export default class OperationResult extends Operation {
|
|
|
264
251
|
|
|
265
252
|
/** Computed properties */
|
|
266
253
|
Object.defineProperties(this, {
|
|
254
|
+
/**
|
|
255
|
+
* hasAgreement
|
|
256
|
+
* - getter 定義でも良いが、Firestore のクエリで使用する可能性があるため、
|
|
257
|
+
* Object.defineProperty で列挙可能プロパティとして定義する。
|
|
258
|
+
*/
|
|
259
|
+
hasAgreement: {
|
|
260
|
+
configurable: true,
|
|
261
|
+
enumerable: true,
|
|
262
|
+
get() {
|
|
263
|
+
return this.agreement != null;
|
|
264
|
+
},
|
|
265
|
+
set(v) {},
|
|
266
|
+
},
|
|
267
267
|
statistics: {
|
|
268
268
|
configurable: true,
|
|
269
269
|
enumerable: true,
|
|
@@ -323,6 +323,7 @@ export default class OperationResult extends Operation {
|
|
|
323
323
|
const calculateCategorySales = (category) => {
|
|
324
324
|
const isQualified = category === "qualified";
|
|
325
325
|
const categoryStats = this.statistics?.[category];
|
|
326
|
+
const rateSet = this.agreement?.rates?.[this.dayType];
|
|
326
327
|
|
|
327
328
|
// 統計データが存在しない場合は警告を出力して初期値を返す
|
|
328
329
|
if (!categoryStats) {
|
|
@@ -334,7 +335,7 @@ export default class OperationResult extends Operation {
|
|
|
334
335
|
siteId: this.siteId,
|
|
335
336
|
category,
|
|
336
337
|
statistics: this.statistics,
|
|
337
|
-
}
|
|
338
|
+
},
|
|
338
339
|
);
|
|
339
340
|
return createInitialValues();
|
|
340
341
|
}
|
|
@@ -374,19 +375,33 @@ export default class OperationResult extends Operation {
|
|
|
374
375
|
|
|
375
376
|
// agreementがある場合のみ単価と金額を計算
|
|
376
377
|
if (this.agreement) {
|
|
378
|
+
if (!rateSet) {
|
|
379
|
+
console.warn(
|
|
380
|
+
`[OperationResult] AgreementV2.rates for dayType '${this.dayType}' is missing.`,
|
|
381
|
+
{
|
|
382
|
+
docId: this.docId,
|
|
383
|
+
dateAt: this.dateAt,
|
|
384
|
+
siteId: this.siteId,
|
|
385
|
+
dayType: this.dayType,
|
|
386
|
+
agreement: this.agreement,
|
|
387
|
+
},
|
|
388
|
+
);
|
|
389
|
+
return result;
|
|
390
|
+
}
|
|
391
|
+
|
|
377
392
|
result.unitPrice = isQualified
|
|
378
|
-
?
|
|
379
|
-
:
|
|
393
|
+
? rateSet.unitPriceQualified || 0
|
|
394
|
+
: rateSet.unitPriceBase || 0;
|
|
380
395
|
result.overtimeUnitPrice = isQualified
|
|
381
|
-
?
|
|
382
|
-
:
|
|
396
|
+
? rateSet.overtimeUnitPriceQualified || 0
|
|
397
|
+
: rateSet.overtimeUnitPriceBase || 0;
|
|
383
398
|
|
|
384
399
|
// 金額計算(RoundSettingを適用)
|
|
385
400
|
result.regularAmount = RoundSetting.apply(
|
|
386
|
-
result.quantity * result.unitPrice
|
|
401
|
+
result.quantity * result.unitPrice,
|
|
387
402
|
);
|
|
388
403
|
result.overtimeAmount = RoundSetting.apply(
|
|
389
|
-
(result.overtimeMinutes * result.overtimeUnitPrice) / 60
|
|
404
|
+
(result.overtimeMinutes * result.overtimeUnitPrice) / 60,
|
|
390
405
|
);
|
|
391
406
|
result.total = result.regularAmount + result.overtimeAmount;
|
|
392
407
|
}
|
|
@@ -438,16 +453,7 @@ export default class OperationResult extends Operation {
|
|
|
438
453
|
configurable: true,
|
|
439
454
|
enumerable: true,
|
|
440
455
|
get() {
|
|
441
|
-
|
|
442
|
-
const jstDate = new Date(
|
|
443
|
-
this.billingDateAt.getTime() + 9 * 60 * 60 * 1000
|
|
444
|
-
); /* JST補正 */
|
|
445
|
-
const year = jstDate.getUTCFullYear();
|
|
446
|
-
const month = jstDate.getUTCMonth() + 1;
|
|
447
|
-
const day = jstDate.getUTCDate();
|
|
448
|
-
return `${year}-${String(month).padStart(2, "0")}-${String(
|
|
449
|
-
day
|
|
450
|
-
).padStart(2, "0")}`;
|
|
456
|
+
return formatJstDate(this.billingDateAt);
|
|
451
457
|
},
|
|
452
458
|
set(v) {},
|
|
453
459
|
},
|
|
@@ -455,35 +461,7 @@ export default class OperationResult extends Operation {
|
|
|
455
461
|
configurable: true,
|
|
456
462
|
enumerable: true,
|
|
457
463
|
get() {
|
|
458
|
-
|
|
459
|
-
const jstDate = new Date(
|
|
460
|
-
this.billingDateAt.getTime() + 9 * 60 * 60 * 1000
|
|
461
|
-
); /* JST補正 */
|
|
462
|
-
const year = jstDate.getUTCFullYear();
|
|
463
|
-
const month = jstDate.getUTCMonth() + 1;
|
|
464
|
-
return `${year}-${String(month).padStart(2, "0")}`;
|
|
465
|
-
},
|
|
466
|
-
set(v) {},
|
|
467
|
-
},
|
|
468
|
-
hasAgreement: {
|
|
469
|
-
configurable: true,
|
|
470
|
-
enumerable: true,
|
|
471
|
-
get() {
|
|
472
|
-
return this.agreement != null;
|
|
473
|
-
},
|
|
474
|
-
set(v) {},
|
|
475
|
-
},
|
|
476
|
-
isInvalid: {
|
|
477
|
-
configurable: true,
|
|
478
|
-
enumerable: true,
|
|
479
|
-
get() {
|
|
480
|
-
if (!this.agreement && !this.allowEmptyAgreement) {
|
|
481
|
-
return INVALID_REASON.EMPTY_AGREEMENT;
|
|
482
|
-
}
|
|
483
|
-
if (!this.billingDateAt) {
|
|
484
|
-
return INVALID_REASON.EMPTY_BILLING_DATE;
|
|
485
|
-
}
|
|
486
|
-
return false;
|
|
464
|
+
return formatJstDate(this.billingDateAt, "YYYY-MM");
|
|
487
465
|
},
|
|
488
466
|
set(v) {},
|
|
489
467
|
},
|
|
@@ -529,7 +507,7 @@ export default class OperationResult extends Operation {
|
|
|
529
507
|
}
|
|
530
508
|
this.billingDateAt = CutoffDate.calculateBillingDateAt(
|
|
531
509
|
this.dateAt,
|
|
532
|
-
this.agreement.cutoffDate
|
|
510
|
+
this.agreement.cutoffDate,
|
|
533
511
|
);
|
|
534
512
|
}
|
|
535
513
|
|
|
@@ -557,16 +535,17 @@ export default class OperationResult extends Operation {
|
|
|
557
535
|
docId: this.siteId,
|
|
558
536
|
});
|
|
559
537
|
if (!siteExists) {
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
);
|
|
538
|
+
const message = `[OperationResult.js] The specified siteId (${this.siteId}) does not exist.`;
|
|
539
|
+
throw new Error(message);
|
|
563
540
|
}
|
|
564
541
|
this.customerId = siteInstance.customerId;
|
|
565
|
-
this.agreement = siteInstance.getAgreement(this);
|
|
542
|
+
// this.agreement = siteInstance.getAgreement(this);
|
|
543
|
+
this.agreement = siteInstance.getValidAgreement(this);
|
|
566
544
|
}
|
|
567
545
|
|
|
568
546
|
/**
|
|
569
|
-
*
|
|
547
|
+
* ドキュメント作成前処理
|
|
548
|
+
* - siteId から customerId を同期し、agreement を適用する。
|
|
570
549
|
* @param {Object} args - Creation options.
|
|
571
550
|
* @param {string} [args.docId] - Document ID to use (optional).
|
|
572
551
|
* @param {boolean} [args.useAutonumber=true] - Whether to use auto-numbering.
|
|
@@ -583,7 +562,9 @@ export default class OperationResult extends Operation {
|
|
|
583
562
|
}
|
|
584
563
|
|
|
585
564
|
/**
|
|
586
|
-
*
|
|
565
|
+
* ドキュメント更新前処理
|
|
566
|
+
* - 更新前および更新後の `isLocked` が true の場合は編集不可とする。
|
|
567
|
+
* - `groupKey` が変更された場合は `customerId` の同期と `agreement` の適用を行う。
|
|
587
568
|
* @param {Object} args - Creation options.
|
|
588
569
|
* @param {Object} [args.transaction] - Firestore transaction.
|
|
589
570
|
* @param {Function} [args.callBack] - Callback function.
|
|
@@ -593,20 +574,16 @@ export default class OperationResult extends Operation {
|
|
|
593
574
|
async beforeUpdate(args = {}) {
|
|
594
575
|
await super.beforeUpdate(args);
|
|
595
576
|
|
|
596
|
-
//
|
|
597
|
-
if (this.isLocked) {
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
);
|
|
577
|
+
// 更新前および更新後の `isLocked` が true の場合は編集不可とする。
|
|
578
|
+
if (this._beforeData.isLocked && this.isLocked) {
|
|
579
|
+
const message = `[OperationResult.js] This OperationResult (docId: ${this.docId}) is locked and cannot be edited.`;
|
|
580
|
+
throw new Error(message);
|
|
601
581
|
}
|
|
602
582
|
|
|
603
|
-
//
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
// if (this.key === this._beforeData.key) return;
|
|
608
|
-
if (this.agreementKey === this._beforeData.agreementKey) return;
|
|
609
|
-
await this._syncCustomerIdAndApplyAgreement();
|
|
583
|
+
// groupKeyが変更された場合はcustomerIdの同期とagreementの適用を行う
|
|
584
|
+
if (this.isGroupKeyChanged) {
|
|
585
|
+
await this._syncCustomerIdAndApplyAgreement();
|
|
586
|
+
}
|
|
610
587
|
}
|
|
611
588
|
|
|
612
589
|
/**
|
|
@@ -620,11 +597,37 @@ export default class OperationResult extends Operation {
|
|
|
620
597
|
*/
|
|
621
598
|
async beforeDelete(args = {}) {
|
|
622
599
|
await super.beforeDelete(args);
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
);
|
|
600
|
+
|
|
601
|
+
// 更新前および更新後の `isLocked` が true の場合は削除不可とする。
|
|
602
|
+
if (this._beforeData.isLocked && this.isLocked) {
|
|
603
|
+
const message = `[OperationResult.js] This OperationResult (docId: ${this.docId}) is locked and cannot be deleted.`;
|
|
604
|
+
throw new Error(message);
|
|
628
605
|
}
|
|
629
606
|
}
|
|
607
|
+
|
|
608
|
+
/**
|
|
609
|
+
* クラス特有のエラーを詳細情報付きで返す内部メソッド
|
|
610
|
+
* - `agreement` が存在せず、`allowEmptyAgreement` が false の場合、`EMPTY_AGREEMENT` エラーを返します。
|
|
611
|
+
* - `billingDateAt` が存在しない場合、`EMPTY_BILLING_DATE` エラーを返します。
|
|
612
|
+
* @returns {Array<Object>} エラー詳細オブジェクトの配列(統一フォーマット)
|
|
613
|
+
*/
|
|
614
|
+
_getInvalidReasons() {
|
|
615
|
+
const result = super._getInvalidReasons();
|
|
616
|
+
|
|
617
|
+
if (!this.agreement && !this.allowEmptyAgreement) {
|
|
618
|
+
result.push({
|
|
619
|
+
...OperationResult.INVALID_REASON.EMPTY_AGREEMENT,
|
|
620
|
+
field: "agreement",
|
|
621
|
+
});
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
if (!this.billingDateAt) {
|
|
625
|
+
result.push({
|
|
626
|
+
...OperationResult.INVALID_REASON.EMPTY_BILLING_DATE,
|
|
627
|
+
field: "billingDateAt",
|
|
628
|
+
});
|
|
629
|
+
}
|
|
630
|
+
|
|
631
|
+
return result;
|
|
632
|
+
}
|
|
630
633
|
}
|