@voyantjs/pricing 0.1.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.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../src/schema.ts"],"names":[],"mappings":"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"}
package/dist/schema.js ADDED
@@ -0,0 +1,458 @@
1
+ import { typeId, typeIdRef } from "@voyantjs/db/lib/typeid-column";
2
+ import { relations } from "drizzle-orm";
3
+ import { boolean, date, index, integer, jsonb, pgEnum, pgTable, text, timestamp, uniqueIndex, } from "drizzle-orm/pg-core";
4
+ export const pricingCategoryTypeEnum = pgEnum("pricing_category_type", [
5
+ "adult",
6
+ "child",
7
+ "infant",
8
+ "senior",
9
+ "group",
10
+ "room",
11
+ "vehicle",
12
+ "service",
13
+ "other",
14
+ ]);
15
+ export const pricingDependencyTypeEnum = pgEnum("pricing_dependency_type", [
16
+ "requires",
17
+ "limits_per_master",
18
+ "limits_sum",
19
+ "excludes",
20
+ ]);
21
+ export const cancellationPolicyTypeEnum = pgEnum("cancellation_policy_type", [
22
+ "simple",
23
+ "advanced",
24
+ "non_refundable",
25
+ "custom",
26
+ ]);
27
+ export const cancellationChargeTypeEnum = pgEnum("cancellation_charge_type", [
28
+ "none",
29
+ "amount",
30
+ "percentage",
31
+ ]);
32
+ export const priceCatalogTypeEnum = pgEnum("price_catalog_type", [
33
+ "public",
34
+ "contract",
35
+ "net",
36
+ "gross",
37
+ "promo",
38
+ "internal",
39
+ "other",
40
+ ]);
41
+ export const optionPricingModeEnum = pgEnum("option_pricing_mode", [
42
+ "per_person",
43
+ "per_booking",
44
+ "starting_from",
45
+ "free",
46
+ "on_request",
47
+ ]);
48
+ export const optionUnitPricingModeEnum = pgEnum("option_unit_pricing_mode", [
49
+ "per_unit",
50
+ "per_person",
51
+ "per_booking",
52
+ "included",
53
+ "free",
54
+ "on_request",
55
+ ]);
56
+ export const optionStartTimeRuleModeEnum = pgEnum("option_start_time_rule_mode", [
57
+ "included",
58
+ "excluded",
59
+ "override",
60
+ "adjustment",
61
+ ]);
62
+ export const priceAdjustmentTypeEnum = pgEnum("price_adjustment_type", ["fixed", "percentage"]);
63
+ export const addonPricingModeEnum = pgEnum("addon_pricing_mode", [
64
+ "included",
65
+ "per_person",
66
+ "per_booking",
67
+ "on_request",
68
+ "unavailable",
69
+ ]);
70
+ export const pricingCategories = pgTable("pricing_categories", {
71
+ id: typeId("pricing_categories"),
72
+ productId: text("product_id"),
73
+ optionId: text("option_id"),
74
+ unitId: text("unit_id"),
75
+ code: text("code"),
76
+ name: text("name").notNull(),
77
+ categoryType: pricingCategoryTypeEnum("category_type").notNull().default("other"),
78
+ seatOccupancy: integer("seat_occupancy").notNull().default(1),
79
+ groupSize: integer("group_size"),
80
+ isAgeQualified: boolean("is_age_qualified").notNull().default(false),
81
+ minAge: integer("min_age"),
82
+ maxAge: integer("max_age"),
83
+ internalUseOnly: boolean("internal_use_only").notNull().default(false),
84
+ active: boolean("active").notNull().default(true),
85
+ sortOrder: integer("sort_order").notNull().default(0),
86
+ metadata: jsonb("metadata").$type(),
87
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
88
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
89
+ }, (table) => [
90
+ index("idx_pricing_categories_product").on(table.productId),
91
+ index("idx_pricing_categories_option").on(table.optionId),
92
+ index("idx_pricing_categories_unit").on(table.unitId),
93
+ index("idx_pricing_categories_type").on(table.categoryType),
94
+ index("idx_pricing_categories_active").on(table.active),
95
+ uniqueIndex("uidx_pricing_categories_option_code").on(table.optionId, table.code),
96
+ ]);
97
+ export const pricingCategoryDependencies = pgTable("pricing_category_dependencies", {
98
+ id: typeId("pricing_category_dependencies"),
99
+ pricingCategoryId: typeIdRef("pricing_category_id")
100
+ .notNull()
101
+ .references(() => pricingCategories.id, { onDelete: "cascade" }),
102
+ masterPricingCategoryId: typeIdRef("master_pricing_category_id")
103
+ .notNull()
104
+ .references(() => pricingCategories.id, { onDelete: "cascade" }),
105
+ dependencyType: pricingDependencyTypeEnum("dependency_type").notNull().default("requires"),
106
+ maxPerMaster: integer("max_per_master"),
107
+ maxDependentSum: integer("max_dependent_sum"),
108
+ active: boolean("active").notNull().default(true),
109
+ notes: text("notes"),
110
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
111
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
112
+ }, (table) => [
113
+ index("idx_pricing_category_dependencies_category").on(table.pricingCategoryId),
114
+ index("idx_pricing_category_dependencies_master").on(table.masterPricingCategoryId),
115
+ uniqueIndex("uidx_pricing_category_dependencies_pair_type").on(table.pricingCategoryId, table.masterPricingCategoryId, table.dependencyType),
116
+ ]);
117
+ export const cancellationPolicies = pgTable("cancellation_policies", {
118
+ id: typeId("cancellation_policies"),
119
+ code: text("code"),
120
+ name: text("name").notNull(),
121
+ policyType: cancellationPolicyTypeEnum("policy_type").notNull().default("custom"),
122
+ simpleCutoffHours: integer("simple_cutoff_hours"),
123
+ isDefault: boolean("is_default").notNull().default(false),
124
+ active: boolean("active").notNull().default(true),
125
+ notes: text("notes"),
126
+ metadata: jsonb("metadata").$type(),
127
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
128
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
129
+ }, (table) => [
130
+ index("idx_cancellation_policies_active").on(table.active),
131
+ index("idx_cancellation_policies_default").on(table.isDefault),
132
+ uniqueIndex("uidx_cancellation_policies_code").on(table.code),
133
+ ]);
134
+ export const cancellationPolicyRules = pgTable("cancellation_policy_rules", {
135
+ id: typeId("cancellation_policy_rules"),
136
+ cancellationPolicyId: typeIdRef("cancellation_policy_id")
137
+ .notNull()
138
+ .references(() => cancellationPolicies.id, { onDelete: "cascade" }),
139
+ sortOrder: integer("sort_order").notNull().default(0),
140
+ cutoffMinutesBefore: integer("cutoff_minutes_before"),
141
+ chargeType: cancellationChargeTypeEnum("charge_type").notNull().default("none"),
142
+ chargeAmountCents: integer("charge_amount_cents"),
143
+ chargePercentBasisPoints: integer("charge_percent_basis_points"),
144
+ active: boolean("active").notNull().default(true),
145
+ notes: text("notes"),
146
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
147
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
148
+ }, (table) => [
149
+ index("idx_cancellation_policy_rules_policy").on(table.cancellationPolicyId),
150
+ index("idx_cancellation_policy_rules_active").on(table.active),
151
+ ]);
152
+ export const priceCatalogs = pgTable("price_catalogs", {
153
+ id: typeId("price_catalogs"),
154
+ code: text("code").notNull(),
155
+ name: text("name").notNull(),
156
+ currencyCode: text("currency_code"),
157
+ catalogType: priceCatalogTypeEnum("catalog_type").notNull().default("public"),
158
+ isDefault: boolean("is_default").notNull().default(false),
159
+ active: boolean("active").notNull().default(true),
160
+ notes: text("notes"),
161
+ metadata: jsonb("metadata").$type(),
162
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
163
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
164
+ }, (table) => [
165
+ uniqueIndex("uidx_price_catalogs_code").on(table.code),
166
+ index("idx_price_catalogs_currency").on(table.currencyCode),
167
+ index("idx_price_catalogs_type").on(table.catalogType),
168
+ index("idx_price_catalogs_active").on(table.active),
169
+ ]);
170
+ export const priceSchedules = pgTable("price_schedules", {
171
+ id: typeId("price_schedules"),
172
+ priceCatalogId: typeIdRef("price_catalog_id")
173
+ .notNull()
174
+ .references(() => priceCatalogs.id, { onDelete: "cascade" }),
175
+ code: text("code"),
176
+ name: text("name").notNull(),
177
+ recurrenceRule: text("recurrence_rule").notNull(),
178
+ timezone: text("timezone"),
179
+ validFrom: date("valid_from"),
180
+ validTo: date("valid_to"),
181
+ weekdays: jsonb("weekdays").$type(),
182
+ priority: integer("priority").notNull().default(0),
183
+ active: boolean("active").notNull().default(true),
184
+ notes: text("notes"),
185
+ metadata: jsonb("metadata").$type(),
186
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
187
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
188
+ }, (table) => [
189
+ index("idx_price_schedules_catalog").on(table.priceCatalogId),
190
+ index("idx_price_schedules_active").on(table.active),
191
+ uniqueIndex("uidx_price_schedules_catalog_code").on(table.priceCatalogId, table.code),
192
+ ]);
193
+ export const optionPriceRules = pgTable("option_price_rules", {
194
+ id: typeId("option_price_rules"),
195
+ productId: text("product_id").notNull(),
196
+ optionId: text("option_id").notNull(),
197
+ priceCatalogId: typeIdRef("price_catalog_id")
198
+ .notNull()
199
+ .references(() => priceCatalogs.id, { onDelete: "cascade" }),
200
+ priceScheduleId: typeIdRef("price_schedule_id").references(() => priceSchedules.id, {
201
+ onDelete: "set null",
202
+ }),
203
+ cancellationPolicyId: typeIdRef("cancellation_policy_id").references(() => cancellationPolicies.id, { onDelete: "set null" }),
204
+ code: text("code"),
205
+ name: text("name").notNull(),
206
+ description: text("description"),
207
+ pricingMode: optionPricingModeEnum("pricing_mode").notNull().default("per_person"),
208
+ baseSellAmountCents: integer("base_sell_amount_cents"),
209
+ baseCostAmountCents: integer("base_cost_amount_cents"),
210
+ minPerBooking: integer("min_per_booking"),
211
+ maxPerBooking: integer("max_per_booking"),
212
+ allPricingCategories: boolean("all_pricing_categories").notNull().default(true),
213
+ isDefault: boolean("is_default").notNull().default(false),
214
+ active: boolean("active").notNull().default(true),
215
+ notes: text("notes"),
216
+ metadata: jsonb("metadata").$type(),
217
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
218
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
219
+ }, (table) => [
220
+ index("idx_option_price_rules_product").on(table.productId),
221
+ index("idx_option_price_rules_option").on(table.optionId),
222
+ index("idx_option_price_rules_catalog").on(table.priceCatalogId),
223
+ index("idx_option_price_rules_schedule").on(table.priceScheduleId),
224
+ index("idx_option_price_rules_policy").on(table.cancellationPolicyId),
225
+ index("idx_option_price_rules_active").on(table.active),
226
+ uniqueIndex("uidx_option_price_rules_option_code").on(table.optionId, table.code),
227
+ ]);
228
+ export const optionUnitPriceRules = pgTable("option_unit_price_rules", {
229
+ id: typeId("option_unit_price_rules"),
230
+ optionPriceRuleId: typeIdRef("option_price_rule_id")
231
+ .notNull()
232
+ .references(() => optionPriceRules.id, { onDelete: "cascade" }),
233
+ optionId: text("option_id").notNull(),
234
+ unitId: text("unit_id").notNull(),
235
+ pricingCategoryId: typeIdRef("pricing_category_id").references(() => pricingCategories.id, {
236
+ onDelete: "set null",
237
+ }),
238
+ pricingMode: optionUnitPricingModeEnum("pricing_mode").notNull().default("per_unit"),
239
+ sellAmountCents: integer("sell_amount_cents"),
240
+ costAmountCents: integer("cost_amount_cents"),
241
+ minQuantity: integer("min_quantity"),
242
+ maxQuantity: integer("max_quantity"),
243
+ active: boolean("active").notNull().default(true),
244
+ sortOrder: integer("sort_order").notNull().default(0),
245
+ notes: text("notes"),
246
+ metadata: jsonb("metadata").$type(),
247
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
248
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
249
+ }, (table) => [
250
+ index("idx_option_unit_price_rules_rule").on(table.optionPriceRuleId),
251
+ index("idx_option_unit_price_rules_option").on(table.optionId),
252
+ index("idx_option_unit_price_rules_unit").on(table.unitId),
253
+ index("idx_option_unit_price_rules_category").on(table.pricingCategoryId),
254
+ index("idx_option_unit_price_rules_active").on(table.active),
255
+ ]);
256
+ export const optionStartTimeRules = pgTable("option_start_time_rules", {
257
+ id: typeId("option_start_time_rules"),
258
+ optionPriceRuleId: typeIdRef("option_price_rule_id")
259
+ .notNull()
260
+ .references(() => optionPriceRules.id, { onDelete: "cascade" }),
261
+ optionId: text("option_id").notNull(),
262
+ startTimeId: text("start_time_id").notNull(),
263
+ ruleMode: optionStartTimeRuleModeEnum("rule_mode").notNull().default("included"),
264
+ adjustmentType: priceAdjustmentTypeEnum("adjustment_type"),
265
+ sellAdjustmentCents: integer("sell_adjustment_cents"),
266
+ costAdjustmentCents: integer("cost_adjustment_cents"),
267
+ adjustmentBasisPoints: integer("adjustment_basis_points"),
268
+ active: boolean("active").notNull().default(true),
269
+ notes: text("notes"),
270
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
271
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
272
+ }, (table) => [
273
+ index("idx_option_start_time_rules_rule").on(table.optionPriceRuleId),
274
+ index("idx_option_start_time_rules_option").on(table.optionId),
275
+ index("idx_option_start_time_rules_start_time").on(table.startTimeId),
276
+ uniqueIndex("uidx_option_start_time_rules_rule_start_time").on(table.optionPriceRuleId, table.startTimeId),
277
+ ]);
278
+ export const optionUnitTiers = pgTable("option_unit_tiers", {
279
+ id: typeId("option_unit_tiers"),
280
+ optionUnitPriceRuleId: typeIdRef("option_unit_price_rule_id")
281
+ .notNull()
282
+ .references(() => optionUnitPriceRules.id, { onDelete: "cascade" }),
283
+ minQuantity: integer("min_quantity").notNull(),
284
+ maxQuantity: integer("max_quantity"),
285
+ sellAmountCents: integer("sell_amount_cents"),
286
+ costAmountCents: integer("cost_amount_cents"),
287
+ active: boolean("active").notNull().default(true),
288
+ sortOrder: integer("sort_order").notNull().default(0),
289
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
290
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
291
+ }, (table) => [
292
+ index("idx_option_unit_tiers_rule").on(table.optionUnitPriceRuleId),
293
+ index("idx_option_unit_tiers_active").on(table.active),
294
+ ]);
295
+ export const pickupPriceRules = pgTable("pickup_price_rules", {
296
+ id: typeId("pickup_price_rules"),
297
+ optionPriceRuleId: typeIdRef("option_price_rule_id")
298
+ .notNull()
299
+ .references(() => optionPriceRules.id, { onDelete: "cascade" }),
300
+ optionId: text("option_id").notNull(),
301
+ pickupPointId: text("pickup_point_id").notNull(),
302
+ pricingMode: addonPricingModeEnum("pricing_mode").notNull().default("included"),
303
+ sellAmountCents: integer("sell_amount_cents"),
304
+ costAmountCents: integer("cost_amount_cents"),
305
+ active: boolean("active").notNull().default(true),
306
+ sortOrder: integer("sort_order").notNull().default(0),
307
+ notes: text("notes"),
308
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
309
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
310
+ }, (table) => [
311
+ index("idx_pickup_price_rules_rule").on(table.optionPriceRuleId),
312
+ index("idx_pickup_price_rules_option").on(table.optionId),
313
+ index("idx_pickup_price_rules_pickup").on(table.pickupPointId),
314
+ uniqueIndex("uidx_pickup_price_rules_rule_pickup").on(table.optionPriceRuleId, table.pickupPointId),
315
+ ]);
316
+ export const dropoffPriceRules = pgTable("dropoff_price_rules", {
317
+ id: typeId("dropoff_price_rules"),
318
+ optionPriceRuleId: typeIdRef("option_price_rule_id")
319
+ .notNull()
320
+ .references(() => optionPriceRules.id, { onDelete: "cascade" }),
321
+ optionId: text("option_id").notNull(),
322
+ facilityId: text("facility_id"),
323
+ dropoffCode: text("dropoff_code"),
324
+ dropoffName: text("dropoff_name").notNull(),
325
+ pricingMode: addonPricingModeEnum("pricing_mode").notNull().default("included"),
326
+ sellAmountCents: integer("sell_amount_cents"),
327
+ costAmountCents: integer("cost_amount_cents"),
328
+ active: boolean("active").notNull().default(true),
329
+ sortOrder: integer("sort_order").notNull().default(0),
330
+ notes: text("notes"),
331
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
332
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
333
+ }, (table) => [
334
+ index("idx_dropoff_price_rules_rule").on(table.optionPriceRuleId),
335
+ index("idx_dropoff_price_rules_option").on(table.optionId),
336
+ index("idx_dropoff_price_rules_facility").on(table.facilityId),
337
+ ]);
338
+ export const extraPriceRules = pgTable("extra_price_rules", {
339
+ id: typeId("extra_price_rules"),
340
+ optionPriceRuleId: typeIdRef("option_price_rule_id")
341
+ .notNull()
342
+ .references(() => optionPriceRules.id, { onDelete: "cascade" }),
343
+ optionId: text("option_id").notNull(),
344
+ productExtraId: text("product_extra_id"),
345
+ optionExtraConfigId: text("option_extra_config_id"),
346
+ pricingMode: addonPricingModeEnum("pricing_mode").notNull().default("included"),
347
+ sellAmountCents: integer("sell_amount_cents"),
348
+ costAmountCents: integer("cost_amount_cents"),
349
+ active: boolean("active").notNull().default(true),
350
+ sortOrder: integer("sort_order").notNull().default(0),
351
+ notes: text("notes"),
352
+ metadata: jsonb("metadata").$type(),
353
+ createdAt: timestamp("created_at", { withTimezone: true }).notNull().defaultNow(),
354
+ updatedAt: timestamp("updated_at", { withTimezone: true }).notNull().defaultNow(),
355
+ }, (table) => [
356
+ index("idx_extra_price_rules_rule").on(table.optionPriceRuleId),
357
+ index("idx_extra_price_rules_option").on(table.optionId),
358
+ index("idx_extra_price_rules_product_extra").on(table.productExtraId),
359
+ index("idx_extra_price_rules_option_extra_config").on(table.optionExtraConfigId),
360
+ ]);
361
+ export const pricingCategoriesRelations = relations(pricingCategories, ({ many }) => ({
362
+ childDependencies: many(pricingCategoryDependencies, { relationName: "pricingCategoryChild" }),
363
+ masterDependencies: many(pricingCategoryDependencies, { relationName: "pricingCategoryMaster" }),
364
+ unitPriceRules: many(optionUnitPriceRules),
365
+ }));
366
+ export const pricingCategoryDependenciesRelations = relations(pricingCategoryDependencies, ({ one }) => ({
367
+ pricingCategory: one(pricingCategories, {
368
+ relationName: "pricingCategoryChild",
369
+ fields: [pricingCategoryDependencies.pricingCategoryId],
370
+ references: [pricingCategories.id],
371
+ }),
372
+ masterPricingCategory: one(pricingCategories, {
373
+ relationName: "pricingCategoryMaster",
374
+ fields: [pricingCategoryDependencies.masterPricingCategoryId],
375
+ references: [pricingCategories.id],
376
+ }),
377
+ }));
378
+ export const cancellationPoliciesRelations = relations(cancellationPolicies, ({ many }) => ({
379
+ rules: many(cancellationPolicyRules),
380
+ optionPriceRules: many(optionPriceRules),
381
+ }));
382
+ export const cancellationPolicyRulesRelations = relations(cancellationPolicyRules, ({ one }) => ({
383
+ cancellationPolicy: one(cancellationPolicies, {
384
+ fields: [cancellationPolicyRules.cancellationPolicyId],
385
+ references: [cancellationPolicies.id],
386
+ }),
387
+ }));
388
+ export const priceCatalogsRelations = relations(priceCatalogs, ({ many }) => ({
389
+ schedules: many(priceSchedules),
390
+ optionPriceRules: many(optionPriceRules),
391
+ }));
392
+ export const priceSchedulesRelations = relations(priceSchedules, ({ one, many }) => ({
393
+ priceCatalog: one(priceCatalogs, {
394
+ fields: [priceSchedules.priceCatalogId],
395
+ references: [priceCatalogs.id],
396
+ }),
397
+ optionPriceRules: many(optionPriceRules),
398
+ }));
399
+ export const optionPriceRulesRelations = relations(optionPriceRules, ({ one, many }) => ({
400
+ priceCatalog: one(priceCatalogs, {
401
+ fields: [optionPriceRules.priceCatalogId],
402
+ references: [priceCatalogs.id],
403
+ }),
404
+ priceSchedule: one(priceSchedules, {
405
+ fields: [optionPriceRules.priceScheduleId],
406
+ references: [priceSchedules.id],
407
+ }),
408
+ cancellationPolicy: one(cancellationPolicies, {
409
+ fields: [optionPriceRules.cancellationPolicyId],
410
+ references: [cancellationPolicies.id],
411
+ }),
412
+ unitRules: many(optionUnitPriceRules),
413
+ startTimeRules: many(optionStartTimeRules),
414
+ pickupRules: many(pickupPriceRules),
415
+ dropoffRules: many(dropoffPriceRules),
416
+ extraRules: many(extraPriceRules),
417
+ }));
418
+ export const optionUnitPriceRulesRelations = relations(optionUnitPriceRules, ({ one, many }) => ({
419
+ optionPriceRule: one(optionPriceRules, {
420
+ fields: [optionUnitPriceRules.optionPriceRuleId],
421
+ references: [optionPriceRules.id],
422
+ }),
423
+ pricingCategory: one(pricingCategories, {
424
+ fields: [optionUnitPriceRules.pricingCategoryId],
425
+ references: [pricingCategories.id],
426
+ }),
427
+ tiers: many(optionUnitTiers),
428
+ }));
429
+ export const optionStartTimeRulesRelations = relations(optionStartTimeRules, ({ one }) => ({
430
+ optionPriceRule: one(optionPriceRules, {
431
+ fields: [optionStartTimeRules.optionPriceRuleId],
432
+ references: [optionPriceRules.id],
433
+ }),
434
+ }));
435
+ export const optionUnitTiersRelations = relations(optionUnitTiers, ({ one }) => ({
436
+ optionUnitPriceRule: one(optionUnitPriceRules, {
437
+ fields: [optionUnitTiers.optionUnitPriceRuleId],
438
+ references: [optionUnitPriceRules.id],
439
+ }),
440
+ }));
441
+ export const pickupPriceRulesRelations = relations(pickupPriceRules, ({ one }) => ({
442
+ optionPriceRule: one(optionPriceRules, {
443
+ fields: [pickupPriceRules.optionPriceRuleId],
444
+ references: [optionPriceRules.id],
445
+ }),
446
+ }));
447
+ export const dropoffPriceRulesRelations = relations(dropoffPriceRules, ({ one }) => ({
448
+ optionPriceRule: one(optionPriceRules, {
449
+ fields: [dropoffPriceRules.optionPriceRuleId],
450
+ references: [optionPriceRules.id],
451
+ }),
452
+ }));
453
+ export const extraPriceRulesRelations = relations(extraPriceRules, ({ one }) => ({
454
+ optionPriceRule: one(optionPriceRules, {
455
+ fields: [extraPriceRules.optionPriceRuleId],
456
+ references: [optionPriceRules.id],
457
+ }),
458
+ }));