Automating your invoicing process ensures you get paid on time while reducing manual data entry. This guide walks you through configuring dynamic due-date calculations and setting up conditional branching logic to safely generate QuickBooks Online (QBO) invoices from your order management system.
By the end of this guide, you will have a workflow that automatically calculates when an invoice is due based on the client's payment terms and routes the automation based on whether the customer's QuickBooks profile is ready.
flowchart TD
A["Webhook Trigger"] --> B["Fetch Order Data (monday.com)"]
B --> C["Calculate Due Dates (Code Step)"]
C --> D{"Branching Logic"}
D -->|"QB ID Exists + Order Ready"| E["Create QBO Invoice"]
D -->|"QB ID Exists + Invoice Now"| E
D -->|"No QB ID Found"| F["Stop Process"]Configuring the automation
Follow these steps to set up your date calculations and routing paths.
- 1
Fetch order and client data
Your workflow should start by capturing the triggering event (like a status change to "Order Ready") and fetching the associated order details. Ensure you retrieve the Client Type and the QuickBooks ID from your database or project board (e.g., monday.com).
- 2
Calculate dynamic due dates
Different clients have different payment terms. You can use a code step to dynamically calculate the
Due DateandDate Deliveredbased on the current date and the client's profile.Add a Python code step to your workflow and paste the following script. This script handles timezone adjustments and applies specific logic for clients who pay by check.
from datetime import datetime, timedelta # --- 1. SETUP --- # Adjust UTC to your local time (e.g., -4 hours for EDT) now_utc = datetime.now() local_now = now_utc + timedelta(hours=-4) client_type = input_data.get('client_type', '').strip() # --- 2. CALCULATE: DUE DATE --- # Logic: Standard = Tomorrow | Pay By Check = 1st of Next Month if client_type == "Pay By Check": if local_now.month == 12: # December rollover to January due_date_obj = datetime(local_now.year + 1, 1, 1) else: # Move to the first day of the next month due_date_obj = datetime(local_now.year, local_now.month + 1, 1) else: # Standard logic: Tomorrow based on local time due_date_obj = local_now + timedelta(days=1) # --- 3. CALCULATE: DATE DELIVERED --- # The local date at the moment of the run date_delivered = local_now.strftime("%Y-%m-%d") # --- 4. OUTPUT --- return { "Due Date": due_date_obj.strftime("%Y-%m-%d"), "date_delivered": date_delivered }Timezone Adjustments: Zapier and similar automation platforms run on UTC by default. Always apply a
timedeltaoffset to match your local business timezone so invoices don't accidentally generate with tomorrow's date if triggered late in the day. - 3
Set up branching logic
To prevent errors in QuickBooks, invoices should only be created if the customer already has a valid QuickBooks ID synced to their profile. Use branching (paths) to evaluate the data before proceeding.
Branching path criteria
Configure your workflow paths using the following criteria to ensure invoices are only generated under the right conditions.
| Path Name | Condition 1 (QuickBooks ID) | Condition 2 (Deal Stage) | Action |
|---|---|---|---|
| Regular Run | mirror_mkm9q8hx (QB ID) Exists | Exactly matches Order Ready | Continue to create invoice |
| Manual Override | mirror_mkm9q8hx (QB ID) Exists | Exactly matches Invoice Now | Continue to create invoice |
| Missing QB ID | text_mky3zz9q (QB ID) Does Not Exist | Any | Stop workflow |
If a record goes down the Missing QB ID path, the workflow will halt. You must ensure your separate customer onboarding workflow has successfully created the customer in QuickBooks and synced the ID back to your database before attempting to invoice.
Keeping customer data synced
If an invoice fails because of outdated contact information, you may need to update the customer record.
When a customer's primary email address is updated in your CRM or project board, ensure you have a secondary automation that:
Triggers an
update_customeraction in QuickBooks Online using their synced QB ID.Updates the
emailAddresscolumn on your Contacts board.Changes the updater status column to Done so your team knows the sync was successful.