# Legacy → ERPNext Field Gap Analysis Complete audit of every legacy database field against current ERPNext doctypes. Goal: **Zero data loss** — every meaningful field must have a home in ERPNext. --- ## 1. Customer (legacy `account` table) ### Already Migrated | Legacy Field | ERPNext Field | Doctype | Script | |---|---|---|---| | id | legacy_account_id | Customer | migrate_direct.py | | first_name + last_name | customer_name | Customer | migrate_direct.py | | email | email_billing | Customer (custom) | import_customer_details.py | | customer_id | legacy_customer_id | Customer | migrate_direct.py | | address1, city, state, zip | address_line, city, province, postal_code | Service Location | migrate_locations.py | | invoice_delivery | invoice_delivery_method | Customer (custom) | import_customer_details.py | | commercial | is_commercial | Customer (custom) | import_customer_details.py | | mauvais_payeur | is_bad_payer | Customer (custom) | import_customer_details.py | | tax_group | tax_category_legacy | Customer (custom) | import_customer_details.py | | contact | contact_name_legacy | Customer (custom) | import_customer_details.py | | mandataire | mandataire | Customer (custom) | import_customer_details.py | | tel_home | tel_home | Customer (custom) | import_customer_details.py | | tel_office | tel_office | Customer (custom) | import_customer_details.py | | cell | cell_phone | Customer (custom) | import_customer_details.py | | fax | fax | Customer (custom) | import_customer_details.py | | misc | notes_internal | Customer (custom) | import_customer_details.py | | frais | exclude_fees | Customer (custom) | import_customer_details.py | | email_autre | email_publipostage | Customer (custom) | import_customer_details.py | | date_orig | date_created_legacy | Customer (custom) | import_customer_details.py | ### GAP — Missing Fields (need custom fields + migration) | Legacy Field | Values/Stats | Proposed ERPNext Field | Priority | |---|---|---|---| | middle_name | Free text | `middle_name` Data | LOW | | title | "M.", "Mme", etc. | `salutation_legacy` Data | LOW | | ppa | 1,249 accounts | `ppa_enabled` Check | HIGH | | ppa_name | Payer name | `ppa_name` Data | HIGH | | ppa_code | Bank transit | `ppa_code` Data | HIGH | | ppa_branch | Bank branch | `ppa_branch` Data | HIGH | | ppa_account | Bank account | `ppa_account` Data | HIGH | | ppa_amount | Amount | `ppa_amount` Currency | HIGH | | ppa_amount_buffer | Buffer | `ppa_amount_buffer` Currency | MEDIUM | | ppa_fixed | Fixed payment flag | `ppa_fixed` Check | MEDIUM | | ppa_cc | PPA via credit card | `ppa_cc` Check | MEDIUM | | ppa_all_invoice | Apply to all invoices | `ppa_all_invoice` Check | MEDIUM | | vip | 28 accounts | `is_vip` Check | MEDIUM | | stripe_id | 785 accounts | `stripe_customer_id` Data | HIGH | | stripe_ppa | Stripe auto-pay flag | `stripe_ppa_enabled` Check | HIGH | | land_owner | Property owner flag | `is_land_owner` Check | LOW | | keyword | Search keyword | `search_keyword` Data | LOW | | pub | Marketing opt-in | `marketing_optin` Check | MEDIUM | | call | Call contact flag | `call_contact` Check | LOW | | username | Portal login | `portal_username` Data | LOW | | password | Portal password (MD5) | `portal_password_hash` Data | LOW | | terminate_reason | Reason for termination | `terminate_reason` Small Text | MEDIUM | | terminate_cie | Competitor they left for | `terminate_cie` Data | MEDIUM | | terminate_note | Termination notes | `terminate_note` Small Text | MEDIUM | | terminate_date | Date terminated | `terminate_date` Date | MEDIUM | | notes_client | Client-visible notes | `notes_client` Small Text | MEDIUM | | address2 | Address line 2 | *Already in Service Location* | — | --- ## 2. Service Subscription (legacy `service` table) ### Already Migrated | Legacy Field | ERPNext Field | Script | |---|---|---| | id | legacy_service_id | import_services_and_enrich_customers.py | | delivery_id | service_location (via map) | import_services_and_enrich_customers.py | | device_id | device (Link to Service Equipment) | import_services_and_enrich_customers.py | | product_id | product_sku | import_services_and_enrich_customers.py | | status | status (mapped to Actif/Suspendu/Annulé) | import_services_and_enrich_customers.py | | comment | notes | import_services_and_enrich_customers.py | | payment_recurrence | billing_cycle | import_services_and_enrich_customers.py | | hijack_price | monthly_price (when hijack=1) | import_services_and_enrich_customers.py | | hijack_download_speed | speed_down (when hijack=1) | import_services_and_enrich_customers.py | | hijack_upload_speed | speed_up (when hijack=1) | import_services_and_enrich_customers.py | | date_orig | start_date | import_services_and_enrich_customers.py | | date_end_contract | end_date | import_services_and_enrich_customers.py | | radius_user | radius_user | import_services_and_enrich_customers.py | | radius_pwd | radius_password | import_services_and_enrich_customers.py | ### GAP — Missing Fields | Legacy Field | Values/Stats | Proposed ERPNext Field | Priority | |---|---|---|---| | hijack | Override flag (bool) | `is_custom_pricing` Check | MEDIUM | | hijack_desc | Override description | `custom_pricing_desc` Data | MEDIUM | | hijack_quota_day | Day bandwidth quota | `quota_day_gb` Float | LOW | | hijack_quota_night | Night bandwidth quota | `quota_night_gb` Float | LOW | | date_suspended | Suspension date | `date_suspended` Date | HIGH | | actif_until | Active-until date | `active_until` Date | MEDIUM | | date_next_invoice | Next invoice date | `next_invoice_date` Date | HIGH | | forfait_internet | Internet bundle flag | `forfait_internet` Check | LOW | | radius_conso | RADIUS consumption tracking | `radius_consumption` Data | LOW | | ip_fixe | Static IP address | `static_ip` Data | MEDIUM | --- ## 3. Service Equipment (legacy `device` table) ### Already Migrated | Legacy Field | ERPNext Field | Script | |---|---|---| | id | legacy_device_id | import_devices_and_enrich.py | | delivery_id | service_location (via map) | import_devices_and_enrich.py | | category | equipment_type (mapped) | import_devices_and_enrich.py | | sn | serial_number | import_devices_and_enrich.py | | mac | mac_address | import_devices_and_enrich.py | | manufacturier | brand | import_devices_and_enrich.py | | model | model | import_devices_and_enrich.py | | manage / manage_cli | ip_address | import_devices_and_enrich.py | | user | login_user | import_devices_and_enrich.py | | pass | login_password | import_devices_and_enrich.py | ### GAP — Missing Fields | Legacy Field | Values/Stats | Proposed ERPNext Field | Priority | |---|---|---|---| | manage | Full management URL/IP | `manage_url` Data | HIGH | | port | Management port | `manage_port` Int | HIGH | | protocol | Management protocol (http/https/ssh) | `manage_protocol` Select | HIGH | | manage_cli | CLI access IP | `cli_ip` Data | HIGH | | port_cli | CLI port | `cli_port` Int | HIGH | | protocol_cli | CLI protocol (ssh/telnet) | `cli_protocol` Select | HIGH | | parent | Parent device ID | `parent_device` Link (Service Equipment) | HIGH | | category | Exact legacy category string | `legacy_category` Data | MEDIUM | | name (legacy) | Device display name | `device_name` Data | LOW | ### GAP — Provisioning Fields (from GenieACS MariaDB) | Source | Field | Proposed ERPNext Field | Priority | |---|---|---|---| | GenieACS wifi table | ssid | `wifi_ssid` Data | HIGH | | GenieACS wifi table | password | `wifi_password` Password | HIGH | | GenieACS voip table | username | `sip_username` Data | HIGH | | GenieACS voip table | password | `sip_password` Password | HIGH | | GenieACS devices | CWMP serial | `cwmp_serial` Data | HIGH | | GenieACS devices | GPON serial | `gpon_serial` Data | HIGH | | Fibre table | line_profile | `fibre_line_profile` Data | MEDIUM | | Fibre table | service_profile | `fibre_service_profile` Data | MEDIUM | ### GAP — ACS Integration Fields | Purpose | Proposed ERPNext Field | Priority | |---|---|---| | GenieACS/Oktopus device ID | `acs_device_id` Data | HIGH | | Last ACS inform time | `acs_last_inform` Datetime | MEDIUM | | ACS online status | `acs_online` Check | MEDIUM | | WAN IP from ACS | `wan_ip` Data | MEDIUM | --- ## 4. Service Location (legacy `delivery` + `fibre` tables) ### Already Migrated | Legacy Field | ERPNext Field | Script | |---|---|---| | delivery.id | legacy_delivery_id | migrate_locations.py | | delivery.address1 | address_line | migrate_locations.py | | delivery.city | city | migrate_locations.py | | delivery.state | province | migrate_locations.py | | delivery.zip | postal_code | migrate_locations.py | | delivery.account_id | customer (via map) | migrate_locations.py | | fibre.frame/slot/port/ontid | olt_port | import_devices_and_enrich.py | | fibre.vlan_* | network_id (concatenated) | import_devices_and_enrich.py | | *connection_type inferred* | connection_type | import_devices_and_enrich.py | ### GAP — Missing Fields from `delivery` | Legacy Field | Proposed ERPNext Field | Priority | |---|---|---| | address2 | `address_line_2` Data | MEDIUM | | contact | `contact_name` (already exists) | — | | phone | `contact_phone` (already exists) | — | | note | `delivery_notes` Small Text | MEDIUM | | appartement | `apartment_number` Data | MEDIUM | ### GAP — Missing Fields from `fibre` | Legacy Field | Values/Stats | Proposed ERPNext Field | Priority | |---|---|---|---| | id | 16,056 entries | `legacy_fibre_id` Int | MEDIUM | | sn | ONT serial number | `ont_serial` Data | HIGH | | olt_ip (info_connect) | OLT management IP | `olt_ip` Data | HIGH | | olt_name (from fibre_olt) | OLT display name | `olt_name` Data | MEDIUM | | ontid | ONT ID on OLT port | `ont_id` Int | HIGH | | terrain | Property type | `terrain_type` Data | LOW | | distance | Distance from OLT | `fibre_distance_m` Float | LOW | | nb_portees | Number of spans | `fibre_spans` Int | LOW | | temps_estim | Estimated install time | `install_time_estimate` Data | LOW | | suite | Apartment indicator | `is_apartment` Check | LOW | | boitier_pas_install | Box not installed flag | `box_not_installed` Check | LOW | | vlan_manage | Management VLAN (individual) | `vlan_manage` Int | MEDIUM | | vlan_internet | Internet VLAN | `vlan_internet` Int | MEDIUM | | vlan_telephone | Telephone VLAN | `vlan_telephone` Int | MEDIUM | | vlan_tele | TV VLAN | `vlan_tv` Int | MEDIUM | | manage_service_id | Mgmt service link | `manage_service_id` Int | LOW | | internet_service_id | Internet service link | `internet_service_id` Int | LOW | | telephone_service_id | Phone service link | `telephone_service_id` Int | LOW | | tele_service_id | TV service link | `tv_service_id` Int | LOW | | placemarks_id | Map placement ID | `placemarks_id` Data | LOW | | appartements_id | Apartment building ID | `apartment_building_id` Data | LOW | --- ## 5. device_attr (key-value pairs, 497 entries) No ERPNext equivalent exists. Contains per-device extended attributes: - **MAC addresses per interface** (eth0 through eth5) — multiple MACs per device - **stb_id** — Ministra/IPTV subscription ID - **Custom OLT references** - **Router routes** (static routes configured on device) ### Proposed Solution | Attribute Key | Proposed ERPNext Field | On Doctype | Priority | |---|---|---|---| | mac_ethX | `mac_addresses_json` Long Text (JSON) | Service Equipment | MEDIUM | | stb_id | `iptv_subscription_id` Data | Service Equipment | HIGH | | OLT refs | Already captured via fibre table | Service Location | — | --- ## 6. Dispatch Job (legacy `bon_travail` table) ### Already Migrated Dispatch Job doctype exists with custom FSM fields. However: ### GAP — Missing Fields from `bon_travail` | Legacy Field | Proposed ERPNext Field | Priority | |---|---|---| | tech1_id | Already `assigned_to` on Dispatch Job | — | | tech2_id | `second_technician` Data | MEDIUM | | tech1_arrive | `tech1_arrival` Datetime | MEDIUM | | tech1_depart | `tech1_departure` Datetime | MEDIUM | | tech2_arrive | `tech2_arrival` Datetime | MEDIUM | | tech2_depart | `tech2_departure` Datetime | MEDIUM | | line items (bon_travail_item) | Already `equipment_items` + `materials_used` child tables | — | --- ## Summary: Custom Fields to Add ### Customer — 23 new fields PPA section (8), Stripe (2), Termination (4), VIP/flags (3), Portal (2), Other (4) ### Service Subscription — 10 new fields Custom pricing (3), Dates (3), Quotas (2), IP (1), Other (1) ### Service Equipment — 17 new fields Management (6), Provisioning (8), ACS (4), Legacy (1) ### Service Location — 18 new fields Fibre infrastructure (10), VLANs (4), Legacy IDs (4) ### Dispatch Job — 5 new fields Second tech + time tracking (5) **Total: ~73 custom fields across 5 doctypes**