Online Booking
Customers browse active movies, choose a showtime, select seats, add optional products, review the order, pay through the stub gateway, view orders, print tickets, and cancel eligible bookings.
This is a first-pass case study. The project is documented from the implemented MVP, SDS coverage, and available architecture diagrams.
Cinema booking and operational system built with Django
Silver Screen is a cinema booking and operations system covering the full path from customer movie discovery to ticket payment, POS order creation, showtime scheduling, and manager-controlled master data. The MVP is implemented with Django class-based views, service-layer business logic, Django templates, HTMX fragment swaps, and raw CSS.
The system supports four role groups: customer, staff counter, scheduler, and cinema manager. Each role has a separate operational surface while sharing the same core domain model for movies, studios, seats, showtimes, orders, tickets, products, add-ons, charges, and payments.
Explore the interface of Silver Screen. Select a role below to view screenshots from the deployment.
The product was built around cinema operations where online booking and onsite counter workflows need to share seat availability, ticket lifecycle rules, and order records without mixing their state transitions.
Customers browse active movies, choose a showtime, select seats, add optional products, review the order, pay through the stub gateway, view orders, print tickets, and cancel eligible bookings.
Staff create onsite orders only after payment, attach an optional customer account, print tickets immediately, view all orders, cancel eligible online orders, and complete pending refunds.
Scheduler users create jam tayang through a phased visual wizard. Runtime and end time are derived from the selected movie, and server-side validation blocks overlaps and past start times.
Managers maintain movies, products, studios, and immutable studio seat layouts. Inactive movies and products are hidden from customer booking and POS add-on selection.
Silver Screen uses Django apps split by responsibility. The cinema app owns the core
domain models, forms, routes, templates, services, admin registration, tests, and demo seed command.
The stub_payment_gateway app owns the provider-side dummy gateway model, gateway pages,
issue-payment endpoint, payment simulation views, and expiration behavior.
Business rules are intentionally kept in services instead of fat models. Online booking, payment callbacks, cancellation, onsite POS creation, scheduling, studio layout generation, and ID generation are coordinated through dedicated service modules so the class-based views remain focused on routing, permissions, forms, and template rendering.
The customer flow has four phases: seat selection, add-ons, review, and payment. Order drafts stay in the session until review confirmation. Confirming creates a pending online order, held tickets, an unpaid payment, optional add-ons, and a service charge.
Staff POS does not create pending or held records. After the customer pays at the counter, the system atomically creates a confirmed onsite order, paid payment, confirmed tickets, QR UUIDs, add-ons, and charges.
Unpaid online cancellations invalidate the provider-side gateway payment and release held seats. Paid confirmed cancellations move payment to refund pending. Used tickets block cancellation.
Each confirmed ticket receives a hard-to-guess QR UUID. The scanner is outside this Django app and is expected to share the same database, read the QR UUID, and mark the ticket as used.
The MVP does not integrate with a real payment processor. Instead, it includes a dedicated payment gateway stub that models provider-side payment issuance, virtual-account assignment, success simulation, expiration simulation, and callback delivery back into Silver Screen.
The internal Payment record is owned by Silver Screen, while the provider-side
GatewayPayment record is owned by the stub gateway. Final payment and order states are
sourced only from callbacks. Countdown displays in the app and gateway are visual; the authoritative
expiration behavior belongs to the gateway worker.
The domain model centers on movies, studio layouts, showtimes, orders, tickets, add-ons, charges, and
payments. Seat protection is enforced with a conditional uniqueness rule so a showtime and seat cannot
have more than one active ticket in HELD, CONFIRMED, or USED
state.
Online and onsite channels share the same order, ticket, and payment tables, but use different state paths. Online orders start pending with held tickets and unpaid payments. Onsite POS orders are created only after payment, so they enter the system already confirmed and paid.