@oneuptime/common 7.0.5058 → 7.0.5065

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.
Files changed (28) hide show
  1. package/Models/DatabaseModels/Project.ts +51 -0
  2. package/Server/Infrastructure/Postgres/SchemaMigrations/1754671483948-MigrationName.ts +22 -0
  3. package/Server/Infrastructure/Postgres/SchemaMigrations/1756293325324-MigrationName.ts +16 -0
  4. package/Server/Infrastructure/Postgres/SchemaMigrations/1756296282627-MigrationName.ts +18 -0
  5. package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +4 -0
  6. package/Server/Services/BillingService.ts +66 -0
  7. package/Server/Services/ProjectService.ts +25 -0
  8. package/UI/Components/Detail/Detail.tsx +1 -1
  9. package/UI/Utils/Countries.ts +256 -0
  10. package/build/dist/Models/DatabaseModels/Project.js +54 -0
  11. package/build/dist/Models/DatabaseModels/Project.js.map +1 -1
  12. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1754671483948-MigrationName.js +8 -0
  13. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1754671483948-MigrationName.js.map +1 -1
  14. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1756293325324-MigrationName.js +12 -0
  15. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1756293325324-MigrationName.js.map +1 -0
  16. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1756296282627-MigrationName.js +16 -0
  17. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1756296282627-MigrationName.js.map +1 -0
  18. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +4 -0
  19. package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
  20. package/build/dist/Server/Services/BillingService.js +59 -0
  21. package/build/dist/Server/Services/BillingService.js.map +1 -1
  22. package/build/dist/Server/Services/ProjectService.js +18 -0
  23. package/build/dist/Server/Services/ProjectService.js.map +1 -1
  24. package/build/dist/UI/Components/Detail/Detail.js +1 -1
  25. package/build/dist/UI/Components/Detail/Detail.js.map +1 -1
  26. package/build/dist/UI/Utils/Countries.js +251 -0
  27. package/build/dist/UI/Utils/Countries.js.map +1 -0
  28. package/package.json +1 -1
@@ -248,6 +248,57 @@ export default class Project extends TenantModel {
248
248
  })
249
249
  public paymentProviderCustomerId?: string = undefined;
250
250
 
