Skip to main content

Kwikfit IPP imports

Introduction

Kwikfit generates invoice files from their IPP system containing completed job lines. These JSON files are imported into ViSN to automatically create invoices and mark enquiries as completed, eliminating the need for manual invoice entry.

Purpose

To streamline the invoicing process, Kwikfit exports invoice data from their IPP system in a JSON format. This file is imported into ViSN, where the system automatically:

  • Validates the invoice data against existing enquiries
  • Matches invoices to enquiries by VRM and enquiry number
  • Verifies invoice totals match ViSN calculations
  • Progresses enquiries to "Completed" status
  • Creates invoices in ViSN with the IPP invoice details

File format

JSON format - *.json

The JSON file must contain an array of objects, where each object has an INVOICE_HEADER property with the following structure:

Fields

ColumnFieldTypeLengthCommentMandatoryExample
AACCOUNT_NOText100Kwikfit account number for the lease company. This must match the account mapping in ViSN.YesM5909U
BINVOICE_NOText100Invoice number from IPP system. This will be saved as the invoice number in ViSN.YesYE374831
CTAX_DATEDate10DD/MM/YYYY - Tax point date for the invoice. This will be used as the tax point date in ViSN.Yes24/11/2025
DDEPOT_NOText100Kwikfit depot/supplier ID. This must match a service unit's supplierId in ViSN.Yes669
ECAR_REGISTRATIONText100Vehicle Registration Mark (VRM). Must match the VRM on the enquiry in ViSN. Validated against VRM regex pattern.YesSN74USH
FINVOICE_VALUENumber(9,2)12Total invoice value (net + VAT). Must match the calculated total in ViSN. Format: nnnnnn.nnYes245.71
GVAT_TOTALNumber(9,2)12Total VAT amount. Format: nnnnnn.nnYes43.27
HORDER_NOText100Enquiry number in ViSN. Must be numeric and match an existing enquiry number.Yes57294658

High level flow

Import process

Overview

The sequence diagram below illustrates the processing flow for the given invoice IPP records.

File upload and processing

  1. File Location: The import file must be uploaded to Google Cloud Storage in the designated import drop path.
  2. Import Trigger: Cloud Scheduler provides the account ID and file location to the import manager service. The import is triggered via a request with the following payload:
    • bucket → Google Cloud Storage bucket name
    • importFileDropPath → Path where the file is located in the bucket
    • importFileName → Name of the JSON file to import
    • appDirectory → Local directory path for temporary file storage
    • accountId → Supplier group account ID in ViSN
    • persist → Boolean flag to determine if invoices should be created (true) or only validated (false)
    • fatalErrorEmailToAddress → Email address to receive fatal error notifications

Example payload:

{
"bucket": "import-bucket-name",
"importFileDropPath": "kwikfit-ipp/",
"importFileName": "kwikfit_invoices_20250115.json",
"appDirectory": "/tmp/imports/",
"accountId": "RMZj6hYyP4PqhobUm1zw",
"persist": true,
"fatalErrorEmailToAddress": "admin@example.com"
}

Data validation

  1. JSON Parsing: The file is parsed as JSON, extracting objects with INVOICE_HEADER properties.

  2. Schema Validation: Each invoice header object is validated against the kwikfitIppInvoiceSchema:

    • All mandatory fields must be present and non-empty
    • TAX_DATE must be in DD/MM/YYYY format
    • CAR_REGISTRATION must match VRM regex pattern
    • INVOICE_VALUE and VAT_TOTAL must be numeric in nnnnnn.nn format
    • ORDER_NO must be numeric
    • Field lengths must not exceed maximum limits
  3. Validation Results:

    • Valid rows are added to Cloud Task queue for invoice generation
    • Invalid rows are logged with specific validation errors
    • Processing statistics are generated (invoicesAddedToQueue, invoicesFailedValidation)

Cloud Task processing

The sequence diagram below illustrates how each record from the import file is processed through the queue.

Overview

Precondition checks

Before generating an invoice, the system performs the following validations:

  1. Service Unit Lookup:

    • Finds service unit within the provided account where supplierId matches DEPOT_NO
    • Abort if: Service unit not found
  2. Enquiry Lookup:

    • Finds enquiry by matching ORDER_NO (enquiryNumber) within the found service unit
    • Abort if: Enquiry not found
  3. VRM Validation:

    • Verifies CAR_REGISTRATION matches the enquiry's VRM
    • Abort if: VRM mismatch
  4. Enquiry Status Check:

    • Verifies enquiry can be completed (not already in a terminal state)
    • Abort if: Enquiry is in an invalid status
  5. MOT Details Check:

    • If enquiry has MOT job line, verifies MOT details are completed
    • Abort if: MOT details missing
  6. ADAS Certificate Check:

    • If enquiry has ADAS calibration, verifies ADAS certificate is saved
    • Abort if: ADAS certificate missing
  7. Invoice Total Matching:

    • Compares INVOICE_VALUE with ViSN's calculated grand total
    • Abort if: Totals do not match (logs both ViSN and IPP totals)

