@shisyamo4131/air-guard-v2-schemas 2.3.7-dev.4 → 2.3.7-dev.40
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 +2 -0
- package/package.json +1 -1
- package/src/Certification.js +49 -0
- package/src/Company.js +27 -1
- package/src/Customer.js +50 -36
- package/src/Employee.js +383 -58
- package/src/OperationBilling.js +28 -14
- package/src/OperationResult.js +29 -10
- package/src/Site.js +45 -9
- package/src/SiteOperationSchedule.js +27 -20
- package/src/System.js +43 -0
- package/src/apis/index.js +4 -0
- package/src/constants/blood-type.js +14 -0
- package/src/constants/certification-type.js +34 -0
- package/src/constants/emergency-contact-relation.js +16 -0
- package/src/constants/index.js +12 -0
- package/src/parts/accessorDefinitions.js +13 -27
- package/src/parts/fieldDefinitions.js +135 -3
package/src/Employee.js
CHANGED
|
@@ -6,7 +6,9 @@
|
|
|
6
6
|
import FireModel from "@shisyamo4131/air-firebase-v2";
|
|
7
7
|
import { defField } from "./parts/fieldDefinitions.js";
|
|
8
8
|
import { defAccessor } from "./parts/accessorDefinitions.js";
|
|
9
|
-
import { VALUES } from "./constants/employment-status.js";
|
|
9
|
+
import { VALUES as EMPLOYMENT_STATUS_VALUES } from "./constants/employment-status.js";
|
|
10
|
+
import { VALUES as BLOOD_TYPE_VALUES } from "./constants/blood-type.js";
|
|
11
|
+
import Certification from "./Certification.js";
|
|
10
12
|
|
|
11
13
|
const classProps = {
|
|
12
14
|
code: defField("code", { label: "従業員コード" }),
|
|
@@ -15,92 +17,204 @@ const classProps = {
|
|
|
15
17
|
lastNameKana: defField("lastNameKana", { required: true }),
|
|
16
18
|
firstNameKana: defField("firstNameKana", { required: true }),
|
|
17
19
|
displayName: defField("displayName", { required: true }),
|
|
18
|
-
title: defField("oneLine", { label: "肩書", required: true }),
|
|
19
20
|
gender: defField("gender", { required: true }),
|
|
20
|
-
dateOfBirth: defField("
|
|
21
|
+
dateOfBirth: defField("dateOfBirth", { required: true }),
|
|
21
22
|
zipcode: defField("zipcode", { required: true }),
|
|
22
23
|
prefCode: defField("prefCode", { required: true }),
|
|
23
24
|
city: defField("city", { required: true }),
|
|
24
25
|
address: defField("address", { required: true }),
|
|
25
26
|
building: defField("building"),
|
|
26
|
-
location: defField("location", { hidden: true }),
|
|
27
|
-
|
|
27
|
+
location: defField("location", { hidden: true }),
|
|
28
|
+
mobile: defField("mobile", { required: true }),
|
|
29
|
+
email: defField("email", { required: false }),
|
|
30
|
+
dateOfHire: defField("dateOfHire", { required: true }),
|
|
28
31
|
employmentStatus: defField("employmentStatus", { required: true }),
|
|
29
|
-
|
|
30
|
-
|
|
32
|
+
title: defField("title"),
|
|
33
|
+
dateOfTermination: defField("dateOfTermination", {
|
|
34
|
+
default: null,
|
|
35
|
+
component: {
|
|
36
|
+
attrs: {
|
|
37
|
+
required: ({ item }) =>
|
|
38
|
+
item.employmentStatus === EMPLOYMENT_STATUS_VALUES.TERMINATED.value,
|
|
39
|
+
disabled: ({ item }) =>
|
|
40
|
+
item.employmentStatus !== EMPLOYMENT_STATUS_VALUES.TERMINATED.value,
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
}),
|
|
44
|
+
reasonOfTermination: defField("reasonOfTermination", {
|
|
31
45
|
component: {
|
|
32
46
|
attrs: {
|
|
33
|
-
required: (item) =>
|
|
47
|
+
required: ({ item }) =>
|
|
48
|
+
item.employmentStatus === EMPLOYMENT_STATUS_VALUES.TERMINATED.value,
|
|
49
|
+
disabled: ({ item }) =>
|
|
50
|
+
item.employmentStatus !== EMPLOYMENT_STATUS_VALUES.TERMINATED.value,
|
|
34
51
|
},
|
|
35
52
|
},
|
|
36
53
|
}),
|
|
54
|
+
|
|
55
|
+
// Foreign related fields
|
|
37
56
|
isForeigner: defField("isForeigner"),
|
|
38
57
|
foreignName: defField("foreignName", {
|
|
39
58
|
component: {
|
|
40
59
|
attrs: {
|
|
41
|
-
required: (item) => item.isForeigner,
|
|
60
|
+
required: ({ item }) => item.isForeigner,
|
|
61
|
+
disabled: ({ item }) => !item.isForeigner,
|
|
42
62
|
},
|
|
43
63
|
},
|
|
44
64
|
}),
|
|
45
65
|
nationality: defField("nationality", {
|
|
46
66
|
component: {
|
|
47
67
|
attrs: {
|
|
48
|
-
required: (item) => item.isForeigner,
|
|
68
|
+
required: ({ item }) => item.isForeigner,
|
|
69
|
+
disabled: ({ item }) => !item.isForeigner,
|
|
49
70
|
},
|
|
50
71
|
},
|
|
51
72
|
}),
|
|
52
|
-
residenceStatus: {
|
|
53
|
-
|
|
73
|
+
residenceStatus: defField("residenceStatus", {
|
|
74
|
+
component: {
|
|
75
|
+
attrs: {
|
|
76
|
+
required: ({ item }) => item.isForeigner,
|
|
77
|
+
disabled: ({ item }) => !item.isForeigner,
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
}),
|
|
81
|
+
periodOfStay: defField("periodOfStay", {
|
|
82
|
+
component: {
|
|
83
|
+
attrs: {
|
|
84
|
+
required: ({ item }) => item.isForeigner,
|
|
85
|
+
disabled: ({ item }) => !item.isForeigner,
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
}),
|
|
89
|
+
|
|
90
|
+
// Security guard related fields
|
|
91
|
+
hasSecurityGuardRegistration: defField("check", { label: "警備員登録" }),
|
|
92
|
+
dateOfSecurityGuardRegistration: defField("dateAt", {
|
|
93
|
+
label: "警備員登録日",
|
|
54
94
|
default: null,
|
|
55
|
-
label: "在留資格",
|
|
56
|
-
required: undefined,
|
|
57
95
|
component: {
|
|
58
|
-
name: "air-text-field",
|
|
59
96
|
attrs: {
|
|
60
|
-
required: (item) => item.
|
|
97
|
+
required: ({ item }) => item.hasSecurityGuardRegistration,
|
|
98
|
+
disabled: ({ item }) => !item.hasSecurityGuardRegistration,
|
|
99
|
+
},
|
|
100
|
+
},
|
|
101
|
+
}),
|
|
102
|
+
bloodType: defField("bloodType", {
|
|
103
|
+
component: {
|
|
104
|
+
attrs: {
|
|
105
|
+
required: ({ item }) => item.hasSecurityGuardRegistration,
|
|
106
|
+
disabled: ({ item }) => !item.hasSecurityGuardRegistration,
|
|
61
107
|
},
|
|
62
108
|
},
|
|
63
|
-
},
|
|
64
|
-
|
|
65
|
-
|
|
109
|
+
}),
|
|
110
|
+
emergencyContactName: defField("emergencyContactName", {
|
|
111
|
+
component: {
|
|
112
|
+
attrs: {
|
|
113
|
+
required: ({ item }) => item.hasSecurityGuardRegistration,
|
|
114
|
+
disabled: ({ item }) => !item.hasSecurityGuardRegistration,
|
|
115
|
+
},
|
|
116
|
+
},
|
|
117
|
+
}),
|
|
118
|
+
emergencyContactRelation: defField("emergencyContactRelation", {
|
|
66
119
|
component: {
|
|
67
120
|
attrs: {
|
|
68
|
-
required: (item) => item.
|
|
121
|
+
required: ({ item }) => item.hasSecurityGuardRegistration,
|
|
122
|
+
disabled: ({ item }) => !item.hasSecurityGuardRegistration,
|
|
69
123
|
},
|
|
70
124
|
},
|
|
71
125
|
}),
|
|
72
|
-
|
|
126
|
+
emergencyContactRelationDetail: defField("emergencyContactRelationDetail", {
|
|
127
|
+
component: {
|
|
128
|
+
attrs: {
|
|
129
|
+
required: ({ item }) => item.hasSecurityGuardRegistration,
|
|
130
|
+
disabled: ({ item }) => !item.hasSecurityGuardRegistration,
|
|
131
|
+
},
|
|
132
|
+
},
|
|
133
|
+
}),
|
|
134
|
+
emergencyContactAddress: defField("emergencyContactAddress", {
|
|
135
|
+
component: {
|
|
136
|
+
attrs: {
|
|
137
|
+
required: ({ item }) => item.hasSecurityGuardRegistration,
|
|
138
|
+
disabled: ({ item }) => !item.hasSecurityGuardRegistration,
|
|
139
|
+
},
|
|
140
|
+
},
|
|
141
|
+
}),
|
|
142
|
+
emergencyContactPhone: defField("emergencyContactPhone", {
|
|
143
|
+
component: {
|
|
144
|
+
attrs: {
|
|
145
|
+
required: ({ item }) => item.hasSecurityGuardRegistration,
|
|
146
|
+
disabled: ({ item }) => !item.hasSecurityGuardRegistration,
|
|
147
|
+
},
|
|
148
|
+
},
|
|
149
|
+
}),
|
|
150
|
+
domicile: defField("domicile", {
|
|
151
|
+
component: {
|
|
152
|
+
attrs: {
|
|
153
|
+
required: ({ item }) => item.hasSecurityGuardRegistration,
|
|
154
|
+
disabled: ({ item }) => !item.hasSecurityGuardRegistration,
|
|
155
|
+
},
|
|
156
|
+
},
|
|
157
|
+
}),
|
|
158
|
+
securityCertifications: defField("array", {
|
|
159
|
+
label: "保有資格",
|
|
160
|
+
customClass: Certification,
|
|
161
|
+
}),
|
|
162
|
+
remarks: defField("remarks"),
|
|
73
163
|
};
|
|
74
164
|
|
|
75
165
|
/*****************************************************************************
|
|
76
|
-
* Employee
|
|
77
|
-
* @
|
|
78
|
-
* @
|
|
79
|
-
* @
|
|
80
|
-
* @
|
|
81
|
-
* @
|
|
82
|
-
* @
|
|
83
|
-
* @
|
|
84
|
-
* @
|
|
85
|
-
* @
|
|
86
|
-
* @
|
|
87
|
-
* @
|
|
88
|
-
* @
|
|
89
|
-
* @
|
|
90
|
-
* @
|
|
91
|
-
* @
|
|
92
|
-
* @
|
|
93
|
-
* @
|
|
94
|
-
* @
|
|
95
|
-
* @
|
|
96
|
-
* @
|
|
97
|
-
* @
|
|
98
|
-
* @
|
|
99
|
-
* @
|
|
100
|
-
* @
|
|
101
|
-
* @
|
|
102
|
-
* @
|
|
103
|
-
* @
|
|
166
|
+
* @prop {string} code - Employee code.
|
|
167
|
+
* @prop {string} lastName - Last name.
|
|
168
|
+
* @prop {string} firstName - First name.
|
|
169
|
+
* @prop {string} lastNameKana - Last name in Kana.
|
|
170
|
+
* @prop {string} firstNameKana - First name in Kana.
|
|
171
|
+
* @prop {string} displayName - Display name.
|
|
172
|
+
* @prop {string} gender - Gender.
|
|
173
|
+
* @prop {Date} dateOfBirth - Date of birth.
|
|
174
|
+
* @prop {string} zipcode - Postal code.
|
|
175
|
+
* @prop {string} prefCode - Prefecture code.
|
|
176
|
+
* @prop {string} city - City name.
|
|
177
|
+
* @prop {string} address - Address details.
|
|
178
|
+
* @prop {string} building - Building name.
|
|
179
|
+
* @prop {object} location - Geographical location.
|
|
180
|
+
* @prop {string} mobile - Mobile phone number.
|
|
181
|
+
* @prop {string} email - Email address.
|
|
182
|
+
* @prop {Date} dateOfHire - Date of hire.
|
|
183
|
+
* @prop {string} employmentStatus - Employment status.
|
|
184
|
+
* @prop {string} title - Job title.
|
|
185
|
+
* @prop {Date} dateOfTermination - Date of termination.
|
|
186
|
+
* @prop {string} reasonOfTermination - Reason for termination.
|
|
187
|
+
* @prop {boolean} isForeigner - Is the employee a foreigner.
|
|
188
|
+
* @prop {string} foreignName - Foreign name.
|
|
189
|
+
* @prop {string} nationality - Nationality.
|
|
190
|
+
* @prop {string} residenceStatus - Residence status.
|
|
191
|
+
* @prop {Date} periodOfStay - Period of stay expiration date.
|
|
192
|
+
* @prop {boolean} hasSecurityGuardRegistration - Has security guard registration.
|
|
193
|
+
* @prop {Date} dateOfSecurityGuardRegistration - Date of security guard registration.
|
|
194
|
+
* @prop {string} bloodType - Blood type.
|
|
195
|
+
* @prop {string} emergencyContactName - Emergency contact name.
|
|
196
|
+
* @prop {string} emergencyContactRelation - Emergency contact relation.
|
|
197
|
+
* @prop {string} emergencyContactRelationDetail - Emergency contact relation detail.
|
|
198
|
+
* @prop {string} emergencyContactAddress - Emergency contact address.
|
|
199
|
+
* @prop {string} emergencyContactPhone - Emergency contact phone number.
|
|
200
|
+
* @prop {string} domicile - Domicile.
|
|
201
|
+
* @prop {Array<Certification>} securityCertifications - Array of security certifications.
|
|
202
|
+
* @prop {string} remarks - Additional remarks.
|
|
203
|
+
*
|
|
204
|
+
* @prop {string} fullName - Full name combining last and first names (read-only)
|
|
205
|
+
* @prop {string} fullNameKana - Full name in Kana combining last and first names (read-only)
|
|
206
|
+
* @prop {string} fullAddress - Full address combining prefecture, city, and address (read-only)
|
|
207
|
+
* @prop {string} prefecture - Prefecture name derived from `prefCode` (read-only)
|
|
208
|
+
*
|
|
209
|
+
* @getter
|
|
210
|
+
* @prop {number} age - Age calculated from `dateOfBirth` (read-only)
|
|
211
|
+
* @prop {number} yearsOfService - Years of service calculated from `dateOfHire` (read-only)
|
|
212
|
+
*
|
|
213
|
+
* @static
|
|
214
|
+
* @prop {string} STATUS_ACTIVE - constant for active employment status
|
|
215
|
+
* @prop {string} STATUS_TERMINATED - constant for terminated employment status
|
|
216
|
+
*
|
|
217
|
+
* @function toTerminated - Change the current employee instance to terminated status.
|
|
104
218
|
*****************************************************************************/
|
|
105
219
|
export default class Employee extends FireModel {
|
|
106
220
|
static className = "従業員";
|
|
@@ -109,6 +223,7 @@ export default class Employee extends FireModel {
|
|
|
109
223
|
static logicalDelete = true;
|
|
110
224
|
static classProps = classProps;
|
|
111
225
|
static tokenFields = [
|
|
226
|
+
"code",
|
|
112
227
|
"lastName",
|
|
113
228
|
"firstName",
|
|
114
229
|
"lastNameKana",
|
|
@@ -122,21 +237,90 @@ export default class Employee extends FireModel {
|
|
|
122
237
|
{ title: "名前", key: "fullName" },
|
|
123
238
|
];
|
|
124
239
|
|
|
125
|
-
static STATUS_ACTIVE =
|
|
126
|
-
static STATUS_TERMINATED =
|
|
240
|
+
static STATUS_ACTIVE = EMPLOYMENT_STATUS_VALUES.ACTIVE.value;
|
|
241
|
+
static STATUS_TERMINATED = EMPLOYMENT_STATUS_VALUES.TERMINATED.value;
|
|
242
|
+
|
|
243
|
+
constructor(item = {}) {
|
|
244
|
+
super(item);
|
|
245
|
+
|
|
246
|
+
// Internal flag to skip terminated status check during toTerminated method
|
|
247
|
+
Object.defineProperty(this, "_skipToTerminatedCheck", {
|
|
248
|
+
writable: true,
|
|
249
|
+
enumerable: false,
|
|
250
|
+
configurable: true,
|
|
251
|
+
value: false,
|
|
252
|
+
});
|
|
253
|
+
}
|
|
127
254
|
|
|
128
255
|
afterInitialize(item = {}) {
|
|
129
256
|
super.afterInitialize(item);
|
|
130
257
|
Object.defineProperties(this, {
|
|
131
258
|
fullName: defAccessor("fullName"),
|
|
259
|
+
fullNameKana: defAccessor("fullNameKana"),
|
|
132
260
|
fullAddress: defAccessor("fullAddress"),
|
|
133
261
|
prefecture: defAccessor("prefecture"),
|
|
134
262
|
});
|
|
135
263
|
}
|
|
136
264
|
|
|
265
|
+
/**
|
|
266
|
+
* 生年月日から年齢を計算します。
|
|
267
|
+
* @returns {{years: number, months: number}|null} 年齢(年数と月数)。dateOfBirthが設定されていない場合はnull。
|
|
268
|
+
*/
|
|
269
|
+
get age() {
|
|
270
|
+
if (!this.dateOfBirth) return null;
|
|
271
|
+
const today = new Date();
|
|
272
|
+
|
|
273
|
+
let years = today.getUTCFullYear() - this.dateOfBirth.getUTCFullYear();
|
|
274
|
+
let months = today.getUTCMonth() - this.dateOfBirth.getUTCMonth();
|
|
275
|
+
const days = today.getUTCDate() - this.dateOfBirth.getUTCDate();
|
|
276
|
+
|
|
277
|
+
if (days < 0) {
|
|
278
|
+
months--;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
if (months < 0) {
|
|
282
|
+
years--;
|
|
283
|
+
months += 12;
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
return { years, months };
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
/**
|
|
290
|
+
* 入社日からの勤続年数を計算します。
|
|
291
|
+
* - 退職日が設定されている場合は、退職日までの勤続年数を計算します。
|
|
292
|
+
* @returns {{years: number, months: number}|null} 勤続年数(年数と月数)。dateOfHireが設定されていない場合はnull。
|
|
293
|
+
*/
|
|
294
|
+
get yearsOfService() {
|
|
295
|
+
if (!this.dateOfHire) return null;
|
|
296
|
+
const today = this.dateOfTermination || new Date();
|
|
297
|
+
|
|
298
|
+
let years = today.getUTCFullYear() - this.dateOfHire.getUTCFullYear();
|
|
299
|
+
let months = today.getUTCMonth() - this.dateOfHire.getUTCMonth();
|
|
300
|
+
const days = today.getUTCDate() - this.dateOfHire.getUTCDate();
|
|
301
|
+
|
|
302
|
+
if (days < 0) {
|
|
303
|
+
months--;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
if (months < 0) {
|
|
307
|
+
years--;
|
|
308
|
+
months += 12;
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
return { years, months };
|
|
312
|
+
}
|
|
313
|
+
|
|
137
314
|
/**
|
|
138
315
|
* 外国籍の場合の必須フィールドを検証します。
|
|
139
|
-
* エラーがある場合は例外をスローします。
|
|
316
|
+
* - エラーがある場合は例外をスローします。
|
|
317
|
+
* - `isForeigner` が false の場合、以下のプロパティを初期化します。
|
|
318
|
+
* - `foreignName`
|
|
319
|
+
* - `nationality`
|
|
320
|
+
* - `residenceStatus`
|
|
321
|
+
* - `periodOfStay`
|
|
322
|
+
* @returns {void}
|
|
323
|
+
* @throws {Error} 外国籍の場合に必須フィールドが未入力の場合。
|
|
140
324
|
*/
|
|
141
325
|
_validateForeignerRequiredFields() {
|
|
142
326
|
if (this.isForeigner) {
|
|
@@ -160,20 +344,84 @@ export default class Employee extends FireModel {
|
|
|
160
344
|
"[Employee.js] periodOfStay is required when isForeigner is true."
|
|
161
345
|
);
|
|
162
346
|
}
|
|
347
|
+
} else {
|
|
348
|
+
// 外国籍でない場合、関連フィールドを初期化
|
|
349
|
+
this.foreignName = null;
|
|
350
|
+
this.nationality = null;
|
|
351
|
+
this.residenceStatus = null;
|
|
352
|
+
this.periodOfStay = null;
|
|
163
353
|
}
|
|
164
354
|
}
|
|
165
355
|
|
|
166
356
|
/**
|
|
167
357
|
* 退職済である場合の必須フィールドを検証します。
|
|
168
|
-
* エラーがある場合は例外をスローします。
|
|
358
|
+
* - エラーがある場合は例外をスローします。
|
|
359
|
+
* - `employmentStatus` が `terminated` の場合、以下のプロパティを必須とします。
|
|
360
|
+
* - `dateOfTermination`
|
|
361
|
+
* - `reasonOfTermination`
|
|
362
|
+
* - `employmentStatus` が `active` の場合、`dateOfTermination`, `reasonOfTermination` を初期化します。
|
|
363
|
+
* @returns {void}
|
|
364
|
+
* @throws {Error} 退職済の場合に必須フィールドが未入力の場合。
|
|
169
365
|
*/
|
|
170
366
|
_validateTerminatedRequiredFields() {
|
|
171
|
-
if (this.employmentStatus ===
|
|
367
|
+
if (this.employmentStatus === EMPLOYMENT_STATUS_VALUES.TERMINATED.value) {
|
|
172
368
|
if (!this.dateOfTermination) {
|
|
173
369
|
throw new Error(
|
|
174
370
|
"[Employee.js] dateOfTermination is required when employmentStatus is 'terminated'."
|
|
175
371
|
);
|
|
176
372
|
}
|
|
373
|
+
if (!this.reasonOfTermination) {
|
|
374
|
+
throw new Error(
|
|
375
|
+
"[Employee.js] reasonOfTermination is required when employmentStatus is 'terminated'."
|
|
376
|
+
);
|
|
377
|
+
}
|
|
378
|
+
} else {
|
|
379
|
+
this.dateOfTermination = null;
|
|
380
|
+
this.reasonOfTermination = null;
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
_validateSecurityGuardFields() {
|
|
385
|
+
if (this.hasSecurityGuardRegistration) {
|
|
386
|
+
if (!this.dateOfSecurityGuardRegistration) {
|
|
387
|
+
throw new Error(
|
|
388
|
+
"[Employee.js] dateOfSecurityGuardRegistration is required when hasSecurityGuardRegistration is true."
|
|
389
|
+
);
|
|
390
|
+
}
|
|
391
|
+
if (!this.emergencyContactName) {
|
|
392
|
+
throw new Error(
|
|
393
|
+
"[Employee.js] emergencyContactName is required when hasSecurityGuardRegistration is true."
|
|
394
|
+
);
|
|
395
|
+
}
|
|
396
|
+
if (!this.emergencyContactRelationDetail) {
|
|
397
|
+
throw new Error(
|
|
398
|
+
"[Employee.js] emergencyContactRelationDetail is required when hasSecurityGuardRegistration is true."
|
|
399
|
+
);
|
|
400
|
+
}
|
|
401
|
+
if (!this.emergencyContactAddress) {
|
|
402
|
+
throw new Error(
|
|
403
|
+
"[Employee.js] emergencyContactAddress is required when hasSecurityGuardRegistration is true."
|
|
404
|
+
);
|
|
405
|
+
}
|
|
406
|
+
if (!this.emergencyContactPhone) {
|
|
407
|
+
throw new Error(
|
|
408
|
+
"[Employee.js] emergencyContactPhone is required when hasSecurityGuardRegistration is true."
|
|
409
|
+
);
|
|
410
|
+
}
|
|
411
|
+
if (!this.domicile) {
|
|
412
|
+
throw new Error(
|
|
413
|
+
"[Employee.js] domicile is required when hasSecurityGuardRegistration is true."
|
|
414
|
+
);
|
|
415
|
+
}
|
|
416
|
+
} else {
|
|
417
|
+
this.dateOfSecurityGuardRegistration = null;
|
|
418
|
+
this.bloodType = BLOOD_TYPE_VALUES.A.value;
|
|
419
|
+
this.emergencyContactName = null;
|
|
420
|
+
this.emergencyContactRelation = null;
|
|
421
|
+
this.emergencyContactRelationDetail = null;
|
|
422
|
+
this.emergencyContactAddress = null;
|
|
423
|
+
this.emergencyContactPhone = null;
|
|
424
|
+
this.domicile = null;
|
|
177
425
|
}
|
|
178
426
|
}
|
|
179
427
|
|
|
@@ -181,21 +429,98 @@ export default class Employee extends FireModel {
|
|
|
181
429
|
* 新しい従業員ドキュメントが作成される前に実行されるフック。
|
|
182
430
|
* - 親クラスの `beforeCreate` を呼び出します。
|
|
183
431
|
* - 従業員が外国人の場合、外国人名と国籍が未入力であればエラーをスローします。
|
|
432
|
+
* @param {Object} args - Creation options.
|
|
433
|
+
* @param {string} [args.docId] - Document ID to use (optional).
|
|
434
|
+
* @param {boolean} [args.useAutonumber=true] - Whether to use auto-numbering.
|
|
435
|
+
* @param {Object} [args.transaction] - Firestore transaction.
|
|
436
|
+
* @param {Function} [args.callBack] - Callback function.
|
|
437
|
+
* @param {string} [args.prefix] - Path prefix.
|
|
184
438
|
*/
|
|
185
|
-
async beforeCreate() {
|
|
186
|
-
await super.beforeCreate();
|
|
439
|
+
async beforeCreate(args = {}) {
|
|
440
|
+
await super.beforeCreate(args);
|
|
187
441
|
this._validateForeignerRequiredFields();
|
|
188
442
|
this._validateTerminatedRequiredFields();
|
|
443
|
+
this._validateSecurityGuardFields();
|
|
189
444
|
}
|
|
190
445
|
|
|
191
446
|
/**
|
|
192
447
|
* 従業員ドキュメントが更新される前に実行されるフック。
|
|
193
448
|
* - 親クラスの `beforeUpdate` を呼び出します。
|
|
194
449
|
* - 従業員が外国人の場合、外国人名と国籍が未入力であればエラーをスローします。
|
|
450
|
+
* @param {Object} args - Creation options.
|
|
451
|
+
* @param {Object} [args.transaction] - Firestore transaction.
|
|
452
|
+
* @param {Function} [args.callBack] - Callback function.
|
|
453
|
+
* @param {string} [args.prefix] - Path prefix.
|
|
195
454
|
*/
|
|
196
|
-
async beforeUpdate() {
|
|
197
|
-
await super.beforeUpdate();
|
|
455
|
+
async beforeUpdate(args = {}) {
|
|
456
|
+
await super.beforeUpdate(args);
|
|
457
|
+
|
|
458
|
+
// `employmentStatus` の `terminated` への直接変更の禁止
|
|
459
|
+
// - 従業員を退職させる場合、様々なチェックが必要になることが想定されるため、専用メソッドとして `toTerminated` を使用する。
|
|
460
|
+
// - `employmentStatus` を `terminated` に変更する場合は、必ず `toTerminated` メソッドを使用すること。
|
|
461
|
+
// - 一度退職処理した従業員の復帰処理は現状想定していないが、将来的に必要になった場合は `toActive` メソッド等を追加実装すること。
|
|
462
|
+
if (
|
|
463
|
+
!this._skipToTerminatedCheck &&
|
|
464
|
+
this.employmentStatus === Employee.STATUS_TERMINATED &&
|
|
465
|
+
this._beforeData.employmentStatus === Employee.STATUS_ACTIVE
|
|
466
|
+
) {
|
|
467
|
+
throw new Error(
|
|
468
|
+
"[Employee.js] Direct changes to employmentStatus to 'terminated' are not allowed. Use toTerminated() method instead."
|
|
469
|
+
);
|
|
470
|
+
}
|
|
471
|
+
|
|
198
472
|
this._validateForeignerRequiredFields();
|
|
199
473
|
this._validateTerminatedRequiredFields();
|
|
474
|
+
this._validateSecurityGuardFields();
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
/**
|
|
478
|
+
* 現在インスタンスに読み込まれている従業員を退職状態に変更します。
|
|
479
|
+
* @param {Date} dateOfTermination - 退職日(Dateオブジェクト)
|
|
480
|
+
* @param {string} reasonOfTermination - 退職理由
|
|
481
|
+
* @param {Object} options - パラメータオブジェクト
|
|
482
|
+
* @param {Function|null} [options.transaction=null] - Firestore トランザクション関数
|
|
483
|
+
* @param {Function|null} [options.callBack=null] - カスタム処理用コールバック
|
|
484
|
+
* @param {string|null} [options.prefix=null] - パスのプレフィックス
|
|
485
|
+
* @returns {Promise<DocumentReference>} 更新されたドキュメントの参照
|
|
486
|
+
* @throws {Error} docIdが存在しない場合、または有効なdateOfTerminationが提供されていない場合。
|
|
487
|
+
*/
|
|
488
|
+
async toTerminated(dateOfTermination, reasonOfTermination, options = {}) {
|
|
489
|
+
if (!this.docId) {
|
|
490
|
+
throw new Error(
|
|
491
|
+
"[Employee.js] docId is required to terminate an employee."
|
|
492
|
+
);
|
|
493
|
+
}
|
|
494
|
+
if (!dateOfTermination || !(dateOfTermination instanceof Date)) {
|
|
495
|
+
throw new Error(
|
|
496
|
+
"[Employee.js] A valid dateOfTermination is required to terminate an employee."
|
|
497
|
+
);
|
|
498
|
+
}
|
|
499
|
+
if (dateOfTermination < this.dateOfHire) {
|
|
500
|
+
throw new Error(
|
|
501
|
+
"[Employee.js] dateOfTermination cannot be earlier than dateOfHire."
|
|
502
|
+
);
|
|
503
|
+
}
|
|
504
|
+
|
|
505
|
+
if (!reasonOfTermination || typeof reasonOfTermination !== "string") {
|
|
506
|
+
throw new Error(
|
|
507
|
+
"[Employee.js] A valid reasonOfTermination is required to terminate an employee."
|
|
508
|
+
);
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
this.employmentStatus = Employee.STATUS_TERMINATED;
|
|
512
|
+
this.dateOfTermination = dateOfTermination;
|
|
513
|
+
this.reasonOfTermination = reasonOfTermination;
|
|
514
|
+
|
|
515
|
+
this._skipToTerminatedCheck = true;
|
|
516
|
+
|
|
517
|
+
try {
|
|
518
|
+
return await this.update(options);
|
|
519
|
+
} catch (error) {
|
|
520
|
+
this.rollback();
|
|
521
|
+
throw error;
|
|
522
|
+
} finally {
|
|
523
|
+
this._skipToTerminatedCheck = false;
|
|
524
|
+
}
|
|
200
525
|
}
|
|
201
526
|
}
|
package/src/OperationBilling.js
CHANGED
|
@@ -181,7 +181,6 @@
|
|
|
181
181
|
* @method delete - Override delete method to allow deletion even when isLocked is true
|
|
182
182
|
*****************************************************************************/
|
|
183
183
|
import OperationResult from "./OperationResult.js";
|
|
184
|
-
import Operation from "./Operation.js";
|
|
185
184
|
|
|
186
185
|
export default class OperationBilling extends OperationResult {
|
|
187
186
|
static className = "稼働請求";
|
|
@@ -192,28 +191,43 @@ export default class OperationBilling extends OperationResult {
|
|
|
192
191
|
{ title: "売上金額", key: "salesAmount", value: "salesAmount" },
|
|
193
192
|
];
|
|
194
193
|
|
|
195
|
-
|
|
196
|
-
|
|
194
|
+
/**
|
|
195
|
+
* Override beforeUpdate to skip `isLocked` check and sync customerId and apply agreement if key changed
|
|
196
|
+
* @param {Object} args - Creation options.
|
|
197
|
+
* @param {Object} [args.transaction] - Firestore transaction.
|
|
198
|
+
* @param {Function} [args.callBack] - Callback function.
|
|
199
|
+
* @param {string} [args.prefix] - Path prefix.
|
|
200
|
+
* @returns {Promise<void>}
|
|
201
|
+
*/
|
|
202
|
+
async beforeUpdate(args = {}) {
|
|
203
|
+
await super.beforeUpdate(args);
|
|
204
|
+
// Sync customerId and apply agreement if key changed
|
|
205
|
+
if (this.key === this._beforeData.key) return;
|
|
206
|
+
await this._syncCustomerIdAndApplyAgreement(args);
|
|
197
207
|
}
|
|
198
208
|
|
|
199
209
|
/**
|
|
200
|
-
* Override
|
|
201
|
-
* @
|
|
202
|
-
* @returns {Promise<void>}
|
|
210
|
+
* Override create method to disallow creation of OperationBilling instances
|
|
211
|
+
* @returns
|
|
203
212
|
*/
|
|
204
|
-
async
|
|
205
|
-
|
|
206
|
-
|
|
213
|
+
async create() {
|
|
214
|
+
return Promise.reject(
|
|
215
|
+
new Error(
|
|
216
|
+
"[OperationBilling.js] Creation of OperationBilling is not implemented."
|
|
217
|
+
)
|
|
218
|
+
);
|
|
207
219
|
}
|
|
208
220
|
|
|
209
221
|
/**
|
|
210
|
-
* Override delete method to
|
|
211
|
-
* @param {*} options
|
|
222
|
+
* Override delete method to disallow deletion of OperationBilling instances
|
|
212
223
|
* @returns {Promise<void>}
|
|
213
224
|
*/
|
|
214
|
-
async delete(
|
|
215
|
-
|
|
216
|
-
|
|
225
|
+
async delete() {
|
|
226
|
+
return Promise.reject(
|
|
227
|
+
new Error(
|
|
228
|
+
"[OperationBilling.js] Deletion of OperationBilling is not implemented."
|
|
229
|
+
)
|
|
230
|
+
);
|
|
217
231
|
}
|
|
218
232
|
|
|
219
233
|
/**
|