Installations Models ==================== Installation ------------ Represents a scheduled charger installation, created after a survey is approved. .. list-table:: :header-rows: 1 :widths: 20 20 20 40 * - Field - Type - Constraints - Description * - id - UUIDField - PK, default=uuid4 - Primary key * - installation_id - CharField(20) - unique, auto-generated - Human-readable ID (e.g., ``INS-2026-00456``) * - survey - OneToOneField(Survey) - not null, on_delete=CASCADE - Linked approved survey * - lead - ForeignKey(Lead) - not null, on_delete=PROTECT - Back-reference to originating lead * - scheduled_date - DateField - not null - Planned installation date * - scheduled_time_slot - CharField(20) - choices: ``morning``, ``afternoon``, ``evening`` - Time window * - status - CharField(20) - choices, default='planned' - Installation lifecycle state * - material_ready - BooleanField - default=False - All materials allocated and confirmed * - customer_confirmed - BooleanField - default=False - Pre-installation confirmation received * - demo_completed - BooleanField - default=False - Charger demo given to customer * - created_by - ForeignKey(User) - not null, on_delete=PROTECT - Central Ops who planned it * - created_at - DateTimeField - auto_now_add - Creation timestamp * - updated_at - DateTimeField - auto_now - Last update timestamp **Status choices**: ``planned``, ``material_pending``, ``material_ready``, ``confirmed``, ``in_progress``, ``completed``, ``report_submitted``, ``closed``, ``rescheduled``, ``cancelled`` **Indexes**: ``status``, ``scheduled_date``, ``lead``, ``created_by`` InstallationAssignment ---------------------- Links an installation to a field team. Same structure as SurveyAssignment. .. list-table:: :header-rows: 1 :widths: 20 20 20 40 * - Field - Type - Constraints - Description * - id - UUIDField - PK, default=uuid4 - Primary key * - installation - ForeignKey(Installation) - not null, on_delete=CASCADE - Parent installation * - team - ForeignKey(Team) - not null, on_delete=PROTECT - Assigned field team * - assigned_by - ForeignKey(User) - not null, on_delete=PROTECT - Central Ops who assigned * - is_primary - BooleanField - default=True - Primary assignment vs emergency backup * - assigned_at - DateTimeField - auto_now_add - Assignment timestamp * - status - CharField(20) - choices: ``assigned``, ``accepted``, ``en_route``, ``on_site``, ``completed``, ``cancelled`` - Assignment state InstallationReport ------------------ Post-installation record submitted by the field team. .. list-table:: :header-rows: 1 :widths: 20 20 20 40 * - Field - Type - Constraints - Description * - id - UUIDField - PK, default=uuid4 - Primary key * - installation - OneToOneField(Installation) - not null, on_delete=CASCADE - Parent installation * - submitted_by - ForeignKey(User) - not null, on_delete=PROTECT - Field team member who submitted * - charger_serial_number - CharField(50) - not null - Serial number of installed charger * - charger_model - CharField(100) - not null - Model of charger installed * - installation_successful - BooleanField - not null - Whether installation was successful * - demo_given - BooleanField - default=False - Demo completed with customer * - customer_signature - FileField - nullable, upload_to='signatures/' - Customer sign-off image * - issues_encountered - TextField - blank - Any issues during installation * - general_notes - TextField - blank - Additional observations * - submitted_at - DateTimeField - auto_now_add - Submission timestamp InstallationMedia ----------------- Photos and videos of the completed installation. .. list-table:: :header-rows: 1 :widths: 20 20 20 40 * - Field - Type - Constraints - Description * - id - UUIDField - PK, default=uuid4 - Primary key * - installation - ForeignKey(Installation) - not null, on_delete=CASCADE - Parent installation * - media_type - CharField(20) - choices: ``photo``, ``video`` - Media type * - file - FileField - not null, upload_to='installation_media/' - Media file * - caption - CharField(255) - blank - Description of media content * - uploaded_by - ForeignKey(User) - not null, on_delete=PROTECT - Uploader * - uploaded_at - DateTimeField - auto_now_add - Upload timestamp