Enquiry Progression

When Preconditions are satisfied

  1. Progress to Completed:

    • Updates enquiry status to "Completed"
    • Adds event log entry with user "IPP"
  2. Generate Invoice Data:

    • Retrieves prefilled invoice data from the enquiry
    • Merges IPP invoice details:
      • taxPointDate → from TAX_DATE (formatted as "dd MMM yyyy")
      • invoiceNumber → from INVOICE_NO
      • invoiceSavedDate → current timestamp
      • calculatedGrandTotal → from prefilled data
  3. Save Invoice Data:

    • Saves invoice data to: accounts/{accountId}/serviceUnits/{serviceUnitId}/enquiries/{enquiryId}/invoices/invoice
  4. Create Invoice and Progress to Invoiced:

    • Calls the Callable service endpoint /api/v1/enquiry/invoices/createInvoice
    • The Callable service:
      • Creates invoice record in the lease company's invoice collection
      • Sets user as "IPP"
      • Links to stock ID if available
      • Progresses enquiry status from "Completed" to "Invoiced"
      • Updates both service unit enquiry and lease company enquiry documents
      • Sets invoiceGenerated flag to true
      • Saves enquiry to billing system
      • Updates search indices (Algolia/Typesense)
    • Note: Invoice PDF generation and export record creation are automatically handled as part of the invoicing process

Logging and reporting

Error scenarios

ScenarioResultLogged Reason
Service unit not foundAbortedsupplierId: {depotNo} is not found in account
Enquiry not foundAbortedenquiryNumber: {orderNo} is not found
VRM mismatchAbortedVRM: {carRegistration} does not match for enquiryId: {enquiryId}
Invalid enquiry statusAbortedenquiryId: {enquiryId} is in {status} status
MOT details missingAbortedenquiryId: {enquiryId} MOT details are not completed
ADAS certificate missingAbortedenquiryId: {enquiryId} ADAS certificate is not completed
Invoice total mismatchAbortedenquiryId: {enquiryId} Invoice value does not match ViSN: {visnTotal} IPP: {ippTotal}
Schema validation failureSkippedField-specific validation errors

Error Handling

  • Validation errors are logged per row with specific field errors
  • Precondition failures are logged with specific reason (e.g., "VRM mismatch", "enquiry not found")
  • Fatal errors trigger email notification to fatalErrorEmailToAddress

Import Logs

  • Location: ancillary/logs/ippInvoicing/logs/{year}/{month}/{date}/logs
  • Each row processed logs:
    • Row number
    • VRM
    • Enquiry number
    • Validation status or error messages
  • End-of-log entry contains aggregated statistics

Processing Statistics

  • invoicesAddedToQueue → Number of valid invoices queued
  • invoicesFailedValidation → Number of rows that failed schema validation
  • invoicesGenerated → Number of invoices successfully created
  • invoicesFailedGeneration → Number of invoices that failed during generation

Log CSV Export

  • A scheduled function (pubsub_generateIppInvoicingLogsCSV) generates CSV exports of the import logs
  • Trigger: Pub/Sub topic generateIppInvoicingLogsCSV
  • Default: Exports today's logs (can be configured with specific date)
  • Output Location: exports/ippInvoicing/logs/{year}/{monthName}/{day}/{ipp_invoicing_logs_{year}-{month}-{day}.csv}
  • Content: All log entries from the import process, excluding the end-of-log-entry document
  • Process Log: Creates a process log entry with type KWIKFIT_IPP_INVOICE containing statistics

Admin UI Monitoring

  • Process logs can be viewed in the Admin UI under Process Logs
  • Process log type: KWIKFIT_IPP_INVOICE
  • Displays statistics when import is successful:
    • Number of invoices added to queue
    • Number of invoices failed validation
    • Number of invoices generated
    • Number of invoices generation failed

Setup Required

Cloud Task Queue

The Cloud Task queue for IPP invoice generation should be configured:

  • Queue Name: ipp-invoice-generation
  • Target URL: Queue Services endpoint /ipp-invoice-generation
  • Task Type: FOR_IPP_INVOICE_GENERATION

Generate Log CSV Export

A Cloud Scheduler should be created to generate daily CSV exports of IPP invoicing logs (note: the import file itself is JSON, but the log exports are CSV for reporting):

A Scheduler should be created in Cloud Scheduler with the following parameters:

  • Name: Generate IPP invoicing logs CSV
  • Region: europe-west2
  • Frequency: Daily (recommended: 0 23 * * * - runs at 11 PM daily)
  • TimeZone: GMT London
  • Topic: projects/[PROJECT_ID]/topics/generateIppInvoicingLogsCSV
  • Message body: a JSON object including the following parameters (all optional):

    • dateTimeStamp: in format yyyy-MMM-dd ex 2025-Jan-15, when skipped it will default to today's date

Note: The scheduler exports the today's logs by default. To export logs for a specific date, include the dateTimeStamp parameter in the message body.

Authored By: Rama on Dec 24, 2025