@shisyamo4131/air-guard-v2-schemas 2.4.2-dev.6 → 2.4.2-dev.60

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.
@@ -2,6 +2,10 @@ import {
2
2
  VALUES as ARRANGEMENT_NOTIFICATION_STATUS_VALUES,
3
3
  OPTIONS as ARRANGEMENT_NOTIFICATION_STATUS_OPTIONS,
4
4
  } from "../constants/arrangement-notification-status.js";
5
+ import {
6
+ VALUES as BILLING_UNIT_TYPE_VALUES,
7
+ OPTIONS as BILLING_UNIT_TYPE_OPTIONS,
8
+ } from "../constants/billing-unit-type.js";
5
9
  import {
6
10
  VALUES as BLOOD_TYPE_VALUES,
7
11
  OPTIONS as BLOOD_TYPE_OPTIONS,
@@ -30,7 +34,15 @@ import {
30
34
  VALUES as GENDER_VALUES,
31
35
  OPTIONS as GENDER_OPTIONS,
32
36
  } from "../constants/gender.js";
37
+ import {
38
+ VALUES as INSURANCE_STATUS_VALUES,
39
+ OPTIONS as INSURANCE_STATUS_OPTIONS,
40
+ } from "../constants/insurance-status.js";
33
41
  import { OPTIONS as PREFECTURES_OPTIONS } from "../constants/prefectures.js";
42
+ import {
43
+ VALUES as PAYMENT_MONTH_VALUES,
44
+ OPTIONS as PAYMENT_MONTH_OPTIONS,
45
+ } from "../constants/payment-month.js";
34
46
  import {
35
47
  VALUES as SHIFT_TYPE_VALUES,
36
48
  OPTIONS as SHIFT_TYPE_OPTIONS,
@@ -40,6 +52,7 @@ import {
40
52
  OPTIONS as SITE_STATUS_OPTIONS,
41
53
  } from "../constants/site-status.js";
42
54
  import CutoffDate from "../utils/CutoffDate.js";
55
+ import { VALIDATION_ERRORS } from "../errorDefinitions.js";
43
56
 
44
57
  export const DEFAULT_WORKING_MINUTES = 480;
45
58
  export const DEFAULT_BREAK_MINUTES = 60;
@@ -47,6 +60,25 @@ export const MINUTES_PER_HOUR = 60;
47
60
  export const MINUTES_PER_QUARTER_HOUR = 15;
48
61
  export const MAX_SCHEDULED_WORKING_MINUTES = 480; // 8時間 * 60分
49
62
 
63
+ /**
64
+ * フィールド定義のデフォルト値
65
+ * - `air-firebase` が提供する `FireModel (BaseClass)` において、クラスが保有するフィールドの定義および値の検証に使用されます。
66
+ * - `component` プロパティは `air-vuetify` の入力コンポーネント生成の為の属性として使用されます。
67
+ * 但し、required, label, hidden, length は入力コンポーネントの属性としても使用されます。
68
+ * - `validator` の返り値は原則オブジェクトです。文字列を返すこともでき、その文字列がエラーメッセージとして扱われますが多言語対応のためには
69
+ * オブジェクトを返すことを推奨します。
70
+ * 返り値が true/false の場合は、従来通りのバリデーション結果として扱われます。
71
+ * @key {String|Number|Boolean|Object|Array|Date} type - データの型
72
+ * @key {any} default - 既定値
73
+ * @key {String} label - フィールドのラベル
74
+ * @key {Number} length - 入力可能な最大文字数(文字列型の場合)
75
+ * @key {Boolean} required - 入力必須かどうか
76
+ * @key {Boolean} hidden - フィールドをUI上で非表示にするかどうか
77
+ * @key {Function} validator - フィールドの値を検証する関数。引数に値を取り、エラーメッセージを返すか、true/falseで検証結果を返す。
78
+ * @key {Object} component - フィールドに対応するUIコンポーネントの定義
79
+ * @key {String} component.name - 使用するコンポーネントの名前(AirVuetifyコンポーネントのみ指定可能)
80
+ * @key {Object} component.attrs - コンポーネントに渡す属性の定義
81
+ */
50
82
  const defaultDefinition = {
51
83
  type: String,
52
84
  default: null,
@@ -54,6 +86,7 @@ const defaultDefinition = {
54
86
  length: undefined,
55
87
  required: undefined,
56
88
  hidden: undefined,
89
+ validator: undefined,
57
90
  component: {
58
91
  name: undefined,
59
92
  attrs: {},
@@ -148,17 +181,36 @@ const generalDefinitions = {
148
181
 
149
182
  /** カスタムパーツ(汎用パーツ含む) */
150
183
  export const fieldDefinitions = {
151
- /** array */
184
+ /*****************************************************************************
185
+ * ARRAY
186
+ *****************************************************************************/
152
187
  array: generalDefinitions.array,
153
- /** check */
188
+
189
+ /*****************************************************************************
190
+ * CHECK
191
+ *****************************************************************************/
154
192
  check: generalDefinitions.check,
193
+ hasPeriodOfStayLimit: {
194
+ ...generalDefinitions.check,
195
+ label: "在留期間制限",
196
+ },
197
+ hasWorkRestrictions: {
198
+ ...generalDefinitions.check,
199
+ label: "就労制限",
200
+ },
155
201
  isForeigner: {
156
202
  ...generalDefinitions.check,
157
203
  label: "外国籍",
158
204
  },
159
- /** code */
205
+
206
+ /*****************************************************************************
207
+ * CODE
208
+ *****************************************************************************/
160
209
  code: generalDefinitions.code,
161
- /** dateAt */
210
+
211
+ /*****************************************************************************
212
+ * DATE AT
213
+ *****************************************************************************/
162
214
  dateAt: generalDefinitions.dateAt,
163
215
  dateOfBirth: {
164
216
  ...generalDefinitions.dateAt,
@@ -186,13 +238,17 @@ export const fieldDefinitions = {
186
238
  label: "退職日",
187
239
  default: null, // 2025-12-26 Set default to null
188
240
  },
241
+ enrollmentDateAt: {
242
+ ...generalDefinitions.dateAt,
243
+ label: "資格取得日",
244
+ default: null,
245
+ },
189
246
  // 2025-12-26 Added
190
247
  expirationDateAt: {
191
248
  ...generalDefinitions.dateAt,
192
249
  label: "有効期限",
193
250
  default: null,
194
251
  },
195
- // 2025-12-26 Added
196
252
  issueDateAt: {
197
253
  ...generalDefinitions.dateAt,
198
254
  label: "取得日",
@@ -209,13 +265,21 @@ export const fieldDefinitions = {
209
265
  ...generalDefinitions.multipleLine,
210
266
  label: "備考",
211
267
  },
212
- /** number */
268
+
269
+ /*****************************************************************************
270
+ * NUMBER
271
+ *****************************************************************************/
213
272
  number: generalDefinitions.number,
214
273
  breakMinutes: {
215
274
  ...generalDefinitions.number,
216
275
  label: "休憩時間(分)",
217
276
  default: DEFAULT_BREAK_MINUTES,
218
- validator: (v) => v >= 0,
277
+ validator: (v) => {
278
+ if (v < 0) {
279
+ return VALIDATION_ERRORS.MIN_VALUE_ERROR(0);
280
+ }
281
+ return true;
282
+ },
219
283
  component: {
220
284
  ...generalDefinitions.number.component,
221
285
  attrs: {
@@ -228,7 +292,12 @@ export const fieldDefinitions = {
228
292
  ...generalDefinitions.number,
229
293
  label: "残業時間(分)",
230
294
  default: 0,
231
- validator: (v) => v >= 0,
295
+ validator: (v) => {
296
+ if (v < 0) {
297
+ return VALIDATION_ERRORS.MIN_VALUE_ERROR(0);
298
+ }
299
+ return true;
300
+ },
232
301
  component: {
233
302
  ...generalDefinitions.number.component,
234
303
  attrs: {
@@ -241,7 +310,12 @@ export const fieldDefinitions = {
241
310
  ...generalDefinitions.number,
242
311
  label: "規定実働時間(分)",
243
312
  default: DEFAULT_WORKING_MINUTES,
244
- validator: (v) => v >= 0,
313
+ validator: (v) => {
314
+ if (v < 0) {
315
+ return VALIDATION_ERRORS.MIN_VALUE_ERROR(0);
316
+ }
317
+ return true;
318
+ },
245
319
  component: {
246
320
  ...generalDefinitions.number.component,
247
321
  attrs: {
@@ -256,12 +330,24 @@ export const fieldDefinitions = {
256
330
  ...generalDefinitions.number,
257
331
  },
258
332
 
259
- /** one-line */
333
+ /*****************************************************************************
334
+ * ONE LINE
335
+ *****************************************************************************/
260
336
  oneLine: generalDefinitions.oneLine,
337
+ abbreviation: {
338
+ ...generalDefinitions.oneLine,
339
+ label: "略称",
340
+ length: 20,
341
+ },
261
342
  address: {
262
343
  ...generalDefinitions.oneLine,
263
344
  label: "町域名・番地",
264
- length: 15,
345
+ length: 30,
346
+ },
347
+ branchName: {
348
+ ...generalDefinitions.oneLine,
349
+ label: "支店名など",
350
+ length: 20,
265
351
  },
266
352
  building: {
267
353
  ...generalDefinitions.oneLine,
@@ -271,7 +357,23 @@ export const fieldDefinitions = {
271
357
  city: {
272
358
  ...generalDefinitions.oneLine,
273
359
  label: "市区町村",
274
- length: 10,
360
+ length: 20,
361
+ },
362
+ companyName: {
363
+ ...generalDefinitions.oneLine,
364
+ label: "会社名",
365
+ length: 20,
366
+ },
367
+ companyNameKana: {
368
+ ...generalDefinitions.oneLine,
369
+ label: "会社名(カナ)",
370
+ length: 40,
371
+ component: {
372
+ name: generalDefinitions.oneLine.component.name,
373
+ attrs: {
374
+ inputType: "katakana",
375
+ },
376
+ },
275
377
  },
276
378
  customerId: {
277
379
  ...generalDefinitions.oneLine,
@@ -287,6 +389,21 @@ export const fieldDefinitions = {
287
389
  },
288
390
  },
289
391
  },
392
+
393
+ /**
394
+ * 取引先名
395
+ * - 2文字以上最大20文字
396
+ */
397
+ customerName: {
398
+ ...generalDefinitions.oneLine,
399
+ label: "取引先名",
400
+ length: 20,
401
+ component: {
402
+ name: generalDefinitions.oneLine.component.name,
403
+ attrs: { minLength: 2 },
404
+ },
405
+ },
406
+
290
407
  displayName: {
291
408
  ...generalDefinitions.oneLine,
292
409
  label: "表示名",
@@ -295,7 +412,7 @@ export const fieldDefinitions = {
295
412
  domicile: {
296
413
  ...generalDefinitions.oneLine,
297
414
  label: "本籍地",
298
- length: 30,
415
+ length: 50,
299
416
  },
300
417
  email: {
301
418
  ...generalDefinitions.oneLine,
@@ -305,13 +422,14 @@ export const fieldDefinitions = {
305
422
  name: generalDefinitions.oneLine.component.name,
306
423
  attrs: {
307
424
  inputType: "email",
425
+ inputmode: "email",
308
426
  },
309
427
  },
310
428
  },
311
429
  emergencyContactAddress: {
312
430
  ...generalDefinitions.oneLine,
313
431
  label: "緊急連絡先住所",
314
- length: 20,
432
+ length: 50,
315
433
  },
316
434
  emergencyContactName: {
317
435
  ...generalDefinitions.oneLine,
@@ -332,6 +450,7 @@ export const fieldDefinitions = {
332
450
  attrs: {
333
451
  counter: true,
334
452
  inputType: "tel",
453
+ inputmode: "tel",
335
454
  },
336
455
  },
337
456
  },
@@ -344,6 +463,7 @@ export const fieldDefinitions = {
344
463
  attrs: {
345
464
  counter: true,
346
465
  inputType: "tel",
466
+ inputmode: "tel",
347
467
  },
348
468
  },
349
469
  },
@@ -375,6 +495,11 @@ export const fieldDefinitions = {
375
495
  },
376
496
  },
377
497
  },
498
+ insuranceNumber: {
499
+ ...generalDefinitions.oneLine,
500
+ label: "被保険者番号(整理記号)",
501
+ length: 20,
502
+ },
378
503
  // 2025-12-26 Added
379
504
  issuedBy: {
380
505
  ...generalDefinitions.oneLine,
@@ -406,6 +531,7 @@ export const fieldDefinitions = {
406
531
  attrs: {
407
532
  counter: true,
408
533
  inputType: "tel",
534
+ inputmode: "tel",
409
535
  },
410
536
  },
411
537
  },
@@ -467,6 +593,7 @@ export const fieldDefinitions = {
467
593
  attrs: {
468
594
  counter: true,
469
595
  inputType: "tel",
596
+ inputmode: "tel",
470
597
  },
471
598
  },
472
599
  },
@@ -503,7 +630,9 @@ export const fieldDefinitions = {
503
630
  },
504
631
  },
505
632
 
506
- /** object */
633
+ /*****************************************************************************
634
+ * OBJECT
635
+ *****************************************************************************/
507
636
  object: generalDefinitions.object,
508
637
 
509
638
  customer: {
@@ -520,15 +649,23 @@ export const fieldDefinitions = {
520
649
  },
521
650
  },
522
651
  },
652
+ employmentInsurance: {
653
+ ...generalDefinitions.object,
654
+ label: "雇用保険",
655
+ },
523
656
  location: {
524
657
  ...generalDefinitions.object,
525
658
  hidden: true,
526
659
  },
527
660
 
528
- /** radio */
661
+ /*****************************************************************************
662
+ * RADIO
663
+ *****************************************************************************/
529
664
  radio: generalDefinitions.radio,
530
665
 
531
- /** select */
666
+ /*****************************************************************************
667
+ * SELECT
668
+ *****************************************************************************/
532
669
  select: generalDefinitions.select,
533
670
  arrangementNotificationStatus: {
534
671
  ...generalDefinitions.select,
@@ -541,6 +678,18 @@ export const fieldDefinitions = {
541
678
  },
542
679
  },
543
680
  },
681
+ /** 請求単位 */
682
+ billingUnitType: {
683
+ ...generalDefinitions.select,
684
+ default: BILLING_UNIT_TYPE_VALUES.PER_DAY.value,
685
+ label: "請求単位",
686
+ component: {
687
+ name: generalDefinitions.select.component.name,
688
+ attrs: {
689
+ items: BILLING_UNIT_TYPE_OPTIONS,
690
+ },
691
+ },
692
+ },
544
693
  bloodType: {
545
694
  ...generalDefinitions.select,
546
695
  label: "血液型",
@@ -630,6 +779,39 @@ export const fieldDefinitions = {
630
779
  },
631
780
  },
632
781
  },
782
+ insuranceStatus: {
783
+ ...generalDefinitions.select,
784
+ default: INSURANCE_STATUS_VALUES.NOT_ENROLLED.value,
785
+ label: "保険状態",
786
+ component: {
787
+ name: generalDefinitions.select.component.name,
788
+ attrs: {
789
+ items: INSURANCE_STATUS_OPTIONS,
790
+ },
791
+ },
792
+ },
793
+ paymentDate: {
794
+ ...generalDefinitions.select,
795
+ default: CutoffDate.VALUES[0].value,
796
+ label: "入金サイト(日)",
797
+ component: {
798
+ name: generalDefinitions.select.component.name,
799
+ attrs: {
800
+ items: CutoffDate.OPTIONS,
801
+ },
802
+ },
803
+ },
804
+ paymentMonth: {
805
+ ...generalDefinitions.select,
806
+ default: PAYMENT_MONTH_VALUES[1].value,
807
+ label: "入金サイト(月数)",
808
+ component: {
809
+ name: generalDefinitions.select.component.name,
810
+ attrs: {
811
+ items: PAYMENT_MONTH_OPTIONS,
812
+ },
813
+ },
814
+ },
633
815
  prefCode: {
634
816
  ...generalDefinitions.select,
635
817
  label: "都道府県",
@@ -689,7 +871,7 @@ export const defField = (key, options = {}) => {
689
871
 
690
872
  if (!baseConfigSource) {
691
873
  console.warn(
692
- `[parts/fieldDefinitions.js defField] Definition for key "${key}" not found. Using fieldDefinitions.default as base.`
874
+ `[parts/fieldDefinitions.js defField] Definition for key "${key}" not found. Using fieldDefinitions.default as base.`,
693
875
  );
694
876
  baseConfigSource = effectiveDefaultDefinition;
695
877
  isFallback = true;
@@ -753,6 +935,10 @@ export const defField = (key, options = {}) => {
753
935
  if (options.hasOwnProperty("required")) {
754
936
  newConfig.required = options.required;
755
937
  }
938
+ // validatorの処理: optionsにvalidatorがあれば設定
939
+ if (options.hasOwnProperty("validator")) {
940
+ newConfig.validator = options.validator;
941
+ }
756
942
  // `hidden` は options にあればその値、なければ newConfig の値 (baseConfig または defaultDefinition 由来) を維持
757
943
  // defaultDefinition.hidden は undefined なので、指定がなければ undefined のままになる
758
944
  if (options.hasOwnProperty("hidden")) {
@@ -15,14 +15,14 @@ export function getDateAt(date, time, dateOffset = 0) {
15
15
  // If date is not null/undefined and is not a string or Date, throw an error
16
16
  if (date != null && !(typeof date === "string" || date instanceof Date)) {
17
17
  throw new Error(
18
- `[getDateAt] Invalid date type. Expected string or Date, got ${typeof date}`
18
+ `[getDateAt] Invalid date type. Expected string or Date, got ${typeof date}`,
19
19
  );
20
20
  }
21
21
 
22
22
  // If time is not null and is not a string, throw an error
23
23
  if (time != null && typeof time !== "string") {
24
24
  throw new Error(
25
- `[getDateAt] Invalid time type. Expected string, got ${typeof time}`
25
+ `[getDateAt] Invalid time type. Expected string, got ${typeof time}`,
26
26
  );
27
27
  }
28
28
 
@@ -31,18 +31,30 @@ export function getDateAt(date, time, dateOffset = 0) {
31
31
  const [hour, minute] = time ? time.split(":").map(Number) : [0, 0];
32
32
  if (isNaN(hour) || isNaN(minute)) {
33
33
  throw new Error(
34
- `[getDateAt] Invalid time format. Expected HH:MM, got ${time}`
34
+ `[getDateAt] Invalid time format. Expected HH:MM, got ${time}`,
35
35
  );
36
36
  }
37
37
 
38
38
  // If date is not provided, use the current date
39
- const result = new Date(date || Date.now());
39
+ const baseDate = new Date(date || Date.now());
40
40
 
41
- // JSTはUTC+9なので、UTC時刻として設定してから9時間引く
42
- result.setUTCHours(hour - 9, minute, 0, 0);
43
- result.setUTCDate(result.getUTCDate() + dateOffset);
41
+ // 入力日時から JST の日付成分を取得してから、JST時刻を合成する。
42
+ // これにより、UTC日付境界を跨ぐケースでも期待通りの JST 日付を保てる。
43
+ const jstDate = new Date(baseDate.getTime() + 9 * 60 * 60 * 1000);
44
+ const year = jstDate.getUTCFullYear();
45
+ const month = jstDate.getUTCMonth();
46
+ const day = jstDate.getUTCDate();
44
47
 
45
- return result;
48
+ const utcMillis = Date.UTC(
49
+ year,
50
+ month,
51
+ day + dateOffset,
52
+ hour - 9,
53
+ minute,
54
+ 0,
55
+ 0,
56
+ );
57
+ return new Date(utcMillis);
46
58
  }
47
59
 
48
60
  export { ContextualError } from "./ContextualError.js";