{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://viopo.co.uk/schema/po.v1.json",
  "title": "VioPO purchase order, version 1",
  "type": "object",
  "additionalProperties": false,
  "required": [
    "schema",
    "document",
    "header",
    "buyer",
    "supplier",
    "ship_to",
    "bill_to",
    "invoice",
    "lines",
    "totals",
    "checks",
    "warnings"
  ],
  "properties": {
    "schema": {
      "const": "viopo.po.v1"
    },
    "document": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "is_purchase_order",
        "pages",
        "source_type",
        "text_layer"
      ],
      "properties": {
        "is_purchase_order": {
          "type": "boolean",
          "description": "False when the file does not look like a purchase order."
        },
        "pages": {
          "type": "integer",
          "minimum": 1
        },
        "source_type": {
          "enum": [
            "pdf",
            "png",
            "jpeg",
            "webp",
            "tiff",
            "gif"
          ]
        },
        "text_layer": {
          "type": "boolean",
          "description": "True when the PDF carried selectable text that was read alongside the page images."
        }
      }
    },
    "header": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "po_number",
        "po_date",
        "revision",
        "currency",
        "quote_reference",
        "requested_delivery_date",
        "payment_terms",
        "shipping_method",
        "incoterms",
        "notes"
      ],
      "properties": {
        "po_number": {
          "type": [
            "string",
            "null"
          ]
        },
        "po_date": {
          "type": [
            "string",
            "null"
          ],
          "format": "date",
          "description": "ISO 8601 date, YYYY-MM-DD."
        },
        "revision": {
          "type": [
            "string",
            "null"
          ]
        },
        "currency": {
          "type": [
            "string",
            "null"
          ],
          "description": "ISO 4217 code, for example GBP, EUR or USD."
        },
        "quote_reference": {
          "type": [
            "string",
            "null"
          ]
        },
        "requested_delivery_date": {
          "type": [
            "string",
            "null"
          ],
          "format": "date",
          "description": "ISO 8601 date, YYYY-MM-DD."
        },
        "payment_terms": {
          "type": [
            "string",
            "null"
          ]
        },
        "shipping_method": {
          "type": [
            "string",
            "null"
          ]
        },
        "incoterms": {
          "type": [
            "string",
            "null"
          ]
        },
        "notes": {
          "type": [
            "string",
            "null"
          ]
        }
      }
    },
    "buyer": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "name",
        "contact_name",
        "email",
        "phone",
        "tax_id",
        "company_number",
        "account_reference",
        "address"
      ],
      "properties": {
        "name": {
          "type": [
            "string",
            "null"
          ]
        },
        "contact_name": {
          "type": [
            "string",
            "null"
          ]
        },
        "email": {
          "type": [
            "string",
            "null"
          ]
        },
        "phone": {
          "type": [
            "string",
            "null"
          ]
        },
        "tax_id": {
          "type": [
            "string",
            "null"
          ],
          "description": "VAT, GST, EIN or similar, as printed."
        },
        "company_number": {
          "type": [
            "string",
            "null"
          ]
        },
        "account_reference": {
          "type": [
            "string",
            "null"
          ],
          "description": "An account, vendor or customer number one party gives the other."
        },
        "address": {
          "type": [
            "object",
            "null"
          ],
          "additionalProperties": false,
          "required": [
            "name",
            "lines",
            "city",
            "region",
            "postal_code",
            "country"
          ],
          "properties": {
            "name": {
              "type": [
                "string",
                "null"
              ]
            },
            "lines": {
              "type": "array",
              "items": {
                "type": "string"
              },
              "description": "Street lines, in the order printed."
            },
            "city": {
              "type": [
                "string",
                "null"
              ]
            },
            "region": {
              "type": [
                "string",
                "null"
              ],
              "description": "County, state or province."
            },
            "postal_code": {
              "type": [
                "string",
                "null"
              ]
            },
            "country": {
              "type": [
                "string",
                "null"
              ],
              "description": "ISO 3166-1 alpha-2 code when it can be told, for example GB or US."
            }
          }
        }
      }
    },
    "supplier": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "name",
        "contact_name",
        "email",
        "phone",
        "tax_id",
        "company_number",
        "account_reference",
        "address"
      ],
      "properties": {
        "name": {
          "type": [
            "string",
            "null"
          ]
        },
        "contact_name": {
          "type": [
            "string",
            "null"
          ]
        },
        "email": {
          "type": [
            "string",
            "null"
          ]
        },
        "phone": {
          "type": [
            "string",
            "null"
          ]
        },
        "tax_id": {
          "type": [
            "string",
            "null"
          ],
          "description": "VAT, GST, EIN or similar, as printed."
        },
        "company_number": {
          "type": [
            "string",
            "null"
          ]
        },
        "account_reference": {
          "type": [
            "string",
            "null"
          ],
          "description": "An account, vendor or customer number one party gives the other."
        },
        "address": {
          "type": [
            "object",
            "null"
          ],
          "additionalProperties": false,
          "required": [
            "name",
            "lines",
            "city",
            "region",
            "postal_code",
            "country"
          ],
          "properties": {
            "name": {
              "type": [
                "string",
                "null"
              ]
            },
            "lines": {
              "type": "array",
              "items": {
                "type": "string"
              },
              "description": "Street lines, in the order printed."
            },
            "city": {
              "type": [
                "string",
                "null"
              ]
            },
            "region": {
              "type": [
                "string",
                "null"
              ],
              "description": "County, state or province."
            },
            "postal_code": {
              "type": [
                "string",
                "null"
              ]
            },
            "country": {
              "type": [
                "string",
                "null"
              ],
              "description": "ISO 3166-1 alpha-2 code when it can be told, for example GB or US."
            }
          }
        }
      }
    },
    "ship_to": {
      "type": [
        "object",
        "null"
      ],
      "additionalProperties": false,
      "required": [
        "name",
        "lines",
        "city",
        "region",
        "postal_code",
        "country"
      ],
      "properties": {
        "name": {
          "type": [
            "string",
            "null"
          ]
        },
        "lines": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Street lines, in the order printed."
        },
        "city": {
          "type": [
            "string",
            "null"
          ]
        },
        "region": {
          "type": [
            "string",
            "null"
          ],
          "description": "County, state or province."
        },
        "postal_code": {
          "type": [
            "string",
            "null"
          ]
        },
        "country": {
          "type": [
            "string",
            "null"
          ],
          "description": "ISO 3166-1 alpha-2 code when it can be told, for example GB or US."
        }
      }
    },
    "bill_to": {
      "type": [
        "object",
        "null"
      ],
      "additionalProperties": false,
      "required": [
        "name",
        "lines",
        "city",
        "region",
        "postal_code",
        "country"
      ],
      "properties": {
        "name": {
          "type": [
            "string",
            "null"
          ]
        },
        "lines": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "Street lines, in the order printed."
        },
        "city": {
          "type": [
            "string",
            "null"
          ]
        },
        "region": {
          "type": [
            "string",
            "null"
          ],
          "description": "County, state or province."
        },
        "postal_code": {
          "type": [
            "string",
            "null"
          ]
        },
        "country": {
          "type": [
            "string",
            "null"
          ],
          "description": "ISO 3166-1 alpha-2 code when it can be told, for example GB or US."
        }
      }
    },
    "invoice": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "email",
        "address",
        "instructions"
      ],
      "properties": {
        "email": {
          "type": [
            "string",
            "null"
          ],
          "description": "Where the buyer wants invoices sent, when the order says."
        },
        "address": {
          "type": [
            "object",
            "null"
          ],
          "additionalProperties": false,
          "required": [
            "name",
            "lines",
            "city",
            "region",
            "postal_code",
            "country"
          ],
          "properties": {
            "name": {
              "type": [
                "string",
                "null"
              ]
            },
            "lines": {
              "type": "array",
              "items": {
                "type": "string"
              },
              "description": "Street lines, in the order printed."
            },
            "city": {
              "type": [
                "string",
                "null"
              ]
            },
            "region": {
              "type": [
                "string",
                "null"
              ],
              "description": "County, state or province."
            },
            "postal_code": {
              "type": [
                "string",
                "null"
              ]
            },
            "country": {
              "type": [
                "string",
                "null"
              ],
              "description": "ISO 3166-1 alpha-2 code when it can be told, for example GB or US."
            }
          }
        },
        "instructions": {
          "type": [
            "string",
            "null"
          ]
        }
      }
    },
    "lines": {
      "type": "array",
      "items": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "line_number",
          "buyer_part_number",
          "supplier_part_number",
          "description",
          "quantity",
          "unit_of_measure",
          "unit_price",
          "discount_percent",
          "tax_rate_percent",
          "line_total",
          "delivery_date"
        ],
        "properties": {
          "line_number": {
            "type": "integer",
            "minimum": 1,
            "description": "Position in the order, from 1, even when the document numbers lines 10, 20, 30."
          },
          "buyer_part_number": {
            "type": [
              "string",
              "null"
            ]
          },
          "supplier_part_number": {
            "type": [
              "string",
              "null"
            ]
          },
          "description": {
            "type": [
              "string",
              "null"
            ]
          },
          "quantity": {
            "type": [
              "number",
              "null"
            ]
          },
          "unit_of_measure": {
            "type": [
              "string",
              "null"
            ],
            "description": "UN/ECE Recommendation 20 code where one is known (EA, BX, PR, KGM), otherwise as printed."
          },
          "unit_price": {
            "type": [
              "number",
              "null"
            ]
          },
          "discount_percent": {
            "type": [
              "number",
              "null"
            ]
          },
          "tax_rate_percent": {
            "type": [
              "number",
              "null"
            ]
          },
          "line_total": {
            "type": [
              "number",
              "null"
            ],
            "description": "Net of tax, as printed. Null when the document does not print one."
          },
          "delivery_date": {
            "type": [
              "string",
              "null"
            ],
            "format": "date",
            "description": "ISO 8601 date, YYYY-MM-DD."
          }
        }
      }
    },
    "totals": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "subtotal",
        "discount",
        "shipping",
        "tax",
        "total"
      ],
      "properties": {
        "subtotal": {
          "type": [
            "number",
            "null"
          ]
        },
        "discount": {
          "type": [
            "number",
            "null"
          ]
        },
        "shipping": {
          "type": [
            "number",
            "null"
          ]
        },
        "tax": {
          "type": [
            "number",
            "null"
          ]
        },
        "total": {
          "type": [
            "number",
            "null"
          ]
        }
      }
    },
    "checks": {
      "type": "array",
      "description": "Arithmetic checks run on the extracted figures. A failed check means a figure should be looked at by a person.",
      "items": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "name",
          "passed",
          "detail"
        ],
        "properties": {
          "name": {
            "type": "string"
          },
          "passed": {
            "type": "boolean"
          },
          "detail": {
            "type": "string"
          }
        }
      }
    },
    "warnings": {
      "type": "array",
      "items": {
        "type": "string"
      }
    }
  }
}
