Odoo (Vendease Custom Addons)¶
Overview¶
This workspace holds the Vendease-maintained Odoo addons that customise the
Discover Fresh production instance and a number of cross-cutting accounting,
inventory, and procurement extensions. It is not a copy of Odoo itself; the
Odoo runtime lives in the sibling odoo-17.0 checkout (and, historically,
odoo-16.0). The addons in this repository are layered on top of that runtime
through Odoo's --addons-path mechanism.
The active branch at the time of writing is discoverfresh, which is being
used to develop and ship operational fixes for the Discover Fresh WhatsApp
grocery delivery service. The production tenant served by this code is the
hosted Odoo Online instance https://packetclouds-vendease.odoo.com, database
packetclouds-vendease-discoverfresh-29412875.
The repository contains three broad classes of addon:
- Discover Fresh business modules (
df_*) — the back-office for the WhatsApp ordering, delivery grouping, virtual warehouse, dispatch, and logistics flows that make up the Discover Fresh product. - Procurement / approval / accounting extensions (
pct_*,account_move_remove_constraint,purchase_order_inherit,pw_purchase_payment_status,hr_expense_pay_to_vendor) — small, targeted modifications to the standard Odoo accounting and purchase apps that have accumulated over multiple Vendease tenants. - Inventory and reporting modules (
storage_locations,comprehensive_stock_report,location_availability_report,deltatech_stock_negative,report_xlsx,partner_category,product_expiry_restrict) — utilities for warehouse rules, XLSX/PDF reports, and stock guardrails. - Fleet and external connectors (
dispatch_vehicle,bigquery_techfinna) — a fleet dispatch workflow that adds approval states to vendor bills, and a third-party Google BigQuery connector used for analytics export.
In addition to module source, the repository contains a small collection of
ad-hoc XML-RPC scripts at the top level (e.g. fix_delivery_fee_propagation.py,
create_carbon_bank_journal.py, diag_so25.py, revert_delivery_fee_overcorrection.py)
that have been used to diagnose or remediate production data. These scripts
are kept locally for reproducibility but are not committed; see the
"Operational Notes & Risks" section below for the policy.
A docs/ subdirectory inside Odoo/ holds longer-form Markdown notes
including a USER_GUIDE.md and the WhatsApp bot API and sprint backlog
documents (also exported to .docx).
Architecture & Technology¶
The addons follow standard Odoo conventions.
- Runtime: Odoo 17.0. The
df_*manifests pin"version": "17.0.1.0.0". Several older or third-party modules (dispatch_vehicle,comprehensive_stock_report,storage_locations,report_xlsx,deltatech_stock_negative,purchase_order_inherit,hr_expense_pay_to_vendor,partner_category,product_expiry_restrict) also declare 17.0 manifests. - Language and packaging: Python 3 modules with the usual
__manifest__.py/models//views//wizard//report//security//data/layout. Front-end assets indf_discover_freshship a small set of OWL/JS dashboard components understatic/src/js,static/src/xml, andstatic/src/css. - Persistence: PostgreSQL via Odoo ORM. No direct SQL is required to operate the addons; the diagnostic scripts in the repository root use XML-RPC (Odoo's external API) rather than direct DB access.
- Asynchronous work: Standard Odoo cron jobs declared in
df_discover_fresh/data/cron_jobs.xmlfor SKU price tracking, weekly inventory updates, and similar housekeeping. - Inter-module dependencies:
df_logisticsdepends ondf_discover_fresh;storage_locationsdepends onpurchase_order_inherit; thepct_approval_*modules depend on the Odoo Enterpriseapprovalsapp. Most other modules depend only on standard Odoo apps (base,account,purchase,stock,hr,hr_expense,mail,sale_management,web). - Licensing: A mix of
OPL-1,LGPL-3,AGPL-3, all declared per module in their manifests. The bigquery connector is a paid third-party module (TechFinna) and includes its own pricing metadata. - Data files and security: Each module follows the standard
Odoo split between
security/(groups, record rules, access CSVs),data/(default data, mail templates, cron jobs, webhook configuration, seed records),views/(XML view definitions and menus),wizard/(transient models and their forms), andreport/(QWeb report templates). Asset bundles for OWL components are declared in theassetskey of the manifest, mapped ontoweb.assets_backend. - Server actions and crons: Scheduled work is registered in
df_discover_fresh/data/cron_jobs.xml, and webhook registration lives indata/webhook_config.xml. Mail templates for transactional notifications are indata/mail_templates.xml.
How It Fits With Other Systems¶
The Odoo addons sit at the centre of the Vendease back-office stack but talk to several adjacent services:
- Odoo runtime: The addons are loaded by an Odoo 17 server. The
upstream source is checked out under the sibling
odoo-17.0/directory in the workspace, withodoo-16.0/retained for reference of the previous major version. - WhatsApp ordering bot:
df_discover_freshexposes webhook endpoints (data/webhook_config.xml) that consume orders pushed in from the WhatsApp bot. Bot-side documentation lives inOdoo/docs/WHATSAPP_BOT_API.mdandOdoo/docs/WHATSAPP_BOT_SPRINT_BACKLOG.md. - Payment provider:
df_discover_fresh/models/paystack_transaction.pyrecords Paystack payment results; the matching template is inviews/payment_result_template.xml. - BigQuery:
bigquery_techfinna(third-party) ships scheduled jobs that export Odoo data into Google BigQuery. It declares external Python dependencies ongoogle-cloud-bigquery,pandas, andpyarrow. - Hosted production instance:
https://packetclouds-vendease.odoo.com, databasepacketclouds-vendease-discoverfresh-29412875. This is an Odoo Online (SaaS) tenant. Module source must be deployed through the Odoo Online module-upload workflow rather than a direct file copy. - Approvals app dependency:
pct_approval_manager_firstandpct_approval_rfq_podepend on the Odooapprovalsapp, which in stock Odoo is delivered as part of Enterprise. Local databases need an Enterprise build (or a community equivalent of theapprovalsmodule) for those two modules to install. - Sibling Vendease projects: The wider Vendease platform
contains a number of non-Odoo services (
discover_fresh,core-services,e-procurement-v2,procurement-integration-backend,Inventory-backend,vendease-payments-backend,vendease-integration-server,wms). The Odoo addons do not depend on those services directly; integration is via the WhatsApp bot webhook, Paystack callbacks, and the BigQuery export, all of which are documented in module-level XML or underOdoo/docs/.
Repository Layout¶
The repository root contains one directory per Odoo module plus a small number of utility scripts and notes.
Discover Fresh business modules (df_*)¶
df_discover_fresh— the main application. Manifest summary: "WhatsApp grocery delivery — back-office operations for Discover Fresh." It owns the virtual warehouse, delivery group management, delivery zones and windows, supplier registration, SKU price tracking and weekly inventory updates, the exception queue, the dispatch wizard, dashboard widgets, and the bulk SKU upload flow. Inherits and extendssale.order,stock.picking,purchase.order,res.partner, andproduct.template/product.product. Markedapplication=True.df_logistics— adds the rider, vehicle, vehicle log, and trip models, plus a profitability/trip-summary report. Extendsdf.delivery.groupand the dispatch wizard so that a delivery group can be turned into a logistics trip with drops. Depends ondf_discover_fresh,account, andanalytic.
Procurement / approval / accounting extensions¶
pct_advance_expense— employee expense advance request workflow with multi-currency support.pct_foragers_report— a sibling module modelled onpct_advance_expensefor forager (field buyer) disbursements.pct_approval_manager_first— reorders the standardapprovalsworkflow so that the manager approves before subsequent approvers.pct_approval_rfq_po— extends approvals to the purchase RFQ / PO flow.pct_budget_view— adds a custom budget viewer menu and views on top ofaccount.pct_partner_constraint— relaxes the duplicate-partner constraint onres.partner.pct_supplier_price— adds holding cost and logistics cost fields toproduct.productand a computed unit cost on purchase order lines.account_move_remove_constraint— addsvendease_referencefields toaccount.moveand no-ops the_check_duplicate_supplier_referenceconstraint that otherwise blocks repeat vendor bill numbers. This module does NOT touch_check_date_maturity, which was the cause of the BNPL receivable incident in April 2026 (see the runbook).purchase_order_inherit— small UI/field tweaks to PO, product, and stock.location.pw_purchase_payment_status(Preway IT Solutions, paid app) — surfaces payment status and due amount on the PO list/form.hr_expense_pay_to_vendor(Ideassion) — extendshr.expenseso an expense can be paid directly to a vendor rather than reimbursed to the employee.partner_category— adds apartner_categoryfield tores.partnerfor vendor segmentation.
Inventory and reporting¶
storage_locations— qty-limit rules per stock location; depends onpurchase_order_inherit.comprehensive_stock_report— XLSX and PDF variants of inbound, outbound, transfer, and per-location stock reports; depends onreport_xlsxanddelivery. Markedauto_install=True.location_availability_report— per-location availability XLSX/PDF report. Alsoauto_install=True.deltatech_stock_negative(Terrabit / Dorin Hongu, OCA-style) — blocks operations that would result in negative stock at configured locations.product_expiry_restrict(Otibro) — smallstock.moveextension related to expiry handling.report_xlsx(ACSONE / OCA) — base helper to register XLSX report renderers; depended on by the Ideassion report modules.
Fleet and external connectors¶
dispatch_vehicle(Ideassion) — a fleet vehicle dispatch workflow.models/account_move.pyaddsto_approve,approved, andrejectedstates toaccount.move.stateplus an approval workflow used for driver bills.bigquery_techfinna(TechFinna) — third-party connector that exports Odoo data to Google BigQuery on a cron, with a wizard for manual exports.
Top-level files¶
README.md— short repository readme.DETAILED_WALKTHROUGH.md— longer-form notes.docs/—USER_GUIDE.md,WHATSAPP_BOT_API.md/.docx, andWHATSAPP_BOT_SPRINT_BACKLOG.md/.docx.handover-docs/— engineering handover site source (this site).create_carbon_bank_journal.py,create_logistic_acccount.py(sic),fix_delivery_fee_propagation.py,revert_delivery_fee_overcorrection.py,diag_so25.py— XML-RPC remediation and diagnostic scripts. Several of these inline admin credentials; the do-not-commit policy for them is listed under "Operational Notes & Risks" below..vscode/— local editor config.
Cluster summary¶
The four clusters above can be thought of as concentric layers around the core Odoo accounting / sales / stock graph:
- The
df_*cluster is the only application-class layer: it owns business records that do not exist in stock Odoo (delivery groups, delivery zones, delivery windows, virtual warehouse, virtual warehouse lines, supplier registration, exception queue, weekly inventory updates, SKU price tracking, Paystack transactions, process breaks, dashboard) and a substantial set of inheritances onsale.order,stock.picking,purchase.order,res.partner, andproduct.product.df_logisticsthen layers trips, riders, vehicles, and vehicle logs on top of that base. - The
pct_*cluster targets standard Odoo apps (approvals,account,purchase,hr_expense) with small, focused modifications. None of them introduce new top-level applications; most simply tweak workflows, relax constraints, or add fields to existing models. - The inventory and reporting cluster supplies general-purpose helpers (XLSX rendering, location reports, negative-stock guard, partner category) that are not tied to any one Vendease product and are reused across tenants.
- The fleet and connector cluster (
dispatch_vehicle,bigquery_techfinna) is more self-contained —dispatch_vehicleis the most invasive of the two because it adds extra states toaccount.move.state, which downstream modules need to be aware of when filtering or transitioning vendor bills.
Running, Building & Deploying¶
Local development relies on a standalone Odoo 17 runtime; this
repository does not ship odoo-bin. The standard pattern is:
- Clone the upstream Odoo 17 source (
https://github.com/odoo/odoo, branch17.0) into a siblingodoo-17.0/directory. Follow Odoo'srequirements.txtandodoo-bininstructions for the supported Python versions. - Add this repository to the Odoo
--addons-path, e.g.:./odoo-bin --addons-path=odoo-17.0/addons,Odoo -d local_db - Install or upgrade the required modules from the Apps menu (or
via
-i df_discover_fresh,df_logistics,...on the first run). - For the production tenant, modules are uploaded via Odoo Online's
module management page on the
packetclouds-vendease-discoverfresh-29412875database. Direct file deployment is not available on Odoo Online.
When developing JS/CSS dashboard widgets in df_discover_fresh, run
the Odoo server with --dev=xml,assets to pick up template and asset
changes without restarting. Tests live alongside their modules under
the standard tests/ convention; none are required for the current
fixes.
The XML-RPC remediation scripts in the repository root expect
xmlrpc.client and the Odoo URL/DB/credentials of the target tenant.
Each script is meant to be safe to re-run (idempotent) and is invoked
manually with python3 fix_<name>.py. Do not commit any script that
contains live credentials.
Operational Notes & Risks¶
- Recent production incidents. Two incidents are written up in full in the Odoo runbook (see the runbook page). In summary:
- BNPL receivable constraint (2026-04-21) — account 410000 was
being used as the partner receivable but was typed
income. The fix was to repoint a sale journal default and flip the account type toasset_receivable. Revenue itself was always captured on 400000. The fix script is kept locally and is idempotent; the underlying invoice creation flow is no longer blocked. -
Trip drop "Delivery Fee Charged" stale at 4,000 (2026-04-23) —
df.delivery.group.zone_idwas empty on most groups, so the delivery fee fell back toir.config_parameterdefaults instead of zone rates; trip drops snapshot a stale fee. Fix landed indf_discover_fresh/models/delivery_group.py,df_logistics/models/logistics_trip_drop.py, and the dispatch wizard, plus a one-off prod data backfill script. A residual follow-up around_sync_delivery_fee_to_ordersremains documented but is harmless while solo and express zone rates are equal. -
Repo hygiene — do NOT commit:
- Local working-notes files (any non-tracked
*.mdcontaining incident detail or credentials). They stay local. - Any script that inlines Odoo admin username/password. The
enumerated set includes
create_logistic_acccount.py,fix_delivery_fee_propagation.py,fix_bnpl_account_type.py,debug_invoice_constraint.py, anddiag_*.py. New XML-RPC helpers should follow the same rule. -
Only stage module source under
df_*/,pct_*/, etc. (models/,views/,wizard/,data/,security/,static/,report/). -
Mixed authorship: The repository bundles modules from several authors (Vendease, Packetclouds Technology, Ideassion, ACSONE/OCA, Terrabit, TechFinna, Preway, Otibro). Some are paid third-party modules and some are community / OCA. Upgrading to a future Odoo major will need a per-module compatibility check rather than a bulk port.
-
Auto-install flags:
comprehensive_stock_reportandlocation_availability_reportdeclareauto_install=True, which means they will install automatically on any Odoo database where their dependencies are present. This is intentional today but is worth being aware of when bringing up a fresh tenant. -
Active branch:
discoverfresh. The recent commit history is focused on delivery-zone audit logs, delivery-fee propagation, theoe_chatterwrapper on the delivery zone form, and SKU bulk-upload header handling. The conventionalmainbranch should be used as the PR base. -
docs/subdirectory insideOdoo/exists and holds the user guide, WhatsApp bot API reference, and sprint backlog. The workspace-leveldocs/directory (one level up) is where this overview lives, and is the recommended home for further long-form Markdown documentation about the addons. -
Module-load ordering:
df_discover_fresh/__manifest__.pycarefully orders itsdatakeys — security first, then default data and cron jobs, then views (with actions ahead of menus that reference them), then wizards and reports. When adding new XML files, preserve that ordering; Odoo will fail to load a menu whose action has not yet been registered. -
Front-end assets: The dashboard widgets in
df_discover_fresh/static/src/register throughweb.assets_backend. After editing a JS or XML template file, restart the server with--dev=xml,assetsto avoid stale bundles. -
Coexistence with paid third-party modules:
bigquery_techfinnaandpw_purchase_payment_statusare commercial modules. Keep their licence keys / purchase records out of source control and refresh them when bringing up a new tenant. -
Branch strategy:
discoverfreshis the active feature branch.mainis the conventional PR base. The recent commit history (delivery zone audit logs, delivery fee propagation, oe_chatter wrapper, SKU bulk-upload header handling) gives a feel for the scope of changes that flow through this repository in a typical iteration.