billing invoice

This commit is contained in:
root
2026-05-25 05:35:55 -04:00
parent 8d0b7a5ceb
commit 33b6bb55f0
12 changed files with 5434 additions and 645 deletions
+613 -205
View File
@@ -52,6 +52,99 @@ enum InvoiceStatus {
VOIDED
}
enum BillingInvoiceTerms {
DUE_ON_RECEIPT
NET_7
NET_15
NET_30
NET_45
NET_60
}
enum BillingInvoiceStatus {
DRAFT
OPEN
PAID
PARTIALLY_PAID
PAYMENT_PENDING
PAST_DUE
VOID
UNCOLLECTIBLE
REFUNDED
PARTIALLY_REFUNDED
}
enum BillingInvoiceType {
SUBSCRIPTION_INITIAL
SUBSCRIPTION_RENEWAL
TRIAL_CONVERSION
SUBSCRIPTION_UPGRADE
SUBSCRIPTION_DOWNGRADE_CREDIT
USAGE_BASED
ONE_TIME
MANUAL
CORRECTION
CANCELLATION_FEE
}
enum BillingLineItemType {
SUBSCRIPTION_FEE
SEAT_FEE
USAGE_FEE
SETUP_FEE
DISCOUNT
TAX
CREDIT
PRORATION
REFUND_ADJUSTMENT
MANUAL_ADJUSTMENT
PROFESSIONAL_SERVICES
CANCELLATION_FEE
}
enum BillingPaymentMethodType {
CARD
ACH_DEBIT
BANK_TRANSFER
WIRE_TRANSFER
MANUAL_INVOICE
PURCHASE_ORDER
}
enum BillingPaymentIntentStatus {
REQUIRES_PAYMENT_METHOD
REQUIRES_CONFIRMATION
REQUIRES_ACTION
PROCESSING
SUCCEEDED
FAILED
CANCELED
REFUNDED
PARTIALLY_REFUNDED
}
enum BillingPaymentAttemptStatus {
PENDING
PROCESSING
SUCCEEDED
FAILED
CANCELED
REFUNDED
PARTIALLY_REFUNDED
}
enum BillingRefundStatus {
PENDING
SUCCEEDED
FAILED
}
enum BillingCreditNoteStatus {
ISSUED
APPLIED
VOID
}
enum PaymentProvider {
AMANPAY
PAYPAL
@@ -340,54 +433,59 @@ model Company {
subscriptionPaymentRef String?
apiKey String @unique @default(cuid())
subscription Subscription?
brand BrandSettings?
employees Employee[]
vehicles Vehicle[]
offers Offer[]
reservations Reservation[]
customers Customer[]
rentalPayments RentalPayment[]
subscriptionInvoices SubscriptionInvoice[]
contractSettings ContractSettings?
accountingSettings AccountingSettings?
insurancePolicies InsurancePolicy[]
pricingRules PricingRule[]
notifications Notification[] @relation("CompanyNotifications")
subscription Subscription?
billingAccounts BillingAccount[]
billingInvoices BillingInvoice[]
brand BrandSettings?
employees Employee[]
vehicles Vehicle[]
offers Offer[]
reservations Reservation[]
customers Customer[]
rentalPayments RentalPayment[]
subscriptionInvoices SubscriptionInvoice[]
contractSettings ContractSettings?
accountingSettings AccountingSettings?
insurancePolicies InsurancePolicy[]
pricingRules PricingRule[]
notifications Notification[] @relation("CompanyNotifications")
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
BillingEvent BillingEvent[]
@@map("companies")
}
model Subscription {
id String @id @default(cuid())
companyId String @unique
company Company @relation(fields: [companyId], references: [id], onDelete: Cascade)
plan Plan @default(STARTER)
billingPeriod BillingPeriod @default(MONTHLY)
status SubscriptionStatus @default(TRIALING)
currency String @default("MAD")
trialStartAt DateTime?
trialEndAt DateTime?
trialUsed Boolean @default(false)
currentPeriodStart DateTime?
currentPeriodEnd DateTime?
paymentPendingSince DateTime?
paymentDueAt DateTime?
pastDueSince DateTime?
suspendedAt DateTime?
endedAt DateTime?
cancelledAt DateTime?
cancelAtPeriodEnd Boolean @default(false)
retryCount Int @default(0)
maxRetryCount Int @default(5)
invoices SubscriptionInvoice[]
events SubscriptionEvent[]
id String @id @default(cuid())
companyId String @unique
company Company @relation(fields: [companyId], references: [id], onDelete: Cascade)
plan Plan @default(STARTER)
billingPeriod BillingPeriod @default(MONTHLY)
status SubscriptionStatus @default(TRIALING)
currency String @default("MAD")
trialStartAt DateTime?
trialEndAt DateTime?
trialUsed Boolean @default(false)
currentPeriodStart DateTime?
currentPeriodEnd DateTime?
paymentPendingSince DateTime?
paymentDueAt DateTime?
pastDueSince DateTime?
suspendedAt DateTime?
endedAt DateTime?
cancelledAt DateTime?
cancelAtPeriodEnd Boolean @default(false)
retryCount Int @default(0)
maxRetryCount Int @default(5)
invoices SubscriptionInvoice[]
billingInvoices BillingInvoice[]
events SubscriptionEvent[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
BillingEvent BillingEvent[]
@@map("subscriptions")
}
@@ -421,6 +519,8 @@ model SubscriptionInvoice {
amanpayTransactionId String? @unique
paypalCaptureId String? @unique
paymentProvider PaymentProvider @default(AMANPAY)
billingInvoiceId String? @unique
billingInvoice BillingInvoice? @relation(fields: [billingInvoiceId], references: [id])
dueAt DateTime?
paidAt DateTime?
failedAt DateTime?
@@ -433,6 +533,314 @@ model SubscriptionInvoice {
@@map("subscription_invoices")
}
model BillingAccount {
id String @id @default(cuid())
companyId String
company Company @relation(fields: [companyId], references: [id], onDelete: Cascade)
isPrimary Boolean @default(true)
legalName String
billingEmail String
billingAddress Json?
taxId String?
taxExempt Boolean @default(false)
defaultCurrency String @default("MAD")
defaultPaymentMethodId String?
defaultPaymentMethod BillingPaymentMethod? @relation("BillingAccountDefaultPaymentMethod", fields: [defaultPaymentMethodId], references: [id])
invoiceTerms BillingInvoiceTerms @default(DUE_ON_RECEIPT)
netTermsDays Int @default(0)
providerCustomerId String?
dunningPaused Boolean @default(false)
dunningPausedAt DateTime?
dunningPausedBy String?
metadata Json @default("{}")
paymentMethods BillingPaymentMethod[] @relation("BillingAccountPaymentMethods")
invoices BillingInvoice[]
paymentIntents BillingPaymentIntent[]
paymentAttempts BillingPaymentAttempt[]
creditBalances BillingCreditBalance[]
creditLedgerEntries BillingCreditLedgerEntry[]
creditNotes BillingCreditNote[]
refunds BillingRefund[]
events BillingEvent[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([companyId])
@@index([companyId, isPrimary])
@@map("billing_accounts")
}
model BillingPaymentMethod {
id String @id @default(cuid())
billingAccountId String
billingAccount BillingAccount @relation("BillingAccountPaymentMethods", fields: [billingAccountId], references: [id], onDelete: Cascade)
type BillingPaymentMethodType
providerPaymentMethodId String?
label String?
brand String?
last4 String?
expMonth Int?
expYear Int?
isDefault Boolean @default(false)
isActive Boolean @default(true)
metadata Json @default("{}")
defaultForBillingAccounts BillingAccount[] @relation("BillingAccountDefaultPaymentMethod")
paymentIntents BillingPaymentIntent[]
paymentAttempts BillingPaymentAttempt[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([billingAccountId])
@@map("billing_payment_methods")
}
model BillingInvoice {
id String @id @default(cuid())
billingAccountId String
billingAccount BillingAccount @relation(fields: [billingAccountId], references: [id], onDelete: Cascade)
companyId String
company Company @relation(fields: [companyId], references: [id], onDelete: Cascade)
subscriptionId String?
subscription Subscription? @relation(fields: [subscriptionId], references: [id])
legacySubscriptionInvoice SubscriptionInvoice?
invoiceNumber String? @unique
invoiceSequence Int? @unique
invoiceType BillingInvoiceType
status BillingInvoiceStatus @default(DRAFT)
currency String @default("MAD")
subtotalAmount Int @default(0)
discountAmount Int @default(0)
creditAmount Int @default(0)
taxAmount Int @default(0)
totalAmount Int @default(0)
amountPaid Int @default(0)
amountDue Int @default(0)
invoiceDate DateTime?
dueAt DateTime?
finalizedAt DateTime?
paidAt DateTime?
voidedAt DateTime?
markedUncollectibleAt DateTime?
billingName String?
billingEmail String?
billingAddress Json?
providerInvoiceId String?
paymentProvider PaymentProvider?
isSubscriptionBlocking Boolean @default(false)
adminReason String?
metadata Json @default("{}")
createdByAdminId String?
lineItems BillingInvoiceLineItem[]
paymentIntents BillingPaymentIntent[]
paymentAttempts BillingPaymentAttempt[]
taxRecords BillingTaxRecord[]
creditNotes BillingCreditNote[]
refunds BillingRefund[]
events BillingEvent[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
BillingCreditLedgerEntry BillingCreditLedgerEntry[]
@@index([billingAccountId])
@@index([companyId])
@@index([subscriptionId])
@@map("billing_invoices")
}
model BillingInvoiceLineItem {
id String @id @default(cuid())
invoiceId String
invoice BillingInvoice @relation(fields: [invoiceId], references: [id], onDelete: Cascade)
subscriptionId String?
plan Plan?
type BillingLineItemType
description String
quantity Int @default(1)
unitAmount Int
amount Int
currency String @default("MAD")
periodStart DateTime?
periodEnd DateTime?
metadata Json @default("{}")
createdAt DateTime @default(now())
@@index([invoiceId])
@@map("billing_invoice_line_items")
}
model BillingPaymentIntent {
id String @id @default(cuid())
invoiceId String
invoice BillingInvoice @relation(fields: [invoiceId], references: [id], onDelete: Cascade)
billingAccountId String
billingAccount BillingAccount @relation(fields: [billingAccountId], references: [id], onDelete: Cascade)
paymentMethodId String?
paymentMethod BillingPaymentMethod? @relation(fields: [paymentMethodId], references: [id])
providerPaymentIntentId String?
status BillingPaymentIntentStatus @default(REQUIRES_PAYMENT_METHOD)
amount Int
currency String @default("MAD")
metadata Json @default("{}")
paymentAttempts BillingPaymentAttempt[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([invoiceId])
@@index([billingAccountId])
@@map("billing_payment_intents")
}
model BillingPaymentAttempt {
id String @id @default(cuid())
invoiceId String
invoice BillingInvoice @relation(fields: [invoiceId], references: [id], onDelete: Cascade)
billingAccountId String
billingAccount BillingAccount @relation(fields: [billingAccountId], references: [id], onDelete: Cascade)
paymentIntentId String?
paymentIntent BillingPaymentIntent? @relation(fields: [paymentIntentId], references: [id])
paymentMethodId String?
paymentMethod BillingPaymentMethod? @relation(fields: [paymentMethodId], references: [id])
providerPaymentId String?
status BillingPaymentAttemptStatus
amount Int
currency String @default("MAD")
failureCode String?
failureMessage String?
attemptedAt DateTime
metadata Json @default("{}")
refunds BillingRefund[]
createdAt DateTime @default(now())
@@index([invoiceId])
@@index([billingAccountId])
@@map("billing_payment_attempts")
}
model BillingCreditBalance {
id String @id @default(cuid())
billingAccountId String
billingAccount BillingAccount @relation(fields: [billingAccountId], references: [id], onDelete: Cascade)
currency String @default("MAD")
balanceAmount Int @default(0)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@unique([billingAccountId, currency])
@@map("billing_credit_balances")
}
model BillingCreditLedgerEntry {
id String @id @default(cuid())
billingAccountId String
billingAccount BillingAccount @relation(fields: [billingAccountId], references: [id], onDelete: Cascade)
invoiceId String?
invoice BillingInvoice? @relation(fields: [invoiceId], references: [id], onDelete: SetNull)
type String
amount Int
currency String @default("MAD")
reason String
createdBy String?
metadata Json @default("{}")
createdAt DateTime @default(now())
@@index([billingAccountId])
@@map("billing_credit_ledger_entries")
}
model BillingCreditNote {
id String @id @default(cuid())
invoiceId String
invoice BillingInvoice @relation(fields: [invoiceId], references: [id], onDelete: Cascade)
billingAccountId String
billingAccount BillingAccount @relation(fields: [billingAccountId], references: [id], onDelete: Cascade)
amount Int
currency String @default("MAD")
reason String
status BillingCreditNoteStatus @default(ISSUED)
createdBy String?
metadata Json @default("{}")
createdAt DateTime @default(now())
@@index([invoiceId])
@@index([billingAccountId])
@@map("billing_credit_notes")
}
model BillingRefund {
id String @id @default(cuid())
invoiceId String
invoice BillingInvoice @relation(fields: [invoiceId], references: [id], onDelete: Cascade)
paymentAttemptId String?
paymentAttempt BillingPaymentAttempt? @relation(fields: [paymentAttemptId], references: [id], onDelete: SetNull)
billingAccountId String
billingAccount BillingAccount @relation(fields: [billingAccountId], references: [id], onDelete: Cascade)
amount Int
currency String @default("MAD")
reason String
status BillingRefundStatus @default(PENDING)
providerRefundId String?
createdBy String?
metadata Json @default("{}")
createdAt DateTime @default(now())
@@index([invoiceId])
@@index([billingAccountId])
@@map("billing_refunds")
}
model BillingTaxRecord {
id String @id @default(cuid())
invoiceId String
invoice BillingInvoice @relation(fields: [invoiceId], references: [id], onDelete: Cascade)
jurisdiction String?
taxRate Float?
taxAmount Int
taxType String?
taxExempt Boolean @default(false)
exemptionReason String?
providerTaxId String?
metadata Json @default("{}")
createdAt DateTime @default(now())
@@index([invoiceId])
@@map("billing_tax_records")
}
model BillingEvent {
id String @id @default(cuid())
billingAccountId String?
billingAccount BillingAccount? @relation(fields: [billingAccountId], references: [id], onDelete: SetNull)
invoiceId String?
invoice BillingInvoice? @relation(fields: [invoiceId], references: [id], onDelete: SetNull)
subscriptionId String?
subscription Subscription? @relation(fields: [subscriptionId], references: [id], onDelete: SetNull)
companyId String?
company Company? @relation(fields: [companyId], references: [id], onDelete: SetNull)
eventType String
source String
payload Json @default("{}")
occurredAt DateTime
createdAt DateTime @default(now())
@@index([billingAccountId])
@@index([invoiceId])
@@index([subscriptionId])
@@index([companyId])
@@map("billing_events")
}
model PaymentAttempt {
id String @id @default(cuid())
invoiceId String
@@ -450,19 +858,19 @@ model PaymentAttempt {
}
model BrandSettings {
id String @id @default(cuid())
companyId String @unique
company Company @relation(fields: [companyId], references: [id], onDelete: Cascade)
id String @id @default(cuid())
companyId String @unique
company Company @relation(fields: [companyId], references: [id], onDelete: Cascade)
displayName String
tagline String?
logoUrl String?
faviconUrl String?
heroImageUrl String?
primaryColor String @default("#1A56DB")
accentColor String @default("#F59E0B")
subdomain String @unique
customDomain String? @unique
customDomainVerified Boolean @default(false)
primaryColor String @default("#1A56DB")
accentColor String @default("#F59E0B")
subdomain String @unique
customDomain String? @unique
customDomainVerified Boolean @default(false)
customDomainAddedAt DateTime?
publicEmail String?
publicPhone String?
@@ -473,17 +881,17 @@ model BrandSettings {
whatsappNumber String?
facebookUrl String?
instagramUrl String?
defaultLocale String @default("en")
defaultCurrency String @default("MAD")
defaultLocale String @default("en")
defaultCurrency String @default("MAD")
amanpayMerchantId String?
amanpaySecretKey String?
paypalEmail String?
paypalMerchantId String?
paymentMethodsEnabled PaymentProvider[]
isListedOnMarketplace Boolean @default(true)
isListedOnMarketplace Boolean @default(true)
marketplaceRating Float?
homePageConfig Json? @map("home_page_config")
menuConfig Json? @map("menu_config")
homePageConfig Json? @map("home_page_config")
menuConfig Json? @map("menu_config")
updatedAt DateTime @updatedAt
@@ -491,20 +899,20 @@ model BrandSettings {
}
model Employee {
id String @id @default(cuid())
companyId String
company Company @relation(fields: [companyId], references: [id], onDelete: Cascade)
clerkUserId String @unique
firstName String
lastName String
email String
phone String?
passwordHash String?
passwordResetToken String? @unique
passwordResetExpiresAt DateTime?
role EmployeeRole @default(AGENT)
preferredLanguage String @default("en")
isActive Boolean @default(true)
id String @id @default(cuid())
companyId String
company Company @relation(fields: [companyId], references: [id], onDelete: Cascade)
clerkUserId String @unique
firstName String
lastName String
email String
phone String?
passwordHash String?
passwordResetToken String? @unique
passwordResetExpiresAt DateTime?
role EmployeeRole @default(AGENT)
preferredLanguage String @default("en")
isActive Boolean @default(true)
notifications Notification[] @relation("EmployeeNotifications")
notificationPreferences NotificationPreference[]
@@ -517,34 +925,34 @@ model Employee {
}
model Vehicle {
id String @id @default(cuid())
companyId String
company Company @relation(fields: [companyId], references: [id], onDelete: Cascade)
make String
model String
year Int
color String
licensePlate String
vin String?
category VehicleCategory @default(ECONOMY)
seats Int @default(5)
transmission Transmission @default(AUTOMATIC)
fuelType FuelType @default(GASOLINE)
features String[]
dailyRate Int
status VehicleStatus @default(AVAILABLE)
photos String[]
mileage Int?
notes String?
isPublished Boolean @default(true)
id String @id @default(cuid())
companyId String
company Company @relation(fields: [companyId], references: [id], onDelete: Cascade)
make String
model String
year Int
color String
licensePlate String
vin String?
category VehicleCategory @default(ECONOMY)
seats Int @default(5)
transmission Transmission @default(AUTOMATIC)
fuelType FuelType @default(GASOLINE)
features String[]
dailyRate Int
status VehicleStatus @default(AVAILABLE)
photos String[]
mileage Int?
notes String?
isPublished Boolean @default(true)
pickupLocations String[] @default([])
allowDifferentDropoff Boolean @default(false)
dropoffLocations String[] @default([])
reservations Reservation[]
maintenance MaintenanceLog[]
offerVehicles OfferVehicle[]
calendarBlocks VehicleCalendarBlock[]
reservations Reservation[]
maintenance MaintenanceLog[]
offerVehicles OfferVehicle[]
calendarBlocks VehicleCalendarBlock[]
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@ -556,28 +964,28 @@ model Vehicle {
}
model Offer {
id String @id @default(cuid())
companyId String
company Company @relation(fields: [companyId], references: [id], onDelete: Cascade)
title String
description String?
termsAndConds String?
imageUrl String?
type OfferType
discountValue Int
specialRate Int?
appliesToAll Boolean @default(true)
categories VehicleCategory[]
minRentalDays Int?
maxRentalDays Int?
promoCode String? @unique
maxRedemptions Int?
redemptionCount Int @default(0)
validFrom DateTime
validUntil DateTime
isActive Boolean @default(true)
isPublic Boolean @default(true)
isFeatured Boolean @default(false)
id String @id @default(cuid())
companyId String
company Company @relation(fields: [companyId], references: [id], onDelete: Cascade)
title String
description String?
termsAndConds String?
imageUrl String?
type OfferType
discountValue Int
specialRate Int?
appliesToAll Boolean @default(true)
categories VehicleCategory[]
minRentalDays Int?
maxRentalDays Int?
promoCode String? @unique
maxRedemptions Int?
redemptionCount Int @default(0)
validFrom DateTime
validUntil DateTime
isActive Boolean @default(true)
isPublic Boolean @default(true)
isFeatured Boolean @default(false)
vehicles OfferVehicle[]
reservations Reservation[]
@@ -621,10 +1029,10 @@ model Renter {
phoneVerified Boolean @default(false)
isActive Boolean @default(true)
reservations Reservation[] @relation("RenterReservations")
reservations Reservation[] @relation("RenterReservations")
savedCompanies RenterSavedCompany[]
reviews Review[]
notifications Notification[] @relation("RenterNotifications")
notifications Notification[] @relation("RenterNotifications")
notificationPreferences NotificationPreference[]
createdAt DateTime @default(now())
@@ -635,7 +1043,7 @@ model Renter {
model RenterSavedCompany {
renterId String
renter Renter @relation(fields: [renterId], references: [id], onDelete: Cascade)
renter Renter @relation(fields: [renterId], references: [id], onDelete: Cascade)
companyId String
savedAt DateTime @default(now())
@@ -684,52 +1092,52 @@ model Customer {
}
model Reservation {
id String @id @default(cuid())
companyId String
company Company @relation(fields: [companyId], references: [id], onDelete: Cascade)
vehicleId String
vehicle Vehicle @relation(fields: [vehicleId], references: [id])
customerId String
customer Customer @relation(fields: [customerId], references: [id])
renterId String?
renter Renter? @relation("RenterReservations", fields: [renterId], references: [id])
offerId String?
offer Offer? @relation(fields: [offerId], references: [id])
promoCodeUsed String?
vehicleCategory VehicleCategory?
source BookingSource @default(DASHBOARD)
marketplaceRef String?
status ReservationStatus @default(DRAFT)
startDate DateTime
endDate DateTime
pickupLocation String?
returnLocation String?
dailyRate Int
discountAmount Int @default(0)
totalDays Int
totalAmount Int
depositAmount Int @default(0)
paymentStatus String @default("UNPAID")
paidAmount Int @default(0)
checkedInAt DateTime?
checkedOutAt DateTime?
checkInMileage Int?
checkOutMileage Int?
notes String?
cancelReason String?
cancelledBy CancelledBy?
contractNumber String? @unique
invoiceNumber String? @unique
reviewToken String? @unique
id String @id @default(cuid())
companyId String
company Company @relation(fields: [companyId], references: [id], onDelete: Cascade)
vehicleId String
vehicle Vehicle @relation(fields: [vehicleId], references: [id])
customerId String
customer Customer @relation(fields: [customerId], references: [id])
renterId String?
renter Renter? @relation("RenterReservations", fields: [renterId], references: [id])
offerId String?
offer Offer? @relation(fields: [offerId], references: [id])
promoCodeUsed String?
vehicleCategory VehicleCategory?
source BookingSource @default(DASHBOARD)
marketplaceRef String?
status ReservationStatus @default(DRAFT)
startDate DateTime
endDate DateTime
pickupLocation String?
returnLocation String?
dailyRate Int
discountAmount Int @default(0)
totalDays Int
totalAmount Int
depositAmount Int @default(0)
paymentStatus String @default("UNPAID")
paidAmount Int @default(0)
checkedInAt DateTime?
checkedOutAt DateTime?
checkInMileage Int?
checkOutMileage Int?
notes String?
cancelReason String?
cancelledBy CancelledBy?
contractNumber String? @unique
invoiceNumber String? @unique
reviewToken String? @unique
checkInFuelLevel String?
checkOutFuelLevel String?
insurances ReservationInsurance[]
insuranceTotal Int @default(0)
insuranceTotal Int @default(0)
additionalDrivers AdditionalDriver[]
additionalDriverTotal Int @default(0)
additionalDriverTotal Int @default(0)
pricingRulesApplied Json?
pricingRulesTotal Int @default(0)
pricingRulesTotal Int @default(0)
damageReports DamageReport[]
rentalPayments RentalPayment[]
inspections DamageInspection[]
@@ -843,9 +1251,9 @@ model NotificationPreference {
// ═══════════════════════════════════════════════════════════════
model MaintenanceLog {
id String @id @default(cuid())
id String @id @default(cuid())
vehicleId String
vehicle Vehicle @relation(fields: [vehicleId], references: [id], onDelete: Cascade)
vehicle Vehicle @relation(fields: [vehicleId], references: [id], onDelete: Cascade)
type String
description String?
cost Int?
@@ -882,37 +1290,37 @@ model VehicleCalendarBlock {
// ═══════════════════════════════════════════════════════════════
model ContractSettings {
id String @id @default(cuid())
companyId String @unique
company Company @relation(fields: [companyId], references: [id], onDelete: Cascade)
legalName String?
registrationNumber String?
taxId String?
terms String @default("")
fuelPolicy String @default("The vehicle must be returned with the same fuel level as at pickup.")
depositPolicy String @default("The security deposit is refundable within 7 days after return, subject to vehicle inspection.")
lateFeePolicy String @default("Late returns will incur a charge of 1 additional day rate per hour of delay.")
damagePolicy String @default("The renter is liable for any damage not covered by insurance.")
additionalClauses String[] @default([])
signatureRequired Boolean @default(true)
contractFooterNote String?
invoiceFooterNote String?
showTax Boolean @default(false)
taxRate Float?
taxLabel String?
contractPrefix String @default("CNT")
invoicePrefix String @default("INV")
fuelPolicyType FuelPolicyType @default(FULL_TO_FULL)
fuelPolicyNote String?
fuelChargePerLiter Int?
fuelShortfallFee Int?
lateFeePerHour Int?
taxLines Json?
lastContractSeq Int @default(0)
lastInvoiceSeq Int @default(0)
additionalDriverCharge AdditionalDriverCharge @default(FREE)
additionalDriverDailyRate Int @default(0)
additionalDriverFlatRate Int @default(0)
id String @id @default(cuid())
companyId String @unique
company Company @relation(fields: [companyId], references: [id], onDelete: Cascade)
legalName String?
registrationNumber String?
taxId String?
terms String @default("")
fuelPolicy String @default("The vehicle must be returned with the same fuel level as at pickup.")
depositPolicy String @default("The security deposit is refundable within 7 days after return, subject to vehicle inspection.")
lateFeePolicy String @default("Late returns will incur a charge of 1 additional day rate per hour of delay.")
damagePolicy String @default("The renter is liable for any damage not covered by insurance.")
additionalClauses String[] @default([])
signatureRequired Boolean @default(true)
contractFooterNote String?
invoiceFooterNote String?
showTax Boolean @default(false)
taxRate Float?
taxLabel String?
contractPrefix String @default("CNT")
invoicePrefix String @default("INV")
fuelPolicyType FuelPolicyType @default(FULL_TO_FULL)
fuelPolicyNote String?
fuelChargePerLiter Int?
fuelShortfallFee Int?
lateFeePerHour Int?
taxLines Json?
lastContractSeq Int @default(0)
lastInvoiceSeq Int @default(0)
additionalDriverCharge AdditionalDriverCharge @default(FREE)
additionalDriverDailyRate Int @default(0)
additionalDriverFlatRate Int @default(0)
updatedAt DateTime @updatedAt
@@ -1046,16 +1454,16 @@ model DamageInspection {
}
model DamagePoint {
id String @id @default(cuid())
inspectionId String
inspection DamageInspection @relation(fields: [inspectionId], references: [id], onDelete: Cascade)
viewType DiagramView
x Float
y Float
damageType DamageType
severity DamageSeverity @default(MINOR)
description String?
isPreExisting Boolean @default(false)
id String @id @default(cuid())
inspectionId String
inspection DamageInspection @relation(fields: [inspectionId], references: [id], onDelete: Cascade)
viewType DiagramView
x Float
y Float
damageType DamageType
severity DamageSeverity @default(MINOR)
description String?
isPreExisting Boolean @default(false)
@@index([inspectionId])
@@map("damage_points")
@@ -1168,7 +1576,7 @@ model AuditLog {
}
model PricingConfig {
id String @id @default(cuid())
id String @id @default(cuid())
plan String
billingPeriod String
amount Int
@@ -1197,10 +1605,10 @@ model PricingPromotion {
code String @unique
name String
description String?
discountType String // 'PERCENTAGE' | 'FIXED'
discountValue Int // percentage (1-100) or centimes for FIXED
plans String[] // empty array = all plans
periods String[] // empty array = all periods
discountType String // 'PERCENTAGE' | 'FIXED'
discountValue Int // percentage (1-100) or centimes for FIXED
plans String[] // empty array = all plans
periods String[] // empty array = all periods
maxUses Int?
usedCount Int @default(0)
validFrom DateTime