The situation
A distributor moved invoice and statement delivery to BillTrust, a receivables portal that prints, faxes, emails or publishes each document according to the customer's preference. The portal expects documents in its own package, made of PDFs, an index file describing each one and how to deliver it, and a file of open balances. NetSuite produces none of these on its own, and assembling them by hand every day was not realistic.
What we built
A Map/Reduce integration, with a second job that marks what was sent.
- Selection. The job finds invoices, credit memos and customer statements due for delivery. For each document it reads the customer's routing preference for transactions and for statements, which is print, fax, email or web.
- Validation. Where the route needs one, the email address or fax number is mandatory. A document without it goes into the error report and is not sent.
- Rendering. Each document is rendered to PDF from the customer's Advanced PDF template.
- Packaging. The PDFs are zipped together with a CSV index that carries the addresses and routing codes the portal expects, formatted to its rules (for example, US postal codes padded to five digits).
- Balances. A separate flow produces the open-balance file for customers with a non-zero balance.
- Delivery. The zip and the balance file go to the portal's SFTP server.
- Marking. A second Map/Reduce takes the internal ids from the run and marks each transaction as exported.
What it does now
The run happens on a schedule. Customers receive their documents by the route they chose, and nobody in receivables prints or emails them. Because each transaction is marked once exported, the next run picks up only new documents. When a run has no transactions to send, it still produces the balance file, so the portal's aging stays current.
Under the hood
- The routing preference drives both what goes in the index and which contact fields are mandatory.
- Marking transactions as exported is a separate job from delivery, so a document is sent once.
- PDFs and the index go into an N/compress archiver and are zipped in one step, without saving loose files first.
- SFTP transport lives in its own library, apart from selection and rendering.
- The portal's formatting rules live in the search definitions, next to the data they format.