FNP providers, manufacturers and data
ViSN uses imported menu datasets for Modulus, OEC/Vauxhall, Ford and Kia, and a live catalogue enriched with imported reference data for VWG. The provider enum has only three values: MODULUS, OEC and OEM. Ford uses OEC; Kia and VWG both use OEM but follow different retrieval paths.
Manufacturer coverage
| Manufacturer label | Provider | Integration/data path | Vehicle key |
|---|---|---|---|
| Citroen | MODULUS | Imported Modulus vehicle and menu files | VRM, or VIN if VRM is not supplied, then vehicle_id. |
| Peugeot | MODULUS | Imported Modulus vehicle and menu files | VRM, or VIN if VRM is not supplied, then vehicle_id. |
| Vauxhall | OEC | Imported OEC fleet prices | VIN. |
| Ford | OEC | Ford files and SQL function | VIN and the function's joins across Ford datasets. |
| Kia | OEM | Manufacturer vehicle/menu files | VIN → vehicle_id, derived during import from model code and model year. |
| Audi | OEM | VWG packages API plus local parts/fluids | VRM lookup VIN, brand/type and supplier PPSO partner key. |
| Skoda | OEM | VWG packages API plus local parts/fluids | VRM lookup VIN, brand/type and supplier PPSO partner key. |
| Seat | OEM | VWG packages API plus local parts/fluids | VRM lookup VIN, brand/type and supplier PPSO partner key. |
| Cupra | OEM | VWG packages API plus local parts/fluids | VRM lookup VIN, brand/type and supplier PPSO partner key. |
| Volkswagen | OEM | VWG packages API plus local parts/fluids | VRM lookup VIN, brand/type and supplier PPSO partner key. |
Other manufacturers in the current mapping use NOT_AVAILABLE. A manufacturer appearing in the broader vehicle list, a configurable integration dropdown or an import filename is not sufficient to establish runtime FNP support. A supplier franchise for Volkswagen also does not automatically match Audi, Seat or another group brand.
Source: runtime manufacturer mapping.
Import service and environment configuration
The pricing data imports below are implemented in fnp-import-manager. Supplier/network FNP settings are imported by import-manager. Neither should be confused with the callable service that reads menus at enquiry time.
File-import jobs specify bucketName, importFilesDropPath, appDirectory and persist; manufacturer jobs also specify fnpProvider. Here an import's fnpProvider can be a manufacturer such as KIA or FORD, whereas the runtime provider is OEM or OEC. Ford and VWG file routes also use importFileName and, where required, importType.
Treat fnp-imports as a common bucket name/default, not a universal environment guarantee. Bucket and prefix are separate values: for example, bucket fnp-imports, prefix oec. Inspect the deployed scheduler request and service configuration for the actual project, bucket, endpoint and SQL database. Database name and credentials come from the service's Cloud SQL configuration; do not infer them from old example job names.
The service exposes these POST route suffixes; prepend the deployed service's route prefix:
| Route suffix | Purpose |
|---|---|
/modulus/import-vehicle-details | Modulus vehicle CSV. |
/modulus/import-menu-price | Modulus menu CSV. |
/oec/import-oec-menu-price | OEC menu CSV. |
/manufacturer/import-vehicle-details | Generic manufacturer vehicle CSV, currently used for Kia. |
/manufacturer/import-menu-price-details | Generic manufacturer menu CSV, currently used for Kia. |
/manufacturer/ford | Ford dataset selected by importType. |
/manufacturer/parts-file-import | VWG parts reference file. |
/manufacturer/fluid-file-import | VWG fluid reference CSV. |
/manufacturer/blacklisted-vins-import | Refresh VWG VIN blacklist from its API. |
For ordinary file routes, use the validation mode (persist: "false") before the persisted import (persist: "true"), inspect validation results, and verify inserted/updated rows afterwards. Validation is not evidence that data has been persisted. Local npm scripts contain example files and sometimes row limits; inspect their arguments before using them for a real batch.
Sources: import routes, local scripts, and Cloud SQL connection code.
Modulus: Peugeot and Citroen
| Input | Table | Purpose |
|---|---|---|
vehicle_reg.csv | modulus_vehicle | Maps VRM/VIN to vehicle_id. |
menu_price.csv | modulus_menu_price | Descriptions, labour time, parts, prices, quantities and fluid flags for vehicle_id. |
Both datasets are required. The runtime chooses VRM whenever supplied and uses the first vehicle match; it does not fall back to a VIN query after a VRM miss. Matching vehicle IDs must exist on both sides.
Menu rows are grouped by their combined short description into a menu with multiple parts. Modulus menus do not contain an OEC-style aggregate band price in the UI; the job uses labour plus selected parts. fnpBand does not filter these descriptions.
The current Modulus importer uses batch inserts. It does not offer the VIN/job-key upsert semantics of OEC or Kia. Do not assume reimporting a file replaces existing rows or is duplicate-free; inspect existing records and the provider's intended replacement process before a repeat import.
File layouts: Modulus vehicle file and Modulus menu file. Implementation: Modulus importer.
OEC: Vauxhall
OEC imports VIN-specific menus into oec_menu_price. Rows contain menu descriptions, labour time, parts, and prices for multiple fleet groups/bands. Persistence upserts on vin plus idJob; it does not replace the entire table. A row absent from the new file is not automatically evidence that an older row was removed.
Current filename: the bucket-loading code generates di_vx_fleet_price_export_<ddMMyyyy>.csv for the processing date and matches that basename. For example, a run on 18 September 2026 expects di_vx_fleet_price_export_18092026.csv. menu_price.csv is not the current OEC bucket filename. Local file-path overrides and example npm scripts are separate from this bucket selection.
The importer maps source headers to internal fields. Service4Fleet and Platinum prices use the LA1 column for each band; Lex prices retain their LA subdivisions. At enquiry read time, fleet level and supplier band select the applicable cost. A row can therefore exist for the VIN while the supplier receives no matching price.
See OEC menu file for columns and FNP Bands for selection rules. Implementation: OEC importer and filename generator.
Ford: separate datasets under the OEC provider
Ford does not use Vauxhall's oec_menu_price lookup. The callable service executes:
SELECT * FROM get_vehicle_descriptions_and_parts('<VIN>');
The function and its dependent tables must exist in the SQL database used by the callable deployment. The importer supports these input families:
importType | File family/examples | Stored dataset |
|---|---|---|
VIN2REG | Vin2Reg.gb... | VIN/registration information in vehicle. |
VIN_PFC | vinpfc.gb... | vin_avs: VIN to applicability/AVS codes. |
CODE_DESC | CODEDESC.TXT... | code_desc: descriptions. |
PARTS_PRICING | MPRIC.GB... | parts_pricing: prices and region information. |
LABOUR_TIME | LTSALL.TXT... | labour_time: labour data. |
PARTS_MASTER | papall.txt... | parts_master: parts applicability. |
FCJ | FCJGB.TXT... | The fcj_* tables, including fcj_fixed_content_jobs, fcj_parts, fcj_fluids, fcj_labour_operations, fcj_fixed_prices and fcj_avs. FIXED_CONTENT_JOB is the schema-map key, not a table name. |
These are file families, not a promise that a historical date suffix is accepted by every job. The deployed request provides importFileName; the processors select matching basenames/prefixes. Inspect that request when a new file is not picked up. The importers have dataset-specific validation and persistence; a successful single-file import does not prove the full function join can resolve a VIN.
The runtime groups the function's rows by description, carries complete_code into fixed-price options/parts and uses Ford Region 22 or Ford Region 23 to select region costs. Multiple prices can require a supplier choice. The current Ford Lex Auto group-name mismatch is documented in Enquiry pricing flow; check it before assuming empty Lex Auto results mean missing Ford source files.
Sources: Ford import controller, Ford processors and validation, and Ford SQL retrieval and shaping.
Kia: generic manufacturer files
| Input | Table | Key/matching behaviour |
|---|---|---|
vehicle_reg.csv | vehicle | VIN upsert; vehicle_id is constructed from miocn and modelYear. |
menu_price.csv | menu_price | vehicle_id is constructed from model and modelYear; menu/part records are upserted on the vehicle ID, description fields and part number. |
For example, the vehicle's miocn and the menu's model must produce the same <model code>_<model year> identifier. A matching VIN without matching menu rows yields no menus.
The menu importer also attempts to mark matching stock records receivedMenuPrice: true, finding stock via Typesense. SQL pricing retrieval and that stock/export bookkeeping are separate: failure to locate stock for the flag is not the same as failure to insert SQL menu rows. Inspect both the log and joined SQL records.
The runtime joins these tables by vehicle_id and filters VIN. It uses labour and part prices rather than OEC fleet-level/band filtering. The supplier workflow also has Kia-specific labour and parts-discount behaviour; see Enquiry pricing flow.
File layouts: Manufacturer vehicle file and Manufacturer menu file. Implementation: manufacturer importer.
VWG: live packages plus imported reference data
VWG menus are requested from the packages API for the VRM lookup VIN. Local reference datasets enrich or gate that response:
| Dataset | Table | Behaviour |
|---|---|---|
| Parts price file | vwg_parts_price | Fixed-width M records contain part number, price and currency. Runtime matches exact part codes. Persisted import truncates and bulk loads the table; treat it as replacement data. |
| Fluid details CSV | vwg_fluid_details | Code, Unit, Description, Comments; persistence upserts on fluid_code. Supplies descriptions, not fluid prices. |
| Blacklisted VIN API | vwg_blacklisted_vin | Refreshed list replaces the table transactionally. A matching VIN suppresses the packages request. |
VWG also needs the supplier's ppsoPartnerKey, brand/vehicle-type mapping and credentials. Menus can load with absent part prices if enrichment fails. Missing non-fluid prices set hasIncompletePartInfo; fluids deliberately have no imported price and require supplier input. A missing fluid price is not equivalent to a failed parts import.
Two current importer details matter operationally:
- The parts validation and persistence paths do not use identical filtering. The persisted
lineToCsvRowcondition rejects a row only when the part number is missing and currency is not GBP. Do not assume persistence alone enforces all validation checks; validate the source and review results. - The local
validate:vwg-blacklisted-vinsentry point calls a constructor that sets persistence to true when no explicit arguments are supplied. Its name is not a safe dry-run guarantee. For validation without replacing the SQL list, use the deployed HTTP controller with explicitpersist: "false"; it still reads the provider API. Confirm the deployed revision before operating it.
File specifications: VWG parts, VWG fluids, and VWG integration deep dive. Implementation: VWG importers and blacklist replacement.
VIN exports and the return-data loop
VIN export is a separate preparatory process for providers that need a stock list before supplying data. It does not attach menus to enquiries.
generateVINListForFnpProvider receives sourceFolderName, fnpProviderName and an optional stock limit. It searches stock through Typesense, validates VINs, generates a headerless CSV, uploads archive/pickup copies and records exportedForFnpEpoch on stock and in the index.
| Export | Eligibility | Filename |
|---|---|---|
| Manufacturer, e.g. Kia | Active customer with matching enabled FNP_KIA integration; stock make matches and receivedMenuPrice != true. | vin_list_for_KIA-<ddMMyyyy>.csv |
| OEC | Active customer; this export bypasses the customer integration switch. Stock make must have includeInFnpVinList; currently Vauxhall, not Ford. Query selects exportedForFnpEpoch at least three months old or 0. | VIN list <ddMMyyyy>.csv |
The generator writes CSV directly; it does not ZIP the output. The pickup folder's existing files are deleted before new output is uploaded, so keep provider destinations configured correctly. Transfer to the provider and receipt/import of the returned dataset are additional steps; a successful export is not proof of returned prices.
For missing return data, inspect the stock index as well as Firestore. A VIN missing from the export can result from inactive customer status, make mismatch, VIN validation, an export limit, index state or the provider-specific timestamp/received-price filters.
See Manufacturer VIN export. Sources: generator, stock query, and lease eligibility.
Verify a data refresh
- Confirm the target environment, SQL connection, deployed importer revision and incoming filename/prefix.
- Review validation output, then the persisted job's success/skipped counts and row/batch errors. HTTP success or an uploaded file alone does not prove all records imported.
- Run a lookup for a known VRM/VIN or part code through the same tables/function used by the callable service.
- Compare provider output with the enquiry's saved descriptions. Imports update provider datasets; they do not automatically update every existing enquiry's cache or jobsheet.
- Use a new controlled test enquiry, or targeted engineering reprocessing of the affected enquiry, to verify loading and actual jobline pricing end to end.
The debugging page supplies read-only queries and the evidence needed before choosing a repair.