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