Skip to content

CONN-801: extend update bills/suppliers docs to Sage Intacct, NetSuite, Zoho Books - #1875

Merged
NathanJCodat merged 5 commits into
mainfrom
CONN-801
Aug 7, 2026
Merged

CONN-801: extend update bills/suppliers docs to Sage Intacct, NetSuite, Zoho Books#1875
NathanJCodat merged 5 commits into
mainfrom
CONN-801

Conversation

@NathanJCodat

@NathanJCodat NathanJCodat commented Aug 7, 2026

Copy link
Copy Markdown
Collaborator

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.md
    • Software coverage note now lists all six platforms.
    • Example payload tabs for NetSuite, Sage Intacct and Zoho Books, including each platform's trackingRefs id formats (department-<id> / location-<id> and customer refs for NetSuite; <tagId>-<tagOptionId> and customer refs for Zoho Books).
    • Software requirements table extended to six columns (reference maxima 45/100/50 for the new three, tax rules, accountRef formats).
    • Software-specific error tabs for the three new platforms with verbatim error messages.
  • docs/payables/sync/suppliers.md — coverage note plus Software-specific behavior tables for the three new platforms (name/currency/status preservation semantics, NetSuite's unsupported contactName and always-send-status guidance, 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 its groupId so 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 IntegrationsList component whose integrationsFilterBillPaySync list 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

  • The NetSuite supplier row "omitting status reactivates an archived supplier" documents current behaviour, which is also tracked as a candidate fix (CONN-1522). If that ships, this row needs updating.
  • Site builds clean (npm run build); the three files were auto-formatted by the pre-commit prettier hook; cspell passes.

🤖 Generated with Claude Code

…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>

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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'.

| Invalid supplier ID | The Supplier with Id `<id>` was not found. |


📝 [vale] <Google.Passive> reported by reviewdog 🐶
In general, use active voice instead of passive voice ('been used').

| Duplicate reference | Reference has already been used for this supplier |


📝 [vale] <Google.Contractions> reported by reviewdog 🐶
Use 'wasn't' instead of 'was not'.

| Invalid supplier ID | `SupplierRef Id` was not found in ZohoBooks. |


📝 [vale] <Google.Contractions> reported by reviewdog 🐶
Use 'can't' instead of 'cannot'.

| Negative bill total | The total amount due cannot be negative. |

:::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.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 [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. |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 [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.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 [vale] <Google.Timeless> reported by reviewdog 🐶
Avoid time-based words like 'currently' in product documentation.

@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown
PR Preview Action v1.8.1
Preview removed because the pull request was closed.
2026-08-07 13:31 UTC

… 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. |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 [vale] <Google.Contractions> reported by reviewdog 🐶
Use 'wasn't' instead of 'was not'.

Suggested change
| 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. |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 [vale] <Google.Contractions> reported by reviewdog 🐶
Use 'wasn't' instead of 'was not'.

Suggested change
| 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. |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 [vale] <Google.Contractions> reported by reviewdog 🐶
Use 'wasn't' instead of 'was not'.

Suggested change
| 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. |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 [vale] <Google.Contractions> reported by reviewdog 🐶
Use 'isn't' instead of 'is not'.

Suggested change
| 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. |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 [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. |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 [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. |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 [vale] <Google.Contractions> reported by reviewdog 🐶
Use 'wasn't' instead of 'was not'.

Suggested change
| 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 |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 [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. |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 [vale] <Google.Contractions> reported by reviewdog 🐶
Use 'wasn't' instead of 'was not'.

Suggested change
| 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. |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 [vale] <Google.Contractions> reported by reviewdog 🐶
Use 'can't' instead of 'cannot'.

Suggested change
| Negative bill total | The total amount due cannot be negative. |
| Negative bill total | The total amount due can't be negative. |

@NathanJCodat
NathanJCodat marked this pull request as ready for review August 7, 2026 11:08
NathanJCodat and others added 2 commits August 7, 2026 12:11
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`. |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 [vale] <Google.Contractions> reported by reviewdog 🐶
Use 'isn't' instead of 'is not'.

Suggested change
| **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`. |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 [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. |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 [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. |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 [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. |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 [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. |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🚫 [vale] <Google.EmDash> reported by reviewdog 🐶
Don't put a space before or after a dash.

Suggested change
| **Archived suppliers** | Archived suppliers can still be updatedthe 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 updatedthe 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. |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 [vale] <Google.Passive> reported by reviewdog 🐶
In general, use active voice instead of passive voice ('are applied').

Comment thread docs/payables/sync/suppliers.md Outdated
#### 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. |

@Huweey Huweey Aug 7, 2026

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FreeAgent returns a 400 response.

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.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we do validate it, that is

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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. |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 [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. |

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📝 [vale] <Google.Passive> reported by reviewdog 🐶
In general, use active voice instead of passive voice ('is ignored').

@github-actions

github-actions Bot commented Aug 7, 2026

Copy link
Copy Markdown

Link check results:

[]

@NathanJCodat
NathanJCodat merged commit 182ae5c into main Aug 7, 2026
8 checks passed
@NathanJCodat
NathanJCodat deleted the CONN-801 branch August 7, 2026 13:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants