Datenmodell
Die wichtigsten Modelle, ihre Beziehungen und domänenspezifische Erweiterungen
im Überblick.
E-Commerce-Core (Oscar)
Produkt-Domäne
ProductClass
│ track_stock, requires_shipping, is_deposit
│
└── Product ─── ProductCategory ─── Category
│ (through)
├── ProductImage
├── ProductRecommendation
├── ProductAttributeValue
├── StockRecord (Preis)
└── parent → Product (Varianten)
| Modell |
Besonderheiten |
ProductClass |
is_deposit steuert Pfandpflicht. requires_shipping unterscheidet physische von digitalen Produkten |
Product |
parent-FK für Varianten-Gruppierung. Produkte ohne parent sind Stammprodukte |
ProductCategory |
1. Kategorie = Hauptkategorie (Breadcrumbs, URL) |
StockRecord |
Preis pro Partner. price_excl_tax wird aus Brutto-Preis errechnet |
Bestell-Domäne
Basket ── Line ── Product
│ │
│ ├── LinePrice
│ └── LineAttribute
│
└── Surcharge (durch SurchargeApplicator)
Order ── Line ── Product
│ │
│ ├── LinePrice
│ └── LineAttribute
│
├── ShippingAddress
├── BillingAddress
├── ShippingEvent
├── PaymentEvent
└── Surcharge (persistiert)
| Modell |
Besonderheiten |
Basket |
after_deposit Property: Warenkorbwert ohne Pfand |
Order |
Pfand-Splitting: Pfand-Positionen werden getrennt von Warenpositionen geführt |
Surcharge |
Persistent gespeichert in der Order (nicht flüchtig wie bei Oscar) |
Angebots-Domäne
Offer ── Condition ── Range
│ │ │
│ ├── Value ├── Produkte
│ └── Coverage ├── Kategorien
│ └── Produktklassen
└── Benefit
├── PercentageDiscountBenefit
├── AbsoluteDiscountBenefit
└── ShippingBenefit
Shop-Eigene Modelle
Versand (Shipping)
OrderAndItemCharges (shipping.models)
├── price_per_order: Decimal # Bestellpauschale
├── price_per_item: Decimal # Stückpreis × Artikel
├── price_per_floor: Decimal # Stockwerkszuschlag × Etage
├── maximum_floor_difference: int # Max. Stockwerke (0 = deaktiviert)
├── price_per_box: Decimal # Kistenzuschlag × Kisten
├── small_order_surcharge: Decimal # Mindermengenzuschlag
├── small_order_threshold: Decimal # Schwellwert (None = deaktiviert)
├── minimum_order_value: Decimal # Mindestbestellwert
└── free_shipping_threshold: Decimal # Versandkostenfrei ab
ShippedFloor
├── shipping_method → OrderAndItemCharges
├── floor: int
└── price_per_floor: Decimal # Etagenspezifischer Preis
Logistik
TimeSlot (logistics.models)
├── start / end: DateTime # Beginn und Ende der Lieferung
├── rule → Rule # Generierungsregel
├── route → Route # Tourenzuweisung
├── capacity: int # Max. Bestellungen (0 = unbegrenzt)
├── blocked: bool # Manuelle Sperre
├── blocker → Blocker # Datums-Sperre
├── is_from_db: bool # False = virtuelles Zeitfenster
└── is_fully_booked_db: bool # Kapazität erreicht
Schedule
├── rules → Rule (related) # Wiederholungsregeln
├── zones → Zone (M2M) # PLZ-Bereiche
├── cutoff_time: Time # Annahmeschluss
├── min_advance_days: int # Mindestvorlauf
└── min_advance_time: Time # Mindestvorlauf-Uhrzeit
Rule
├── schedule → Schedule
├── start / end: Time # Uhrzeit-Bereich
├── weekdays: str # Komma-getrennt: "1,2,3,4,5"
├── frequency: Frequency # Wöchentlich / 2-wöchentlich
├── interval: int
└── order_quota: int # Max. Bestellungen pro Slot
Route
├── name: str
├── number: int
├── max_stops: int
└── vehicle: str (optional)
Zone
├── name: str
└── postcodes → Postcode
Postcode
├── zone → Zone
├── postcode: str
├── city: str
└── blocker_set → Blocker
Blocker
├── date: date
├── postcode → Postcode (optional)
└── description: str
Kommunikation & Organisation
OrganizationUnit (user.models)
├── type: INTERNAL(0) | ADDITIONAL_EMAIL_RECIPIENT(1)
├── members → User (M2M)
├── email_recipients (TextField, komma-getrennt)
├── event_types → CommunicationEventType (M2M)
├── customers → User (M2M)
├── product_classes → ProductClass (M2M)
├── source_types (TextField)
├── minimum_order_value / maximum_order_value
└── api_endpoint (URL, optional)
CommunicationEventType (communication.models)
├── code: str # ORDER_PLACED, REGISTRATION, …
├── name: str
├── category: USER | ORDER | CUSTOM
└── email_templates → EmailTemplate
├── subject
├── body_html
└── body_text
Wichtige Properties & Methoden
| Modell |
Property/Methode |
Beschreibung |
Basket |
after_deposit |
Warenkorbwert ohne Pfand (Brutto) |
Basket |
num_boxes |
Anzahl Kisten (product.has_box) |
Basket |
num_items |
Anzahl Artikel |
OrderAndItemCharges |
get_extra_charges(basket) |
Alle Zuschläge als Liste von Dicts |
OrderAndItemCharges |
is_free_shipping(basket) |
Versandkostenfreigrenze prüfen |
OrderAndItemCharges |
_get_basket_total_without_deposit(basket) |
Pfand-freier Warenkorbwert |
OrganizationUnit |
check_responsibility(event, user, order) |
Zuständigkeit für Event prüfen |
OrganizationUnit |
send_all(event, user, messages) |
Kommunikation über alle OUs senden |
OrganizationUnit |
get_responsible_ous(event, user, order) |
Alle zuständigen OUs ermitteln |
OrganizationUnit |
get_email(messages) |
E-Mail mit Empfängern + Attachments |
TimeSlot |
is_fully_booked |
Kapazität erreicht? |
TimeSlot |
status |
blocked / fully_booked / bookable / plannable |
TimeSlot |
is_from_db |
True = gespeichert, False = virtuell |
TimeSlot |
date |
Lokales Datum des Slots |
Schedule |
get_next_time_slots(postcode) |
Nächste verfügbare Zeitfenster |