@shisyamo4131/air-guard-v2-schemas 2.3.8-dev.2 → 2.4.0
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 +25 -5
- package/src/mixins/GeocodableMixin.js +149 -0
package/index.js
CHANGED
|
@@ -6,6 +6,7 @@ export { default as Company } from "./src/Company.js";
|
|
|
6
6
|
export { default as Customer, CustomerMinimal } from "./src/Customer.js";
|
|
7
7
|
export { default as CutoffDate } from "./src/utils/CutoffDate.js";
|
|
8
8
|
export { default as Employee } from "./src/Employee.js";
|
|
9
|
+
export { GeocodableMixin } from "./src/mixins/GeocodableMixin.js";
|
|
9
10
|
export { default as OperationBilling } from "./src/OperationBilling.js";
|
|
10
11
|
export { default as OperationResult } from "./src/OperationResult.js";
|
|
11
12
|
export { default as OperationResultDetail } from "./src/OperationResultDetail.js";
|
package/package.json
CHANGED
package/src/Company.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Company Model
|
|
3
|
-
* @version 1.
|
|
3
|
+
* @version 1.0.0
|
|
4
4
|
* @author shisyamo4131
|
|
5
|
-
* @update 2025-12-
|
|
6
|
-
* @update 2025-12-
|
|
7
|
-
* @update 2025-
|
|
8
|
-
* @update 2025-11-
|
|
5
|
+
* @update 2025-12-29 - Add `isCompleteRequiredFields` computed property.
|
|
6
|
+
* @update 2025-12-02 - Add maintenance information properties.
|
|
7
|
+
* @update 2025-12-01 - Add Stripe integration fields (stripeCustomerId, subscription).
|
|
8
|
+
* @update 2025-11-27 - Add bank information fields for billing.
|
|
9
|
+
* @update 2025-11-23 - Set `usePrefix` to false.
|
|
9
10
|
*/
|
|
10
11
|
import FireModel from "@shisyamo4131/air-firebase-v2";
|
|
11
12
|
import { defField } from "./parts/fieldDefinitions.js";
|
|
@@ -149,6 +150,25 @@ export default class Company extends FireModel {
|
|
|
149
150
|
},
|
|
150
151
|
set() {},
|
|
151
152
|
},
|
|
153
|
+
|
|
154
|
+
// Check if all `required` fields are filled.
|
|
155
|
+
// Used for validating whether the Company info is complete.
|
|
156
|
+
isCompleteRequiredFields: {
|
|
157
|
+
enumerable: true,
|
|
158
|
+
configurable: true,
|
|
159
|
+
get() {
|
|
160
|
+
return !!(
|
|
161
|
+
this.companyName &&
|
|
162
|
+
this.companyNameKana &&
|
|
163
|
+
this.zipcode &&
|
|
164
|
+
this.prefCode &&
|
|
165
|
+
this.city &&
|
|
166
|
+
this.address &&
|
|
167
|
+
this.tel
|
|
168
|
+
);
|
|
169
|
+
},
|
|
170
|
+
set() {},
|
|
171
|
+
},
|
|
152
172
|
});
|
|
153
173
|
|
|
154
174
|
/*************************************************************************
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file src/mixins/GeocodableMixin.js
|
|
3
|
+
* @description Geocoding 機能を提供する Mixin
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Geocoding 機能を提供する Mixin
|
|
8
|
+
* @param {Class} BaseClass - 継承元のクラス
|
|
9
|
+
* @returns {Class} Geocoding 機能を持つクラス
|
|
10
|
+
*/
|
|
11
|
+
export function GeocodableMixin(BaseClass) {
|
|
12
|
+
return class extends BaseClass {
|
|
13
|
+
/**
|
|
14
|
+
* Firestore 用のコンバーターを提供します。
|
|
15
|
+
* - location から geopoint を自動生成して Firestore に保存します。
|
|
16
|
+
* - toObject() は純粋なプレーンオブジェクトを返すため、コンポーネント側で安全に使用できます。
|
|
17
|
+
* @override
|
|
18
|
+
*/
|
|
19
|
+
static converter() {
|
|
20
|
+
const superConverter = super.converter();
|
|
21
|
+
return {
|
|
22
|
+
toFirestore: (instance) => {
|
|
23
|
+
const obj = superConverter.toFirestore(instance);
|
|
24
|
+
|
|
25
|
+
// location から geopoint を生成
|
|
26
|
+
if (obj.location?.lat && obj.location?.lng) {
|
|
27
|
+
try {
|
|
28
|
+
const adapter = this.getAdapter();
|
|
29
|
+
const GeoPoint = adapter.GeoPoint;
|
|
30
|
+
|
|
31
|
+
if (GeoPoint) {
|
|
32
|
+
obj.geopoint = new GeoPoint(obj.location.lat, obj.location.lng);
|
|
33
|
+
}
|
|
34
|
+
} catch (error) {
|
|
35
|
+
console.warn(
|
|
36
|
+
`[${this.className}.converter] GeoPoint generation failed:`,
|
|
37
|
+
error
|
|
38
|
+
);
|
|
39
|
+
obj.geopoint = null;
|
|
40
|
+
}
|
|
41
|
+
} else {
|
|
42
|
+
obj.geopoint = null;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
return obj;
|
|
46
|
+
},
|
|
47
|
+
fromFirestore: superConverter.fromFirestore,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* 新しいドキュメントが作成される前に `location` を取得してセットします。
|
|
53
|
+
* @param {Object} args - Creation options.
|
|
54
|
+
* @param {boolean} [args.skipGeocoding=false] - Skip geocoding process.
|
|
55
|
+
* @returns {Promise<void>}
|
|
56
|
+
*/
|
|
57
|
+
async beforeCreate(args = {}) {
|
|
58
|
+
await super.beforeCreate(args);
|
|
59
|
+
|
|
60
|
+
if (!args.skipGeocoding) {
|
|
61
|
+
await this._geocodeAndSetLocation("beforeCreate");
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* ドキュメントが更新される前に `location` を取得してセットします。
|
|
67
|
+
* 住所に変更がない場合はジオコーディングをスキップします。
|
|
68
|
+
* @param {Object} args - Update options.
|
|
69
|
+
* @param {boolean} [args.skipGeocoding=false] - Skip geocoding process.
|
|
70
|
+
* @returns {Promise<void>}
|
|
71
|
+
*/
|
|
72
|
+
async beforeUpdate(args = {}) {
|
|
73
|
+
await super.beforeUpdate(args);
|
|
74
|
+
|
|
75
|
+
const currentFullAddress = this.fullAddress;
|
|
76
|
+
const previousFullAddress = this._beforeData?.fullAddress;
|
|
77
|
+
|
|
78
|
+
// 住所に変更がない場合、またはskipGeocodingがtrueの場合はスキップ
|
|
79
|
+
if (
|
|
80
|
+
args.skipGeocoding ||
|
|
81
|
+
(this._beforeData && currentFullAddress === previousFullAddress)
|
|
82
|
+
) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
await this._geocodeAndSetLocation("beforeUpdate");
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* ジオコーディング処理
|
|
91
|
+
* fullAddress から緯度・経度・正規化された住所を取得し、location に設定
|
|
92
|
+
* @private
|
|
93
|
+
* @param {string} context - 呼び出し元のコンテキスト('beforeCreate' | 'beforeUpdate')
|
|
94
|
+
*/
|
|
95
|
+
async _geocodeAndSetLocation(context) {
|
|
96
|
+
const address = this.fullAddress;
|
|
97
|
+
|
|
98
|
+
if (!address || address.trim() === "") {
|
|
99
|
+
this.location = null;
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
if (!GeocodableMixin._geocodingFunction) {
|
|
104
|
+
console.warn(
|
|
105
|
+
`[${this.constructor.className}.${context}] Geocoding function not set. Skipping geocoding.`
|
|
106
|
+
);
|
|
107
|
+
this.location = null;
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
try {
|
|
112
|
+
const coordinates = await GeocodableMixin._geocodingFunction(address);
|
|
113
|
+
|
|
114
|
+
if (coordinates && coordinates.lat && coordinates.lng) {
|
|
115
|
+
this.location = {
|
|
116
|
+
formattedAddress: coordinates.formattedAddress || address,
|
|
117
|
+
lat: coordinates.lat,
|
|
118
|
+
lng: coordinates.lng,
|
|
119
|
+
};
|
|
120
|
+
} else {
|
|
121
|
+
this.location = null;
|
|
122
|
+
}
|
|
123
|
+
} catch (error) {
|
|
124
|
+
console.warn(
|
|
125
|
+
`[${this.constructor.className}.${context}] Geocoding failed:`,
|
|
126
|
+
error
|
|
127
|
+
);
|
|
128
|
+
this.location = null;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Geocoding 処理を行う関数(外部から注入)
|
|
136
|
+
* @type {Function|null}
|
|
137
|
+
* @static
|
|
138
|
+
*/
|
|
139
|
+
GeocodableMixin._geocodingFunction = null;
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Geocoding 関数を設定します。
|
|
143
|
+
* すべての GeocodableMixin を継承したクラスで共有されます。
|
|
144
|
+
* @param {Function} fn - 住所文字列を受け取り、{ lat, lng, formattedAddress } を返す非同期関数
|
|
145
|
+
* @static
|
|
146
|
+
*/
|
|
147
|
+
GeocodableMixin.setGeocodingFunction = function (fn) {
|
|
148
|
+
GeocodableMixin._geocodingFunction = fn;
|
|
149
|
+
};
|