feat: Equipment-System, Buchungsbearbeitung, Kundenadresse, LexOffice-Fix
- Vintage Modell hinzugefuegt - Equipment Multi-Select (Neue Buchung + Bearbeitung) - Kundenadresse in Formularen - Bearbeiten-Seite fuer Buchungen - Abbau-Zeiten in Formularen und Uebersicht - Vertrag PDF nur bei Privatkunden - LexOffice Kontakt-Erstellung Fix (BUSINESS) - Zurueck-Pfeil auf Touren-Seite
This commit is contained in:
@@ -34,6 +34,7 @@ enum PhotoboxModel {
|
||||
VINTAGE_PHOTOS
|
||||
NOSTALGIE
|
||||
MAGIC_MIRROR
|
||||
VINTAGE
|
||||
}
|
||||
|
||||
enum InvoiceType {
|
||||
@@ -74,6 +75,7 @@ model User {
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
driverTours Tour[]
|
||||
driverLocations DriverLocation[]
|
||||
notifications Notification[]
|
||||
driverAvailability DriverAvailability[]
|
||||
}
|
||||
@@ -87,6 +89,10 @@ model Location {
|
||||
contactEmail String
|
||||
active Boolean @default(true)
|
||||
|
||||
warehouseAddress String?
|
||||
warehouseZip String?
|
||||
warehouseCity String?
|
||||
|
||||
imapHost String?
|
||||
imapPort Int?
|
||||
imapUser String?
|
||||
@@ -120,8 +126,16 @@ model PriceConfig {
|
||||
|
||||
model PhotoboxModel
|
||||
basePrice Float
|
||||
pricePerKm Float
|
||||
includedKm Int @default(0)
|
||||
|
||||
kmFlatRate Float @default(0)
|
||||
kmFlatRateUpTo Int @default(15)
|
||||
pricePerKm Float @default(0)
|
||||
kmMultiplier Int @default(4)
|
||||
|
||||
lexofficeArticleId String?
|
||||
lexofficeArticleIdWithFlat String?
|
||||
lexofficeKmFlatArticleId String?
|
||||
lexofficeKmExtraArticleId String?
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
@@ -185,6 +199,8 @@ model Booking {
|
||||
dismantleTimeEarliest DateTime?
|
||||
dismantleTimeLatest DateTime?
|
||||
|
||||
withPrintFlat Boolean @default(true)
|
||||
|
||||
distance Float?
|
||||
calculatedPrice Float?
|
||||
|
||||
@@ -223,6 +239,7 @@ model Booking {
|
||||
|
||||
tourId String?
|
||||
tour Tour? @relation(fields: [tourId], references: [id])
|
||||
tourStops TourStop[]
|
||||
|
||||
notes String?
|
||||
internalNotes String?
|
||||
@@ -267,6 +284,27 @@ enum TourStatus {
|
||||
CANCELLED
|
||||
}
|
||||
|
||||
enum StopStatus {
|
||||
PENDING // Noch nicht erreicht
|
||||
EN_ROUTE // Fahrer ist unterwegs
|
||||
ARRIVED // Fahrer ist angekommen
|
||||
SETUP_STARTED // Aufbau begonnen
|
||||
SETUP_COMPLETE // Aufbau abgeschlossen
|
||||
PICKUP_STARTED // Abbau/Abholung begonnen
|
||||
PICKUP_COMPLETE // Abholung abgeschlossen
|
||||
SKIPPED // Übersprungen
|
||||
ISSUE // Problem aufgetreten
|
||||
}
|
||||
|
||||
enum PhotoType {
|
||||
SETUP_BEFORE // Vor dem Aufbau
|
||||
SETUP_AFTER // Nach dem Aufbau
|
||||
PICKUP_BEFORE // Vor dem Abbau
|
||||
PICKUP_AFTER // Nach dem Abbau
|
||||
ISSUE // Problem-Dokumentation
|
||||
OTHER // Sonstiges
|
||||
}
|
||||
|
||||
model Tour {
|
||||
id String @id @default(cuid())
|
||||
tourDate DateTime
|
||||
@@ -276,6 +314,7 @@ model Tour {
|
||||
driver User? @relation(fields: [driverId], references: [id])
|
||||
|
||||
bookings Booking[]
|
||||
tourStops TourStop[]
|
||||
|
||||
routeOptimized Json?
|
||||
totalDistance Float?
|
||||
@@ -295,6 +334,93 @@ model Tour {
|
||||
@@index([status])
|
||||
}
|
||||
|
||||
model TourStop {
|
||||
id String @id @default(cuid())
|
||||
tourId String
|
||||
tour Tour @relation(fields: [tourId], references: [id], onDelete: Cascade)
|
||||
|
||||
bookingId String
|
||||
booking Booking @relation(fields: [bookingId], references: [id])
|
||||
|
||||
stopOrder Int // Reihenfolge der Stopps (1, 2, 3, ...)
|
||||
stopType String @default("DELIVERY") // DELIVERY, PICKUP, BOTH
|
||||
|
||||
status StopStatus @default(PENDING)
|
||||
|
||||
// Timestamps für jeden Status
|
||||
arrivedAt DateTime?
|
||||
setupStartedAt DateTime?
|
||||
setupCompleteAt DateTime?
|
||||
pickupStartedAt DateTime?
|
||||
pickupCompleteAt DateTime?
|
||||
|
||||
// Optional: GPS-Position bei Ankunft
|
||||
arrivalLatitude Float?
|
||||
arrivalLongitude Float?
|
||||
|
||||
// Notizen vom Fahrer
|
||||
notes String? @db.Text
|
||||
issueDescription String? @db.Text
|
||||
|
||||
photos DeliveryPhoto[]
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
@@unique([tourId, bookingId])
|
||||
@@index([tourId, stopOrder])
|
||||
@@index([status])
|
||||
}
|
||||
|
||||
model DriverLocation {
|
||||
id String @id @default(cuid())
|
||||
|
||||
driverId String
|
||||
driver User @relation(fields: [driverId], references: [id], onDelete: Cascade)
|
||||
|
||||
latitude Float
|
||||
longitude Float
|
||||
accuracy Float? // GPS-Genauigkeit in Metern
|
||||
heading Float? // Richtung in Grad (0-360)
|
||||
speed Float? // Geschwindigkeit in km/h
|
||||
|
||||
tourId String?
|
||||
|
||||
// Optional: Welcher Stopp ist aktuell?
|
||||
currentStopId String?
|
||||
|
||||
createdAt DateTime @default(now())
|
||||
|
||||
@@index([driverId, createdAt])
|
||||
@@index([tourId])
|
||||
}
|
||||
|
||||
model DeliveryPhoto {
|
||||
id String @id @default(cuid())
|
||||
|
||||
tourStopId String
|
||||
tourStop TourStop @relation(fields: [tourStopId], references: [id], onDelete: Cascade)
|
||||
|
||||
photoType PhotoType
|
||||
|
||||
// Dateispeicherung (z.B. /uploads/photos/...)
|
||||
fileName String
|
||||
filePath String
|
||||
fileSize Int?
|
||||
mimeType String?
|
||||
|
||||
// Optional: GPS-Position wo das Foto aufgenommen wurde
|
||||
latitude Float?
|
||||
longitude Float?
|
||||
|
||||
caption String? @db.Text
|
||||
|
||||
uploadedAt DateTime @default(now())
|
||||
|
||||
@@index([tourStopId])
|
||||
@@index([photoType])
|
||||
}
|
||||
|
||||
model Notification {
|
||||
id String @id @default(cuid())
|
||||
userId String?
|
||||
@@ -372,6 +498,9 @@ model Equipment {
|
||||
notes String?
|
||||
purchaseDate DateTime?
|
||||
purchasePrice Decimal?
|
||||
price Float?
|
||||
|
||||
lexofficeArticleId String?
|
||||
|
||||
minStockLevel Int?
|
||||
currentStock Int?
|
||||
|
||||
Reference in New Issue
Block a user