# Data Structure Foundation — Lead to Live Service ## ERPNext Doctype Relationships ``` ┌──────────────┐ │ Lead │ ← Website visitor / phone call │ (new type) │ Not yet a customer └──────┬───────┘ │ Convert to Customer ▼ ┌───────────────────────────────────────────────────────────┐ │ Customer │ │ name, email, phone, customer_group (Résidentiel/Comm.) │ │ stripe_id, legacy_customer_id │ └──────────┬─────────────────────────┬──────────────────────┘ │ │ ▼ ▼ ┌─────────────────────┐ ┌─────────────────────────┐ │ Service Location │ │ Sales Invoice │ │ (delivery address) │ │ Payment Entry │ │ │ │ (billing) │ │ address, city, zip │ └─────────────────────────┘ │ lat, lng │ │ connection_type │ │ olt_name, olt_ip │ │ frame/slot/port │ │ ont_id │ │ status: Pending → │ │ Active │ │ fibre_id (legacy) │ └──────┬──────────────┘ │ ├──────────────────────────────────┐ ▼ ▼ ┌──────────────────┐ ┌──────────────────────┐ │ Service │ │ Service Equipment │ │ Subscription │ │ │ │ │ │ serial_number │ │ item (product) │ │ mac_address │ │ status: Pending │ │ equipment_type │ │ → Active │ │ brand, model │ │ start_date │ │ status: En inventaire│ │ billing_interval │ │ → Actif │ │ rate (monthly $) │ │ olt_* fields │ └──────────────────┘ │ wifi_ssid (new) │ │ wifi_password (new) │ │ sip_username (new) │ │ sip_password (new) │ └──────────────────────┘ ┌──────────────────────────────────────────────────┐ │ Project │ │ "Installation - {customer_name}" │ │ customer, service_location │ │ status: Open → Completed │ │ │ │ ┌─── Task ────────────────────────────────┐ │ │ │ "Préparer équipement" │ support │ │ │ │ "Activer port OLT" │ support │ │ │ │ "Configurer WiFi/VoIP" │ support │ │ │ │ "Installation sur site" │ tech │ │ │ │ "Vérifier signal" │ tech │ │ │ │ "Confirmer service" │ tech │ │ │ └─────────────────────────────────────────┘ │ └──────────────────────────────────────────────────┘ ┌──────────────────────────────────────────────────┐ │ Dispatch Job │ │ customer, service_location │ │ project (link to Installation project) │ │ scheduled_date, preferred_dates │ │ assigned_technician │ │ required_tags: [Fibre, Installation] │ │ equipment_list (child table) │ │ status: Scheduled → In Progress → Completed │ └──────────────────────────────────────────────────┘ ┌──────────────────────────────────────────────────┐ │ Issue (Ticket) │ │ customer, service_location │ │ subject, description │ │ issue_type: Installation, Support, Réparation │ │ status: Open → Resolved → Closed │ │ linked_project (new field) │ └──────────────────────────────────────────────────┘ ``` --- ## New Doctype: Installation Order (or use Lead + Project) Rather than creating a new doctype, we use ERPNext's existing **Lead** → **Customer** conversion + **Project** with tasks. The wizard creates everything in one shot. ### Option A: Use ERPNext Lead Doctype ``` Lead (ERPNext built-in) lead_name: "Jean Tremblay" email_id, phone source: "Website" | "Phone" | "Walk-in" status: "Lead" → "Opportunity" → "Converted" → "Do Not Contact" Custom fields: address_line, city, postal_code fibre_id (link to fibre table entry) olt_port (frame/slot/port) requested_services: ["Internet", "TV", "Phone"] internet_plan: "FTTH150I" tv_package: "TVBSTANDARD" phone: Check preferred_date_1, preferred_date_2, preferred_date_3 stripe_payment_intent notes ``` ### Option B: Direct Customer Creation (simpler) Skip Lead, create Customer directly on checkout. Use a Project as the "order" container. **Recommended: Option B** — for self-service checkout, the customer already paid. No need for a Lead stage. For phone orders, the agent creates the customer directly too. --- ## The Wizard Flow (Website or Agent) ### Step 1: Address Check ``` Input: address string Output: fibre entry (id, olt_port, max_speed, zone_tarifaire) OR "not available" → lead capture ``` ### Step 2: Plan Selection ``` Input: fibre zone_tarifaire Output: available plans with pricing - Internet: filtered by max_speed and zone - TV: always available if internet selected - Phone: always available (even without fiber) - Discounts: auto-calculated (2x, 3x, 4x combo) ``` ### Step 3: Customer Info ``` Input: name, email, phone preferred installation dates (3 choices) OR "contactez-moi" Output: customer data ready for creation ``` ### Step 4: Payment (Stripe) ``` Input: card details (Stripe Elements) Output: payment_intent confirmed First month pro-rated + one-time charges ``` ### Step 5: Order Creation (atomic — all or nothing) ``` Creates in ERPNext (via targo-hub or n8n): 1. Customer { customer_name, email, phone, customer_group } 2. Service Location { customer, address, olt_port, fibre_id, status: "Pending Install" } 3. Service Subscriptions (one per service) { customer, location, item: FTTH150I, status: "Pending" } { customer, location, item: TVBSTANDARD, status: "Pending" } { customer, location, item: TELEPMENS, status: "Pending" } 4. Service Equipment (placeholders — serials TBD by tech) { customer, location, type: "ONT", status: "En inventaire" } { customer, location, type: "Routeur", status: "En inventaire" } { customer, location, type: "Décodeur TV", status: "En inventaire" } (if TV) 5. Project "Installation - Jean Tremblay" { customer, service_location, status: "Open" } Tasks: - Préparer équipement (assigné: support) - Activer port OLT {frame/slot/port} (assigné: support) - Configurer WiFi (assigné: support, auto-possible) - Configurer VoIP (if phone, assigné: support) - Installation sur site (assigné: tech via dispatch) - Vérifier signal ONT (assigné: tech) - Confirmer service fonctionnel (assigné: tech) 6. Dispatch Job { customer, location, project, scheduled_date: preferred_date_1, tags: [Fibre, Installation], status: "Scheduled" } 7. Reserve Fibre Port UPDATE fibre SET sn = 'RESERVED-{customer_id}' WHERE id = {fibre_id} 8. Notifications - SMS to customer (Twilio): "Commande confirmée!" - Email to customer (Mailjet): order summary - SSE to Ops: new-installation event ``` --- ## Provisioning Data on Service Equipment ### New Custom Fields Needed ```python # On Service Equipment doctype, add: # WiFi provisioning (for Deco routers) custom_wifi_ssid = Data, label="WiFi SSID" custom_wifi_password = Password, label="WiFi Password" custom_wifi_ssid_5g = Data, label="WiFi SSID 5GHz" (if different) custom_wifi_enabled = Check, label="WiFi Enabled", default=1 # VoIP provisioning (for ONTs with phone) custom_sip_username = Data, label="SIP Username" custom_sip_password = Password, label="SIP Password" custom_sip_line = Int, label="SIP Line Number", default=1 # GPON provisioning custom_gpon_serial = Data, label="GPON Serial" (physical sticker: RCMG/TPLG) custom_cwmp_serial = Data, label="CWMP Serial" (GenieACS internal) custom_fibre_line_profile = Data, label="Line Profile ID" custom_fibre_service_profile = Data, label="Service Profile ID" # RADIUS (for PPPoE if applicable) custom_radius_user = Data, label="RADIUS Username" custom_radius_password = Password, label="RADIUS Password" ``` ### WiFi Generation on Order ``` When order is created: 1. Generate WiFi SSID: "Gigafibre-{lastname}" or customer-chosen 2. Generate WiFi password: random 12-char alphanumeric 3. Store on Service Equipment (Routeur type) 4. When tech installs Deco → it bootstraps → ACS reads WiFi from ERPNext via targo-hub: GET /devices/{mac}/provision → returns SSID/password ``` ### VoIP Provisioning on Order ``` When phone service ordered: 1. Allocate SIP account from Fonoster/Routr POST /telephony/credentials → creates SIP user 2. Store SIP username/password on Service Equipment (ONT type) 3. When tech installs ONT → it bootstraps → ACS reads VoIP from ERPNext via targo-hub: GET /devices/{serial}/provision → returns SIP creds ``` --- ## Fibre Availability: Linking to RQA Addresses ### Current State - `fiber_availability` table in Supabase: uuidadresse → zone_tarifaire + max_speed - This table was imported from a different source than the legacy `fibre` table - They need to be linked ### Target ```sql -- Add fibre_id column to fiber_availability ALTER TABLE fiber_availability ADD COLUMN fibre_id INTEGER; ALTER TABLE fiber_availability ADD COLUMN olt_ip VARCHAR(64); ALTER TABLE fiber_availability ADD COLUMN olt_port VARCHAR(16); -- "0/3/2" ALTER TABLE fiber_availability ADD COLUMN ont_slot INTEGER; -- available ontid ALTER TABLE fiber_availability ADD COLUMN port_available BOOLEAN DEFAULT true; -- Match fibre entries to RQA addresses -- Strategy: postal code + street name fuzzy match + civic number UPDATE fiber_availability fa SET fibre_id = f.id, olt_ip = f.info_connect, olt_port = CONCAT(f.frame, '/', f.slot, '/', f.port), port_available = (f.sn IS NULL OR f.sn = '' OR f.sn LIKE 'RESERVED%') FROM fibre f JOIN addresses a ON a.identifiant_unique_adresse = fa.uuidadresse WHERE similarity(lower(f.rue), lower(a.odonyme_recompose_normal)) > 0.5 AND lower(f.ville) = lower(a.nom_municipalite) AND f.zip = a.code_postal; ``` ### Alternative: Serve Fibre Data Directly Instead of linking to Supabase, have targo-hub serve a `/availability` endpoint that queries the legacy fibre table directly: ``` GET /availability?q=123+rue+principale+saint-anicet 1. Fuzzy search RQA addresses (Supabase/pg_trgm) 2. For matched address, query fibre table: SELECT * FROM fibre WHERE rue LIKE '%principale%' AND ville LIKE '%anicet%' AND (sn IS NULL OR sn = '') -- available port 3. Return: { available, max_speed, olt_port, zone_tarifaire, fibre_id } ``` --- ## Agent Phone Order Flow Same data structure, different entry point: ``` Agent in Ops app: 1. Search customer (existing) or click "Nouveau client" 2. Enter address → same availability check 3. Select services → same plan picker 4. Choose dates → same date picker 5. Click "Créer commande" → Same API call as website checkout → Same n8n/targo-hub workflow → Same Project + Tasks + Dispatch Job creation Difference: no Stripe payment upfront → Invoice generated, customer pays later or agent takes CC over phone ``` ### Ops App: New "Nouvelle installation" Wizard ``` Route: /ops/new-installation Components: Step1_AddressCheck.vue — address search + availability Step2_PlanSelection.vue — internet/tv/phone picker + pricing Step3_CustomerInfo.vue — name/email/phone (or existing customer) Step4_DateSelection.vue — preferred dates calendar Step5_Summary.vue — review + confirm On confirm → POST /api/checkout (same endpoint as website) ``` --- ## Migration: Legacy Data → ERPNext ### Already Migrated - ✅ Customers (account → Customer) - ✅ Service Locations (delivery → Service Location) - ✅ Service Subscriptions (service → Service Subscription) - ✅ Service Equipment (device → Service Equipment) - ✅ Tickets (ticket → Issue) - ✅ Invoices (invoice → Sales Invoice) - ✅ OLT data on equipment (fibre → custom fields) ### Still Needed 1. **WiFi provisioning data** → Service Equipment custom fields - genieacs.wifi (1,713 entries, 858 unique Deco MACs) - Match: wifi.serial (Deco MAC) → device.mac → Service Equipment.mac_address 2. **VoIP provisioning data** → Service Equipment custom fields - genieacs.voip (797 entries, 469 unique RCMG serials) - Match: voip.serial (RCMG) → device.sn → Service Equipment.serial_number 3. **RADIUS credentials** → Service Equipment or Service Subscription - service.radius_user + service.radius_pwd - Match: service.device_id → device.sn → Service Equipment 4. **Product catalog** → ERPNext Item (if not already done) - 100+ legacy products with SKU, pricing, speed tiers - fibre_lineprofile + fibre_serviceprofile for OLT provisioning 5. **Fibre → RQA address link** for availability search - 16,056 fibre entries need matching to 5.2M RQA addresses - Strategy: postal code + street similarity + civic number --- ## Build Priority ### Week 1: Data Foundation 1. Add provisioning custom fields to Service Equipment 2. Migrate WiFi/VoIP/RADIUS data to those fields 3. Match fibre entries to RQA addresses 4. Expose availability API (fibre port check) ### Week 2: Order Wizard 1. Build /ops/new-installation wizard in Ops app 2. Build targo-hub /checkout endpoint 3. Build n8n "New Order" workflow 4. Auto-create: Customer → Location → Subscriptions → Equipment → Project → Tasks → Dispatch Job ### Week 3: Website Checkout 1. Upgrade AvailabilityDialog → full checkout flow 2. Stripe integration 3. Same /checkout endpoint as Ops wizard 4. SMS/email confirmations ### Week 4: Auto-Provisioning 1. targo-hub /devices/{serial}/provision endpoint 2. ACS webhook on device bootstrap → reads ERPNext 3. WiFi/VoIP auto-push from Service Equipment fields 4. "Device online" notifications