Systems in practice
Inventory, Sales, and Ad Spend in One View
How we connected Odoo inventory, Shopify sales and refunds, and advertising spend in Google Sheets for a footwear retailer operating two online stores.
Footwear retail / Inventory and marketing operations
- Make
- Odoo
- Shopify
- Google Sheets
- Meta Ads
- Google Ads
Business challenge
A footwear retailer operated two Shopify stores while managing inventory in Odoo. Stock value, available pairs, store sales, refunds, and advertising spend lived in different systems.
The team needed a shared reporting view that connected stock availability with commercial activity without treating the two stores as a single undifferentiated business. Reporting also needed to retain refunds rather than equate order totals with net sales.
Solution overview
We built two independent Make workflows with Google Sheets as the reporting workspace. One groups stocked Odoo products by brand and records stock value and available quantities. The other gathers Shopify order totals, refund amounts, and advertising spend for store-level reporting.
The workflows share a reporting destination, not a direct dependency. Inventory can be reviewed by brand while sales and marketing activity are organized by store and reporting date.
How the system works
Inventory by brand / Store sales and advertising
Make / Workflow orchestration
1Inventory reporting
Read stocked products
Retrieve positive-stock products and their brand, quantity, and stock-value fields.
Odoo
Aggregate each brand
Apply configured exclusions, sum stock value, and retain the inserted report row for the quantity update.
Make
Write value and quantity together
Append a dated brand row and update that same row with available stock quantities.
Google Sheets
2Store performance reporting
Read orders and refunds
Collect store order totals and retrieve refund details for the configured reporting window.
Shopify / GraphQL API
Collect and group spend
Read Meta accounts separately. Google campaign names containing outlet enter the Outlet group; all others enter the Luxury fallback group.
Meta Ads / Google Ads
Update report and chart inputs
Write separate sales/refund fields and store chart rows alongside dated advertising spend.
Google Sheets
Workflow 1 — Inventory by brandThe Odoo API retrieves products with positive available stock, including brand, quantity, and stock-value fields. Make groups the products by brand, applies configured brand exclusions, and sums their stock values.
The workflow appends a dated brand row to Google Sheets, retains its returned row number, and then sums available quantities for that same group. It updates the matching row with the quantity total, keeping value and stock counts together.
Workflow 2 — Store sales and refundsThe reporting workflow defines a previous-day window and queries paid and partially refunded Shopify orders separately for each store. It aggregates their order totals, then uses Shopify GraphQL requests to retrieve refund details for refunded and partially refunded orders in that window.
Refund amounts are aggregated separately from order totals. The shared worksheet receives dated sales and refund columns, while store-specific chart sheets receive sales totals. This keeps the inputs available for refund-aware reporting without conflating them with settled cash receipts.
Advertising spendSeparate Meta ad-account requests retrieve the previous day's spend for the two stores. Google Ads campaign names are lowercased: names containing "outlet" enter the Outlet reporting group, while all remaining campaigns enter the Luxury fallback group. The workflow writes grouped spend into the shared report and store chart rows. These are configured reporting rules, not independently validated attribution of revenue to advertising.
Engineering decisions
- Separate inventory from performance reportingTwo workflows isolate stock aggregation from sales and advertising retrieval. The design does not depend on an Odoo-to-ad-platform integration.
- Retain row identity during multi-pass writesInventory quantities are written back using the row number returned by the stock-value insertion. Reporting chart updates likewise reference the newly added chart rows.
- Keep commercial measures distinctOrder totals and refund amounts occupy separate report fields. This preserves their meaning rather than labeling an unverified calculation as accounting revenue.
- Make store grouping explicitMeta uses separate ad accounts. Google Ads assigns campaigns whose lowercased names contain "outlet" to the Outlet group and sends all remaining campaigns to the Luxury fallback group. The naming convention controls reporting buckets, not verified customer or revenue attribution.
- Apply bounded recovery where configuredMeta and Google Ads retrieval modules have retry handlers. Those handlers support recovery from source failures; they do not establish transactional writes or duplicate-free reruns.
Results & business impact
The delivered workflows give the team a shared Google Sheets workspace for inventory, sales, refunds, and advertising spend. Brand-level stock reporting and separate outputs for the two Shopify stores preserve the operational context behind the figures.
Automated collection and worksheet updates reduce the need to gather information manually from Odoo, Shopify, Meta Ads, and Google Ads. Order totals and refund amounts remain separate measures; the report is not presented as independently reconciled accounting revenue.
Brand-level inventory
Stock value and available quantities are recorded together for each included brand.
Separate store reporting
Each Shopify store retains its own sales totals, refund amounts, and chart inputs.
Shared commercial visibility
Inventory and store results can be reviewed alongside advertising spend in the same reporting workspace.
Less manual information gathering
Connected workflows collect and write source data rather than requiring separate exports from each system.
Technology stack
- Make
- Coordinates API calls, grouping, aggregation, routing, sheet writes, and configured retries.
- Odoo
- Supplies stocked product records, brand assignments, stock values, and available quantities.
- Shopify and its GraphQL API
- Supply store orders and refund details for the selected reporting window.
- Meta Ads
- Supplies ad-account spend through reporting requests.
- Google Ads
- Supplies campaign costs for store-group aggregation.
- Google Sheets
- Stores the shared report and the inputs to store-specific chart tabs.