CONN-801: extend update bills/suppliers docs to Sage Intacct, NetSuite, Zoho Books - #1875
Conversation
…e, Zoho Books - update-bill.md: coverage note, per-platform example payloads (including trackingRefs id formats), six-column software requirements table, new "Software-specific behavior" section, and error tabs for the three new platforms with verbatim error messages. - suppliers.md: coverage note and software-specific behavior tables for the three new platforms. - configure-customer.md: Sage Intacct (knfz) and Zoho Books (rwuv) added to the platformKey table. All platform behaviours were verified live against integration during CONN-799 acceptance testing rather than inferred from code. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Remaining comments which cannot be posted as a review comment to avoid GitHub Rate Limit
vale
📝 [vale] <Google.Contractions> reported by reviewdog 🐶
Use 'wasn't' instead of 'was not'.
codat-docs/docs/payables/sync/update-bill.md
Line 278 in 350ddc4
📝 [vale] <Google.Passive> reported by reviewdog 🐶
In general, use active voice instead of passive voice ('been used').
codat-docs/docs/payables/sync/update-bill.md
Line 305 in 350ddc4
📝 [vale] <Google.Contractions> reported by reviewdog 🐶
Use 'wasn't' instead of 'was not'.
codat-docs/docs/payables/sync/update-bill.md
Line 306 in 350ddc4
📝 [vale] <Google.Contractions> reported by reviewdog 🐶
Use 'can't' instead of 'cannot'.
codat-docs/docs/payables/sync/update-bill.md
Line 307 in 350ddc4
| :::info Software coverage | ||
|
|
||
| This action is currently only supported for FreeAgent, QuickBooks Online, and Xero. | ||
| This action is currently only supported for FreeAgent, Oracle NetSuite, QuickBooks Online, Sage Intacct, Xero, and Zoho Books. |
There was a problem hiding this comment.
📝 [vale] <Google.Timeless> reported by reviewdog 🐶
Avoid time-based words like 'currently' in product documentation.
| | **Supplier name** | It's not possible to clear the supplier name. Sending a `null` value or excluding the field keeps the existing name. | | ||
| | **Default currency** | Sending a `null` value keeps the existing currency, but sending `""` clears the supplier's currency on the platform. | | ||
| | **Addresses** | Sage Intacct supports a single address per supplier, and the response returns the first address only. | | ||
| | **Contact name** | `contactName` is split on the last space into a first and last name, each limited to 40 characters. | |
There was a problem hiding this comment.
📝 [vale] <Google.Passive> reported by reviewdog 🐶
In general, use active voice instead of passive voice ('is split').
| :::info Software coverage | ||
|
|
||
| This action is currently only supported for FreeAgent, QuickBooks Online, and Xero. | ||
| This action is currently only supported for FreeAgent, Oracle NetSuite, QuickBooks Online, Sage Intacct, Xero, and Zoho Books. |
There was a problem hiding this comment.
📝 [vale] <Google.Timeless> reported by reviewdog 🐶
Avoid time-based words like 'currently' in product documentation.
|
… sheet The limitations section belongs in the Bill Pay Kit acceptance-testing cheat sheets rather than the public docs; the requirements table and error tabs carry the client-facing essentials. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
|
||
| | Issue | Error message | | ||
| | ------------------------------- | ----------------------------------------- | | ||
| | Invalid supplier ID | `Supplier Ref` was not found in NetSuite. | |
There was a problem hiding this comment.
📝 [vale] <Google.Contractions> reported by reviewdog 🐶
Use 'wasn't' instead of 'was not'.
| | Invalid supplier ID | `Supplier Ref` was not found in NetSuite. | | |
| | Invalid supplier ID | `Supplier Ref` wasn't found in NetSuite. | |
| | Issue | Error message | | ||
| | ------------------------------- | ----------------------------------------- | | ||
| | Invalid supplier ID | `Supplier Ref` was not found in NetSuite. | | ||
| | Invalid account ID | `Account Ref` was not found in NetSuite. | |
There was a problem hiding this comment.
📝 [vale] <Google.Contractions> reported by reviewdog 🐶
Use 'wasn't' instead of 'was not'.
| | Invalid account ID | `Account Ref` was not found in NetSuite. | | |
| | Invalid account ID | `Account Ref` wasn't found in NetSuite. | |
| | ------------------------------- | ----------------------------------------- | | ||
| | Invalid supplier ID | `Supplier Ref` was not found in NetSuite. | | ||
| | Invalid account ID | `Account Ref` was not found in NetSuite. | | ||
| | Invalid tax rate ID | `Tax Rate Ref` was not found in NetSuite. | |
There was a problem hiding this comment.
📝 [vale] <Google.Contractions> reported by reviewdog 🐶
Use 'wasn't' instead of 'was not'.
| | Invalid tax rate ID | `Tax Rate Ref` was not found in NetSuite. | | |
| | Invalid tax rate ID | `Tax Rate Ref` wasn't found in NetSuite. | |
| | Invalid supplier ID | `Supplier Ref` was not found in NetSuite. | | ||
| | Invalid account ID | `Account Ref` was not found in NetSuite. | | ||
| | Invalid tax rate ID | `Tax Rate Ref` was not found in NetSuite. | | ||
| | Changed or unsupported currency | `Currency` is not supported for supplier. | |
There was a problem hiding this comment.
📝 [vale] <Google.Contractions> reported by reviewdog 🐶
Use 'isn't' instead of 'is not'.
| | Changed or unsupported currency | `Currency` is not supported for supplier. | | |
| | Changed or unsupported currency | `Currency` isn't supported for supplier. | |
|
|
||
| | Issue | Error message | | ||
| | ------------------------- | ----------------------------------------------------------------------- | | ||
| | Bill fully or partly paid | This bill has been paid or partially paid and can no longer be updated. | |
There was a problem hiding this comment.
📝 [vale] <Google.Passive> reported by reviewdog 🐶
In general, use active voice instead of passive voice ('been paid').
|
|
||
| | Issue | Error message | | ||
| | ------------------------- | ----------------------------------------------------------------------- | | ||
| | Bill fully or partly paid | This bill has been paid or partially paid and can no longer be updated. | |
There was a problem hiding this comment.
📝 [vale] <Google.Passive> reported by reviewdog 🐶
In general, use active voice instead of passive voice ('be updated').
| | Issue | Error message | | ||
| | ------------------------- | ----------------------------------------------------------------------- | | ||
| | Bill fully or partly paid | This bill has been paid or partially paid and can no longer be updated. | | ||
| | Invalid supplier ID | The Supplier with Id `<id>` was not found. | |
There was a problem hiding this comment.
📝 [vale] <Google.Contractions> reported by reviewdog 🐶
Use 'wasn't' instead of 'was not'.
| | Invalid supplier ID | The Supplier with Id `<id>` was not found. | | |
| | Invalid supplier ID | The Supplier with Id `<id>` wasn't found. | |
|
|
||
| | Issue | Error message | | ||
| | -------------------------- | ------------------------------------------------- | | ||
| | Duplicate reference | Reference has already been used for this supplier | |
There was a problem hiding this comment.
📝 [vale] <Google.Passive> reported by reviewdog 🐶
In general, use active voice instead of passive voice ('been used').
| | Issue | Error message | | ||
| | -------------------------- | ------------------------------------------------- | | ||
| | Duplicate reference | Reference has already been used for this supplier | | ||
| | Invalid supplier ID | `SupplierRef Id` was not found in ZohoBooks. | |
There was a problem hiding this comment.
📝 [vale] <Google.Contractions> reported by reviewdog 🐶
Use 'wasn't' instead of 'was not'.
| | Invalid supplier ID | `SupplierRef Id` was not found in ZohoBooks. | | |
| | Invalid supplier ID | `SupplierRef Id` wasn't found in ZohoBooks. | |
| | -------------------------- | ------------------------------------------------- | | ||
| | Duplicate reference | Reference has already been used for this supplier | | ||
| | Invalid supplier ID | `SupplierRef Id` was not found in ZohoBooks. | | ||
| | Negative bill total | The total amount due cannot be negative. | |
There was a problem hiding this comment.
📝 [vale] <Google.Contractions> reported by reviewdog 🐶
Use 'can't' instead of 'cannot'.
| | Negative bill total | The total amount due cannot be negative. | | |
| | Negative bill total | The total amount due can't be negative. | |
Pre-existing on main: the separator row declared a third column and the archived-suppliers row carried a stray trailing cell. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Converts the six per-platform headings into the same Tabs/TabItem layout the update-bill page uses for its software-specific errors, sharing groupId="software" so the platform selection carries across pages. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
| | Limitation | Description | | ||
| | -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ||
| | **Status** | Always include `status` in the request. Omitting it reactivates an archived supplier. | | ||
| | **Contact name** | `contactName` is not supported on update. Any value sent in the request is ignored and the response returns `null`. | |
There was a problem hiding this comment.
📝 [vale] <Google.Contractions> reported by reviewdog 🐶
Use 'isn't' instead of 'is not'.
| | **Contact name** | `contactName` is not supported on update. Any value sent in the request is ignored and the response returns `null`. | | |
| | **Contact name** | `contactName` isn't supported on update. Any value sent in the request is ignored and the response returns `null`. | |
| | Limitation | Description | | ||
| | -------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ||
| | **Status** | Always include `status` in the request. Omitting it reactivates an archived supplier. | | ||
| | **Contact name** | `contactName` is not supported on update. Any value sent in the request is ignored and the response returns `null`. | |
There was a problem hiding this comment.
📝 [vale] <Google.Passive> reported by reviewdog 🐶
In general, use active voice instead of passive voice ('is ignored').
| | **Contact name** | `contactName` is not supported on update. Any value sent in the request is ignored and the response returns `null`. | | ||
| | **Duplicate names** | Supplier names must be unique. Updating a name to match an existing supplier returns a `400` response. | | ||
| | **Supplier name** | Omitting `supplierName` clears it. Include the existing name if you don't want to change it. | | ||
| | **Default currency** | The currency must be enabled in the NetSuite organization, or the update returns a `400` response. Sending a `null` value leaves the existing currency unchanged. | |
There was a problem hiding this comment.
📝 [vale] <Google.Passive> reported by reviewdog 🐶
In general, use active voice instead of passive voice ('be enabled').
| | **Supplier name** | It's not possible to clear the supplier name. Sending a `null` value or excluding the field keeps the existing name. | | ||
| | **Duplicate names** | Supplier names must be unique, unless the Zoho Books organization allows duplicate vendor names. Updating a name to match an existing supplier returns a `400` response. | | ||
| | **Default currency** | The currency must exist in the Zoho Books organization's currency list, or the update returns a `400` response. Sending a `null` value keeps the existing currency. Changing a supplier's currency also changes the currency of bills created for that supplier, because Zoho Books derives bill currency from the supplier. | | ||
| | **Addresses** | Billing and delivery addresses are replaced together. Sending only a billing address clears the delivery address. | |
There was a problem hiding this comment.
📝 [vale] <Google.Passive> reported by reviewdog 🐶
In general, use active voice instead of passive voice ('are replaced').
| | **Duplicate names** | Supplier names must be unique, unless the Zoho Books organization allows duplicate vendor names. Updating a name to match an existing supplier returns a `400` response. | | ||
| | **Default currency** | The currency must exist in the Zoho Books organization's currency list, or the update returns a `400` response. Sending a `null` value keeps the existing currency. Changing a supplier's currency also changes the currency of bills created for that supplier, because Zoho Books derives bill currency from the supplier. | | ||
| | **Addresses** | Billing and delivery addresses are replaced together. Sending only a billing address clears the delivery address. | | ||
| | **Archived suppliers** | Archived suppliers can still be updated — the field changes are applied and the supplier remains archived. A rejected update never changes the supplier's status. | |
There was a problem hiding this comment.
📝 [vale] <Google.Passive> reported by reviewdog 🐶
In general, use active voice instead of passive voice ('be updated').
| | **Duplicate names** | Supplier names must be unique, unless the Zoho Books organization allows duplicate vendor names. Updating a name to match an existing supplier returns a `400` response. | | ||
| | **Default currency** | The currency must exist in the Zoho Books organization's currency list, or the update returns a `400` response. Sending a `null` value keeps the existing currency. Changing a supplier's currency also changes the currency of bills created for that supplier, because Zoho Books derives bill currency from the supplier. | | ||
| | **Addresses** | Billing and delivery addresses are replaced together. Sending only a billing address clears the delivery address. | | ||
| | **Archived suppliers** | Archived suppliers can still be updated — the field changes are applied and the supplier remains archived. A rejected update never changes the supplier's status. | |
There was a problem hiding this comment.
🚫 [vale] <Google.EmDash> reported by reviewdog 🐶
Don't put a space before or after a dash.
| | **Archived suppliers** | Archived suppliers can still be updated — the field changes are applied and the supplier remains archived. A rejected update never changes the supplier's status. | | |
| | **Archived suppliers** | Archived suppliers can still be updated—the field changes are applied and the supplier remains archived. A rejected update never changes the supplier's status. | |
| | **Duplicate names** | Supplier names must be unique, unless the Zoho Books organization allows duplicate vendor names. Updating a name to match an existing supplier returns a `400` response. | | ||
| | **Default currency** | The currency must exist in the Zoho Books organization's currency list, or the update returns a `400` response. Sending a `null` value keeps the existing currency. Changing a supplier's currency also changes the currency of bills created for that supplier, because Zoho Books derives bill currency from the supplier. | | ||
| | **Addresses** | Billing and delivery addresses are replaced together. Sending only a billing address clears the delivery address. | | ||
| | **Archived suppliers** | Archived suppliers can still be updated — the field changes are applied and the supplier remains archived. A rejected update never changes the supplier's status. | |
There was a problem hiding this comment.
📝 [vale] <Google.Passive> reported by reviewdog 🐶
In general, use active voice instead of passive voice ('are applied').
| #### QuickBooks Online | ||
| | Limitation | Description | | ||
| | -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ||
| | **Supplier name** | If `supplierName` is `null` in the request, FreeAgent uses the value in `contactName` instead (the value must contain a space). If both fields are `null`, FreeAgent returns a `400` response. | |
There was a problem hiding this comment.
FreeAgent returns a
400response.
I wonder if this is the correct perspective? If I was reading documentation I would care more about what the service I am consuming returns. It might be better to state that Codat rejects both fields being null and returns a 400 because FreeAgent doesn't allow it.
There was a problem hiding this comment.
If we do validate it, that is
There was a problem hiding this comment.
Changed to "If supplierName is null in the request, FreeAgent uses the value in contactName instead (the value must contain a space). Codat rejects a request where both fields are null with a
400 response, because FreeAgent requires a name."
Review feedback (Huw): the 400 comes from Codat-side validation (FreeAgentUpdateSupplierValidator - "Supplier Name or Contact Name must be provided"), not from FreeAgent; the request never reaches the platform. Reworded from the consumer perspective. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
|
||
| | Limitation | Description | | ||
| | -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ||
| | **Supplier name** | If `supplierName` is `null` in the request, FreeAgent uses the value in `contactName` instead (the value must contain a space). Codat rejects a request where both fields are `null` with a `400` response, because FreeAgent requires a name. | |
There was a problem hiding this comment.
📝 [vale] <Google.Parens> reported by reviewdog 🐶
Use parentheses judiciously.
| | -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | ||
| | **Supplier name** | If `supplierName` is `null` in the request, FreeAgent uses the value in `contactName` instead (the value must contain a space). Codat rejects a request where both fields are `null` with a `400` response, because FreeAgent requires a name. | | ||
| | **Country** | It's not possible to clear the supplier's country. Sending a `null` value or excluding the field from the request sets the value to the company's default country. | | ||
| | **Default currency** | FreeAgent doesn't support currency at supplier level. Any value sent in the request is ignored, and the response returns the company's base currency. | |
There was a problem hiding this comment.
📝 [vale] <Google.Passive> reported by reviewdog 🐶
In general, use active voice instead of passive voice ('is ignored').
|
Link check results: |
What
Extends the Bill Pay (sync) update documentation from the original three platforms (FreeAgent, QBO, Xero) to the three added by the CONN-783 epic: Sage Intacct, Oracle NetSuite, and Zoho Books.
docs/payables/sync/update-bill.mdtrackingRefsid formats (department-<id>/location-<id>and customer refs for NetSuite;<tagId>-<tagOptionId>and customer refs for Zoho Books).docs/payables/sync/suppliers.md— coverage note plus Software-specific behavior tables for the three new platforms (name/currency/status preservation semantics, NetSuite's unsupportedcontactNameand always-send-statusguidance, Sage Intacct's single-address and 40-character name-split limits, Zoho Books' paired address replacement and archived-supplier behaviour). The whole Software-specific behavior section (all six platforms) is now presented as platform tabs, matching the update-bill page's error tabs and sharing itsgroupIdso the platform selection carries across pages. Also repairs the pre-existing malformed Xero limitations table (stray third column in the separator and a trailing empty cell).docs/payables/configure-customer.md— Sage Intacct (knfz) and Zoho Books (rwuv) added to the platformKey table.The behavioural quirks for updating bills (currency models, reference-on-omission, tax-period and subsidiary constraints, Zoho's 404 quirk) deliberately live in the internal Bill Pay Kit cheat sheets rather than these public pages — the requirements table and error tabs carry the client-facing essentials.
The "Supported integrations" pages use the dynamic
IntegrationsListcomponent whoseintegrationsFilterBillPaySynclist already includes all six platforms — no change needed there.Provenance
Every behaviour documented here was verified live against integration during CONN-799 acceptance testing (all six AC suites green), not inferred from code.
Reviewer notes
statusreactivates an archived supplier" documents current behaviour, which is also tracked as a candidate fix (CONN-1522). If that ships, this row needs updating.npm run build); the three files were auto-formatted by the pre-commit prettier hook; cspell passes.🤖 Generated with Claude Code