To continue my work on the upload of invoices, from your reactions, I found that it's highly appreciated if the work will be released to the community as open source and by consequence, I'm submitting the proposal for review, to make it as usefull as possible to the wider audience.
Goal for my customer is to upload invoices which can be edited after upload. They're on 1.3, so, posting draft invoices is not an option. We've decided to go with saving orders. These orders can be converted to invoices after review and possibly after being completed.
As it turns out, there's very little technical difference in saving an invoice or saving an order, so I'm now aiming to solve both at the same time.
In order to document the interface, I've created the XSD below and I would highly appreciate your review. The idea behind the XSD is the following process:
One of the things I'm thinking about is to require the server to return a 207 (with associated multistatus response body)
So, would this work for you? Do you have enhancements, either to the process or to the XSD?
<?xml version="1.0" encoding="utf-8"?>
<xs:simpleType id="invoice-target-type" name="invoice-target-type">
<xs:restriction base="xs:string">
<xs:enumeration value="AR" />
<xs:enumeration value="AP" />
<xs:enumeration value="sales-order" />
<xs:enumeration value="purchase-order" />
</xs:restriction>
</xs:simpleType>
<xs:element name="invoice-upload">
<xs:annotation>
<xs:documentation>The 'invoice-upload' tag contains a list of invoices to be uploaded, optionally preceded by FX rates to be used for the transactions, if no other rate is already in the system.</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:element maxOccurs="unbounded" name="fx-rate">
<xs:complexType>
<xs:attribute name="curr" type="xs:string" use="required" />
<xs:attribute name="buy" type="xs:decimal" use="required" />
<xs:attribute name="sell" type="xs:decimal" use="required" />
<xs:attribute name="date" type="xs:date" use="required" />
</xs:complexType>
</xs:element>
<xs:element minOccurs="0" maxOccurs="unbounded" name="invoice">
<xs:annotation>
<xs:documentation>The 'invoice' tag contains the actual invoice data to be inserted into the system</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="ship-to" type="xs:string" />
<xs:element minOccurs="0" name="ship-via" type="xs:string" />
<xs:element minOccurs="0" maxOccurs="unbounded" name="invoice-row">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="description" type="xs:string" />
<xs:element minOccurs="0" name="notes" type="xs:string" />
</xs:sequence>
<xs:attribute name="partnumber" type="xs:string" use="required" />
<xs:attribute name="quantity" type="xs:decimal" use="optional" />
<xs:attribute name="unit" type="xs:string" use="optional" />
<xs:attribute name="price" type="xs:decimal" use="optional" />
<xs:attribute name="discount" type="xs:decimal" use="optional" />
<xs:attribute default="false" name="taxform-applied" type="xs:boolean" use="optional" />
<xs:attribute name="date" type="xs:date" use="optional" />
<xs:attribute name="serial" type="xs:string" use="optional" />
<xs:attribute name="project" type="xs:string" use="optional" />
</xs:complexType>
</xs:element>
<xs:element minOccurs="0" name="notes" type="xs:string" />
<xs:element minOccurs="0" name="internal-notes" type="xs:string" />
</xs:sequence>
<xs:attribute name="type" type="invoice-target-type" use="required" />
<xs:attribute name="number" type="xs:string" use="optional" />
<xs:attribute name="date" type="xs:date" use="required">
<xs:annotation>
<xs:documentation>Identifies the order date in case of orders or the transaction date in case of invoices</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="currency" use="optional" />
<xs:attribute name="meta-number" type="xs:string" use="required">
<xs:annotation>
<xs:documentation>Identifies the customer or vendor number to create the item for</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="employee-id" type="xs:positiveInteger" use="required" />
<xs:attribute default="false" name="tax-included" type="xs:boolean" use="optional" />
<xs:attribute name="due" type="xs:date" use="optional">
<xs:annotation>
<xs:documentation>Due date for invoices, required by date for orders.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="crdate" type="xs:date" use="optional">
<xs:annotation>
<xs:documentation>Used only for invoices.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:sequence>
<xs:attribute default="true" name="atomic" type="xs:boolean" use="optional" />
</xs:complexType>
</xs:element>
<xs:element name="invoice-upload-response">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" maxOccurs="unbounded" name="item-response">
<xs:complexType>
<xs:attribute name="sequence-number" type="xs:positiveInteger" use="required" />
<xs:attribute name="success" type="xs:boolean" use="required" />
<xs:attribute name="value" type="xs:string" use="required" />
</xs:complexType>
</xs:element>
</xs:sequence>
</xs:complexType>
</xs:element>
</xs:schema>