251
+ @ColumnAccessControl({
252
+ create: [Permission.ProjectOwner, Permission.ManageProjectBilling],
253
+ read: [
254
+ Permission.ProjectOwner,
255
+ Permission.ProjectAdmin,
256
+ Permission.ProjectMember,
257
+ Permission.ReadProject,
258
+ Permission.UnAuthorizedSsoUser,
259
+ Permission.ProjectUser,
260
+ ],
261
+ update: [Permission.ProjectOwner, Permission.ManageProjectBilling],
262
+ })
263
+ @TableColumn({
264
+ type: TableColumnType.LongText,
265
+ title: "Business Details / Billing Address",
266
+ description:
267
+ "Business legal name, address and any tax information to appear on invoices.",
268
+ })
269
+ @Column({
270
+ type: ColumnType.LongText,
271
+ length: ColumnLength.LongText,
272
+ nullable: true,
273
+ unique: false,
274
+ })
275
+ public businessDetails?: string = undefined;
276
+
277
+ @ColumnAccessControl({
278
+ create: [Permission.ProjectOwner, Permission.ManageProjectBilling],
279
+ read: [
280
+ Permission.ProjectOwner,
281
+ Permission.ProjectAdmin,
282
+ Permission.ProjectMember,
283
+ Permission.ReadProject,
284
+ Permission.UnAuthorizedSsoUser,
285
+ Permission.ProjectUser,
286
+ ],
287
+ update: [Permission.ProjectOwner, Permission.ManageProjectBilling],
288
+ })
289
+ @TableColumn({
290
+ type: TableColumnType.ShortText,
291
+ title: "Business Country (ISO Alpha-2)",
292
+ description: "Two-letter ISO country code for billing address (e.g., US, GB, DE).",
293
+ })
294
+ @Column({
295
+ type: ColumnType.ShortText,
296
+ length: ColumnLength.ShortText,
297
+ nullable: true,
298
+ unique: false,
299
+ })
300
+ public businessDetailsCountry?: string = undefined;
301
+
251
302
  @ColumnAccessControl({
252
303
  create: [],
253
304
  read: [
@@ -68,6 +68,28 @@ export class MigrationName1754671483948 implements MigrationInterface {
68
68
  await queryRunner.query(
69
69
  `ALTER TABLE "StatusPageAnnouncement" ADD "subscriberNotificationStatusMessage" text`,
70
70
  );
71
+ // Set all existing rows' subscriber notification statuses to 'Success' since they were previously considered notified
72
+ await queryRunner.query(
73
+ `UPDATE "Incident" SET "subscriberNotificationStatusOnIncidentCreated"='Success'`,
74
+ );
75
+ await queryRunner.query(
76
+ `UPDATE "IncidentPublicNote" SET "subscriberNotificationStatusOnNoteCreated"='Success'`,
77
+ );
78
+ await queryRunner.query(
79
+ `UPDATE "IncidentStateTimeline" SET "subscriberNotificationStatus"='Success'`,
80
+ );
81
+ await queryRunner.query(
82
+ `UPDATE "ScheduledMaintenance" SET "subscriberNotificationStatusOnEventScheduled"='Success'`,
83
+ );
84
+ await queryRunner.query(
85
+ `UPDATE "ScheduledMaintenancePublicNote" SET "subscriberNotificationStatusOnNoteCreated"='Success'`,
86
+ );
87
+ await queryRunner.query(
88
+ `UPDATE "ScheduledMaintenanceStateTimeline" SET "subscriberNotificationStatus"='Success'`,
89
+ );
90
+ await queryRunner.query(
91
+ `UPDATE "StatusPageAnnouncement" SET "subscriberNotificationStatus"='Success'`,
92
+ );
71
93
  await queryRunner.query(
72
94
  `ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "rotation" SET DEFAULT '{"_type":"Recurring","value":{"intervalType":"Day","intervalCount":{"_type":"PositiveNumber","value":1}}}'`,
73
95
  );
@@ -0,0 +1,16 @@
1
+ import { MigrationInterface, QueryRunner } from "typeorm";
2
+
3
+ export class MigrationName1756293325324 implements MigrationInterface {
4
+ public name = 'MigrationName1756293325324'
5
+
6
+ public async up(queryRunner: QueryRunner): Promise<void> {
7
+ await queryRunner.query(`ALTER TABLE "Project" ADD "businessDetails" character varying(500)`);
8
+ }
9
+
10
+ public async down(queryRunner: QueryRunner): Promise<void> {
11
+
12
+ await queryRunner.query(`ALTER TABLE "Project" DROP COLUMN "businessDetails"`);
13
+
14
+ }
15
+
16
+ }
@@ -0,0 +1,18 @@
1
+ import { MigrationInterface, QueryRunner } from "typeorm";
2
+
3
+ export class MigrationName1756296282627 implements MigrationInterface {
4
+ public name = 'MigrationName1756296282627'
5
+
6
+ public async up(queryRunner: QueryRunner): Promise<void> {
7
+ await queryRunner.query(`ALTER TABLE "Project" ADD "businessDetailsCountry" character varying(100)`);
8
+ await queryRunner.query(`ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "rotation" SET DEFAULT '{"_type":"Recurring","value":{"intervalType":"Day","intervalCount":{"_type":"PositiveNumber","value":1}}}'`);
9
+ await queryRunner.query(`ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "restrictionTimes" SET DEFAULT '{"_type":"RestrictionTimes","value":{"restictionType":"None","dayRestrictionTimes":null,"weeklyRestrictionTimes":[]}}'`);
10
+ }
11
+
12
+ public async down(queryRunner: QueryRunner): Promise<void> {
13
+ await queryRunner.query(`ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "restrictionTimes" SET DEFAULT '{"_type": "RestrictionTimes", "value": {"restictionType": "None", "dayRestrictionTimes": null, "weeklyRestrictionTimes": []}}'`);
14
+ await queryRunner.query(`ALTER TABLE "OnCallDutyPolicyScheduleLayer" ALTER COLUMN "rotation" SET DEFAULT '{"_type": "Recurring", "value": {"intervalType": "Day", "intervalCount": {"_type": "PositiveNumber", "value": 1}}}'`);
15
+ await queryRunner.query(`ALTER TABLE "Project" DROP COLUMN "businessDetailsCountry"`);
16
+ }
17
+
18
+ }
@@ -161,6 +161,8 @@ import { MigrationName1755110936888 } from "./1755110936888-MigrationName";
161
161
  import { MigrationName1755775040650 } from "./1755775040650-MigrationName";
162
162
  import { MigrationName1755778495455 } from "./1755778495455-MigrationName";
163
163
  import { MigrationName1755778934927 } from "./1755778934927-MigrationName";
164
+ import { MigrationName1756293325324 } from "./1756293325324-MigrationName";
165
+ import { MigrationName1756296282627 } from "./1756296282627-MigrationName";
164
166
 
165
167
  export default [
166
168
  InitialMigration,
@@ -326,4 +328,6 @@ export default [
326
328
  MigrationName1755775040650,
327
329
  MigrationName1755778495455,
328
330
  MigrationName1755778934927,
331
+ MigrationName1756293325324,
332
+ MigrationName1756296282627
329
333
  ];
@@ -80,6 +80,72 @@ export class BillingService extends BaseService {
80
80
  await this.stripe.customers.update(id, { name: newName });
81
81
  }
82
82
 
83
+ @CaptureSpan()
84
+ public async updateCustomerBusinessDetails(
85
+ id: string,
86
+ businessDetails: string,
87
+ countryCode?: string | null,
88
+ ): Promise<void> {
89
+ if (!this.isBillingEnabled()) {
90
+ throw new BadDataException(Errors.BillingService.BILLING_NOT_ENABLED);
91
+ }
92
+ // Goal: Update Stripe Customer "Billing details" (address fields) rather than invoice footer.
93
+ // We only have a single free-form textarea. We'll map:
94
+ // First non-empty line -> address.line1
95
+ // Second non-empty line (if any) and remaining (joined, truncated) -> address.line2
96
+ // We also persist full text in metadata so we can reconstruct or improve parsing later.
97
+ // NOTE: Because Stripe requires structured address, any city/state/postal/country detection
98
+ // would be heuristic; we keep it simple unless we later add structured fields.
99
+
100
+ const lines: Array<string> = businessDetails
101
+ .split(/\r?\n/)
102
+ .map((l: string) => l.trim())
103
+ .filter((l: string) => l.length > 0);
104
+
105
+ let line1: string | undefined = undefined;
106
+ let line2: string | undefined = undefined;
107
+
108
+ if (lines && lines.length > 0) {
109
+ const first: string = lines[0]!; // non-null
110
+ line1 = first.substring(0, 200); // Stripe typical limit safeguard.
111
+ }
112
+ if (lines && lines.length > 1) {
113
+ const rest: string = lines.slice(1).join(', ');
114
+ line2 = rest.substring(0, 200);
115
+ }
116
+
117
+ const updateParams: Stripe.CustomerUpdateParams = {
118
+ metadata: {
119
+ business_details_full: businessDetails.substring(0, 5000),
120
+ },
121
+ address: {},
122
+ };
123
+
124
+ if (line1) {
125
+ updateParams.address = updateParams.address || {};
126
+ updateParams.address.line1 = line1;
127
+ }
128
+ if (line2) {
129
+ updateParams.address = updateParams.address || {};
130
+ updateParams.address.line2 = line2;
131
+ }
132
+ if (countryCode) {
133
+ updateParams.address = updateParams.address || {};
134
+ // Stripe expects uppercase 2-letter ISO code
135
+ updateParams.address.country = countryCode.toUpperCase();
136
+ }
137
+
138
+ if (!line1 && !line2 && !countryCode) {
139
+ // Clear address if empty details submitted.
140
+ updateParams.address = {
141
+ line1: '',
142
+ line2: '',
143
+ } as any;
144
+ }
145
+
146
+ await this.stripe.customers.update(id, updateParams);
147
+ }
148
+
83
149
  @CaptureSpan()
84
150
  public async deleteCustomer(id: string): Promise<void> {
85
151
  if (!this.isBillingEnabled()) {
@@ -273,6 +273,31 @@ export class ProjectService extends DatabaseService<Model> {
273
273
  updateBy: UpdateBy<Model>,
274
274
  ): Promise<OnUpdate<Model>> {
275
275
  if (IsBillingEnabled) {
276
+
277
+ if (updateBy.data.businessDetails || updateBy.data.businessDetailsCountry) {
278
+ // Sync to Stripe.
279
+ const project: Model | null = await this.findOneById({
280
+ id: new ObjectID(updateBy.query._id! as string),
281
+ select: {
282
+ paymentProviderCustomerId: true,
283
+ },
284
+ props: { isRoot: true },
285
+ });
286
+
287
+ if (project?.paymentProviderCustomerId) {
288
+ try {
289
+ await BillingService.updateCustomerBusinessDetails(
290
+ project.paymentProviderCustomerId,
291
+ (updateBy.data.businessDetails as string) || '',
292
+ (updateBy.data.businessDetailsCountry as string) || null,
293
+ );
294
+ } catch (err) {
295
+ logger.error(
296
+ 'Failed to update Stripe customer business details: ' + err,
297
+ );
298
+ }
299
+ }
300
+ }
276
301
  if (updateBy.data.enableAutoRechargeSmsOrCallBalance) {
277
302
  await NotificationService.rechargeIfBalanceIsLow(
278
303
  new ObjectID(updateBy.query._id! as string),
@@ -420,7 +420,7 @@ const Detail: DetailFunction = <T extends GenericObject>(
420
420
  )}
421
421
  </div>
422
422
  )}
423
- {(data === null || data === undefined) && field.placeholder && (
423
+ {(data === null || data === undefined || data === '') && field.placeholder && (
424
424
  <PlaceholderText text={field.placeholder} />
425
425
  )}
426
426
  </div>
@@ -0,0 +1,256 @@
1
+ // ISO 3166-1 alpha-2 country codes and names.
2
+ // Limited to widely recognized sovereign states and territories supported by Stripe.
3
+ // If needed, expand or adjust for specific business logic.
4
+ export interface CountryOption { value: string; label: string }
5
+
6
+ export const Countries: Array<CountryOption> = [
7
+ { value: 'AF', label: 'Afghanistan' },
8
+ { value: 'AL', label: 'Albania' },
9
+ { value: 'DZ', label: 'Algeria' },
10
+ { value: 'AS', label: 'American Samoa' },
11
+ { value: 'AD', label: 'Andorra' },
12
+ { value: 'AO', label: 'Angola' },
13
+ { value: 'AI', label: 'Anguilla' },
14
+ { value: 'AQ', label: 'Antarctica' },
15
+ { value: 'AG', label: 'Antigua and Barbuda' },
16
+ { value: 'AR', label: 'Argentina' },
17
+ { value: 'AM', label: 'Armenia' },
18
+ { value: 'AW', label: 'Aruba' },
19
+ { value: 'AU', label: 'Australia' },
20
+ { value: 'AT', label: 'Austria' },
21
+ { value: 'AZ', label: 'Azerbaijan' },
22
+ { value: 'BS', label: 'Bahamas' },
23
+ { value: 'BH', label: 'Bahrain' },
24
+ { value: 'BD', label: 'Bangladesh' },
25
+ { value: 'BB', label: 'Barbados' },
26
+ { value: 'BY', label: 'Belarus' },
27
+ { value: 'BE', label: 'Belgium' },
28
+ { value: 'BZ', label: 'Belize' },
29
+ { value: 'BJ', label: 'Benin' },
30
+ { value: 'BM', label: 'Bermuda' },
31
+ { value: 'BT', label: 'Bhutan' },
32
+ { value: 'BO', label: 'Bolivia' },
33
+ { value: 'BQ', label: 'Bonaire, Sint Eustatius and Saba' },
34
+ { value: 'BA', label: 'Bosnia and Herzegovina' },
35
+ { value: 'BW', label: 'Botswana' },
36
+ { value: 'BV', label: 'Bouvet Island' },
37
+ { value: 'BR', label: 'Brazil' },
38
+ { value: 'IO', label: 'British Indian Ocean Territory' },
39
+ { value: 'BN', label: 'Brunei Darussalam' },
40
+ { value: 'BG', label: 'Bulgaria' },
41
+ { value: 'BF', label: 'Burkina Faso' },
42
+ { value: 'BI', label: 'Burundi' },
43
+ { value: 'KH', label: 'Cambodia' },
44
+ { value: 'CM', label: 'Cameroon' },
45
+ { value: 'CA', label: 'Canada' },
46
+ { value: 'CV', label: 'Cape Verde' },
47
+ { value: 'KY', label: 'Cayman Islands' },
48
+ { value: 'CF', label: 'Central African Republic' },
49
+ { value: 'TD', label: 'Chad' },
50
+ { value: 'CL', label: 'Chile' },
51
+ { value: 'CN', label: 'China' },
52
+ { value: 'CX', label: 'Christmas Island' },
53
+ { value: 'CC', label: 'Cocos (Keeling) Islands' },
54
+ { value: 'CO', label: 'Colombia' },
55
+ { value: 'KM', label: 'Comoros' },
56
+ { value: 'CG', label: 'Congo' },
57
+ { value: 'CD', label: 'Congo, the Democratic Republic of the' },
58
+ { value: 'CK', label: 'Cook Islands' },
59
+ { value: 'CR', label: 'Costa Rica' },
60
+ { value: 'CI', label: "Côte d'Ivoire" },
61
+ { value: 'HR', label: 'Croatia' },
62
+ { value: 'CU', label: 'Cuba' },
63
+ { value: 'CW', label: 'Curaçao' },
64
+ { value: 'CY', label: 'Cyprus' },
65
+ { value: 'CZ', label: 'Czech Republic' },
66
+ { value: 'DK', label: 'Denmark' },
67
+ { value: 'DJ', label: 'Djibouti' },
68
+ { value: 'DM', label: 'Dominica' },
69
+ { value: 'DO', label: 'Dominican Republic' },
70
+ { value: 'EC', label: 'Ecuador' },
71
+ { value: 'EG', label: 'Egypt' },
72
+ { value: 'SV', label: 'El Salvador' },
73
+ { value: 'GQ', label: 'Equatorial Guinea' },
74
+ { value: 'ER', label: 'Eritrea' },
75
+ { value: 'EE', label: 'Estonia' },
76
+ { value: 'ET', label: 'Ethiopia' },
77
+ { value: 'FK', label: 'Falkland Islands (Malvinas)' },
78
+ { value: 'FO', label: 'Faroe Islands' },
79
+ { value: 'FJ', label: 'Fiji' },
80
+ { value: 'FI', label: 'Finland' },
81
+ { value: 'FR', label: 'France' },
82
+ { value: 'GF', label: 'French Guiana' },
83
+ { value: 'PF', label: 'French Polynesia' },
84
+ { value: 'TF', label: 'French Southern Territories' },
85
+ { value: 'GA', label: 'Gabon' },
86
+ { value: 'GM', label: 'Gambia' },
87
+ { value: 'GE', label: 'Georgia' },
88
+ { value: 'DE', label: 'Germany' },
89
+ { value: 'GH', label: 'Ghana' },
90
+ { value: 'GI', label: 'Gibraltar' },
91
+ { value: 'GR', label: 'Greece' },
92
+ { value: 'GL', label: 'Greenland' },
93
+ { value: 'GD', label: 'Grenada' },
94
+ { value: 'GP', label: 'Guadeloupe' },
95
+ { value: 'GU', label: 'Guam' },
96
+ { value: 'GT', label: 'Guatemala' },
97
+ { value: 'GG', label: 'Guernsey' },
98
+ { value: 'GN', label: 'Guinea' },
99
+ { value: 'GW', label: 'Guinea-Bissau' },
100
+ { value: 'GY', label: 'Guyana' },
101
+ { value: 'HT', label: 'Haiti' },
102
+ { value: 'HM', label: 'Heard Island and McDonald Islands' },
103
+ { value: 'HN', label: 'Honduras' },
104
+ { value: 'HK', label: 'Hong Kong' },
105
+ { value: 'HU', label: 'Hungary' },
106
+ { value: 'IS', label: 'Iceland' },
107
+ { value: 'IN', label: 'India' },
108
+ { value: 'ID', label: 'Indonesia' },
109
+ { value: 'IR', label: 'Iran, Islamic Republic of' },
110
+ { value: 'IQ', label: 'Iraq' },
111
+ { value: 'IE', label: 'Ireland' },
112
+ { value: 'IM', label: 'Isle of Man' },
113
+ { value: 'IL', label: 'Israel' },
114
+ { value: 'IT', label: 'Italy' },
115
+ { value: 'JM', label: 'Jamaica' },
116
+ { value: 'JP', label: 'Japan' },
117
+ { value: 'JE', label: 'Jersey' },
118
+ { value: 'JO', label: 'Jordan' },
119
+ { value: 'KZ', label: 'Kazakhstan' },
120
+ { value: 'KE', label: 'Kenya' },
121
+ { value: 'KI', label: 'Kiribati' },
122
+ { value: 'KP', label: "Korea, Democratic People's Republic of" },
123
+ { value: 'KR', label: 'Korea, Republic of' },
124
+ { value: 'KW', label: 'Kuwait' },
125
+ { value: 'KG', label: 'Kyrgyzstan' },
126
+ { value: 'LA', label: "Lao People's Democratic Republic" },
127
+ { value: 'LV', label: 'Latvia' },
128
+ { value: 'LB', label: 'Lebanon' },
129
+ { value: 'LS', label: 'Lesotho' },
130
+ { value: 'LR', label: 'Liberia' },
131
+ { value: 'LY', label: 'Libya' },
132
+ { value: 'LI', label: 'Liechtenstein' },
133
+ { value: 'LT', label: 'Lithuania' },
134
+ { value: 'LU', label: 'Luxembourg' },
135
+ { value: 'MO', label: 'Macao' },
136
+ { value: 'MG', label: 'Madagascar' },
137
+ { value: 'MW', label: 'Malawi' },
138
+ { value: 'MY', label: 'Malaysia' },
139
+ { value: 'MV', label: 'Maldives' },
140
+ { value: 'ML', label: 'Mali' },
141
+ { value: 'MT', label: 'Malta' },
142
+ { value: 'MH', label: 'Marshall Islands' },
143
+ { value: 'MQ', label: 'Martinique' },
144
+ { value: 'MR', label: 'Mauritania' },
145
+ { value: 'MU', label: 'Mauritius' },
146
+ { value: 'YT', label: 'Mayotte' },
147
+ { value: 'MX', label: 'Mexico' },
148
+ { value: 'FM', label: 'Micronesia, Federated States of' },
149
+ { value: 'MD', label: 'Moldova, Republic of' },
150
+ { value: 'MC', label: 'Monaco' },
151
+ { value: 'MN', label: 'Mongolia' },
152
+ { value: 'ME', label: 'Montenegro' },
153
+ { value: 'MS', label: 'Montserrat' },
154
+ { value: 'MA', label: 'Morocco' },
155
+ { value: 'MZ', label: 'Mozambique' },
156
+ { value: 'MM', label: 'Myanmar' },
157
+ { value: 'NA', label: 'Namibia' },
158
+ { value: 'NR', label: 'Nauru' },
159
+ { value: 'NP', label: 'Nepal' },
160
+ { value: 'NL', label: 'Netherlands' },
161
+ { value: 'NC', label: 'New Caledonia' },
162
+ { value: 'NZ', label: 'New Zealand' },
163
+ { value: 'NI', label: 'Nicaragua' },
164
+ { value: 'NE', label: 'Niger' },
165
+ { value: 'NG', label: 'Nigeria' },
166
+ { value: 'NU', label: 'Niue' },
167
+ { value: 'NF', label: 'Norfolk Island' },
168
+ { value: 'MK', label: 'North Macedonia' },
169
+ { value: 'MP', label: 'Northern Mariana Islands' },
170
+ { value: 'NO', label: 'Norway' },
171
+ { value: 'OM', label: 'Oman' },
172
+ { value: 'PK', label: 'Pakistan' },
173
+ { value: 'PW', label: 'Palau' },
174
+ { value: 'PS', label: 'Palestine, State of' },
175
+ { value: 'PA', label: 'Panama' },
176
+ { value: 'PG', label: 'Papua New Guinea' },
177
+ { value: 'PY', label: 'Paraguay' },
178
+ { value: 'PE', label: 'Peru' },
179
+ { value: 'PH', label: 'Philippines' },
180
+ { value: 'PN', label: 'Pitcairn' },
181
+ { value: 'PL', label: 'Poland' },
182
+ { value: 'PT', label: 'Portugal' },
183
+ { value: 'PR', label: 'Puerto Rico' },
184
+ { value: 'QA', label: 'Qatar' },
185
+ { value: 'RE', label: 'Réunion' },
186
+ { value: 'RO', label: 'Romania' },
187
+ { value: 'RU', label: 'Russian Federation' },
188
+ { value: 'RW', label: 'Rwanda' },
189
+ { value: 'BL', label: 'Saint Barthélemy' },
190
+ { value: 'SH', label: 'Saint Helena, Ascension and Tristan da Cunha' },
191
+ { value: 'KN', label: 'Saint Kitts and Nevis' },
192
+ { value: 'LC', label: 'Saint Lucia' },
193
+ { value: 'MF', label: 'Saint Martin (French part)' },
194
+ { value: 'PM', label: 'Saint Pierre and Miquelon' },
195
+ { value: 'VC', label: 'Saint Vincent and the Grenadines' },
196
+ { value: 'WS', label: 'Samoa' },
197
+ { value: 'SM', label: 'San Marino' },
198
+ { value: 'ST', label: 'Sao Tome and Principe' },
199
+ { value: 'SA', label: 'Saudi Arabia' },
200
+ { value: 'SN', label: 'Senegal' },
201
+ { value: 'RS', label: 'Serbia' },
202
+ { value: 'SC', label: 'Seychelles' },
203
+ { value: 'SL', label: 'Sierra Leone' },
204
+ { value: 'SG', label: 'Singapore' },
205
+ { value: 'SX', label: 'Sint Maarten (Dutch part)' },
206
+ { value: 'SK', label: 'Slovakia' },
207
+ { value: 'SI', label: 'Slovenia' },
208
+ { value: 'SB', label: 'Solomon Islands' },
209
+ { value: 'SO', label: 'Somalia' },
210
+ { value: 'ZA', label: 'South Africa' },
211
+ { value: 'GS', label: 'South Georgia and the South Sandwich Islands' },
212
+ { value: 'SS', label: 'South Sudan' },
213
+ { value: 'ES', label: 'Spain' },
214
+ { value: 'LK', label: 'Sri Lanka' },
215
+ { value: 'SD', label: 'Sudan' },
216
+ { value: 'SR', label: 'Suriname' },
217
+ { value: 'SJ', label: 'Svalbard and Jan Mayen' },
218
+ { value: 'SZ', label: 'Swaziland' },
219
+ { value: 'SE', label: 'Sweden' },
220
+ { value: 'CH', label: 'Switzerland' },
221
+ { value: 'SY', label: 'Syrian Arab Republic' },
222
+ { value: 'TW', label: 'Taiwan, Province of China' },
223
+ { value: 'TJ', label: 'Tajikistan' },
224
+ { value: 'TZ', label: 'Tanzania, United Republic of' },
225
+ { value: 'TH', label: 'Thailand' },
226
+ { value: 'TL', label: 'Timor-Leste' },
227
+ { value: 'TG', label: 'Togo' },
228
+ { value: 'TK', label: 'Tokelau' },
229
+ { value: 'TO', label: 'Tonga' },
230
+ { value: 'TT', label: 'Trinidad and Tobago' },
231
+ { value: 'TN', label: 'Tunisia' },
232
+ { value: 'TR', label: 'Turkey' },
233
+ { value: 'TM', label: 'Turkmenistan' },
234
+ { value: 'TC', label: 'Turks and Caicos Islands' },
235
+ { value: 'TV', label: 'Tuvalu' },
236
+ { value: 'UG', label: 'Uganda' },
237
+ { value: 'UA', label: 'Ukraine' },
238
+ { value: 'AE', label: 'United Arab Emirates' },
239
+ { value: 'GB', label: 'United Kingdom' },
240
+ { value: 'US', label: 'United States' },
241
+ { value: 'UM', label: 'United States Minor Outlying Islands' },
242
+ { value: 'UY', label: 'Uruguay' },
243
+ { value: 'UZ', label: 'Uzbekistan' },
244
+ { value: 'VU', label: 'Vanuatu' },
245
+ { value: 'VE', label: 'Venezuela, Bolivarian Republic of' },
246
+ { value: 'VN', label: 'Viet Nam' },
247
+ { value: 'VG', label: 'Virgin Islands, British' },
248
+ { value: 'VI', label: 'Virgin Islands, U.S.' },
249
+ { value: 'WF', label: 'Wallis and Futuna' },
250
+ { value: 'EH', label: 'Western Sahara' },
251
+ { value: 'YE', label: 'Yemen' },
252
+ { value: 'ZM', label: 'Zambia' },
253
+ { value: 'ZW', label: 'Zimbabwe' },
254
+ ];
255
+
256
+ export default Countries;
@@ -47,6 +47,8 @@ let Project = class Project extends TenantModel {
47
47
  this.paymentProviderSubscriptionSeats = undefined;
48
48
  this.trialEndsAt = undefined;
49
49
  this.paymentProviderCustomerId = undefined;
50
+ this.businessDetails = undefined;
51
+ this.businessDetailsCountry = undefined;
50
52
  this.paymentProviderSubscriptionStatus = undefined;
51
53
  this.paymentProviderMeteredSubscriptionStatus = undefined;
52
54
  this.paymentProviderPromoCode = undefined;
@@ -285,6 +287,58 @@ __decorate([
285
287
  }),
286
288
  __metadata("design:type", String)
287
289
  ], Project.prototype, "paymentProviderCustomerId", void 0);
290
+ __decorate([
291
+ ColumnAccessControl({
292
+ create: [Permission.ProjectOwner, Permission.ManageProjectBilling],
293
+ read: [
294
+ Permission.ProjectOwner,
295
+ Permission.ProjectAdmin,
296
+ Permission.ProjectMember,
297
+ Permission.ReadProject,
298
+ Permission.UnAuthorizedSsoUser,
299
+ Permission.ProjectUser,
300
+ ],
301
+ update: [Permission.ProjectOwner, Permission.ManageProjectBilling],
302
+ }),
303
+ TableColumn({
304
+ type: TableColumnType.LongText,
305
+ title: "Business Details / Billing Address",
306
+ description: "Business legal name, address and any tax information to appear on invoices.",
307
+ }),
308
+ Column({
309
+ type: ColumnType.LongText,
310
+ length: ColumnLength.LongText,
311
+ nullable: true,
312
+ unique: false,
313
+ }),
314
+ __metadata("design:type", String)
315
+ ], Project.prototype, "businessDetails", void 0);
316
+ __decorate([
317
+ ColumnAccessControl({
318
+ create: [Permission.ProjectOwner, Permission.ManageProjectBilling],
319
+ read: [
320
+ Permission.ProjectOwner,
321
+ Permission.ProjectAdmin,
322
+ Permission.ProjectMember,
323
+ Permission.ReadProject,
324
+ Permission.UnAuthorizedSsoUser,
325
+ Permission.ProjectUser,
326
+ ],
327
+ update: [Permission.ProjectOwner, Permission.ManageProjectBilling],
328
+ }),
329
+ TableColumn({
330
+ type: TableColumnType.ShortText,
331
+ title: "Business Country (ISO Alpha-2)",
332
+ description: "Two-letter ISO country code for billing address (e.g., US, GB, DE).",
333
+ }),
334
+ Column({
335
+ type: ColumnType.ShortText,
336
+ length: ColumnLength.ShortText,
337
+ nullable: true,
338
+ unique: false,
339
+ }),
340
+ __metadata("design:type", String)
341
+ ], Project.prototype, "businessDetailsCountry", void 0);
288
342
  __decorate([
289
343
  ColumnAccessControl({
290
344
  create: [],