Skip to content

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:

  1. 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.
  2. 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.
  3. 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.
  4. 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 in df_discover_fresh ship a small set of OWL/JS dashboard components under static/src/js, static/src/xml, and static/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.xml for SKU price tracking, weekly inventory updates, and similar housekeeping.
  • Inter-module dependencies: df_logistics depends on df_discover_fresh; storage_locations depends on purchase_order_inherit; the pct_approval_* modules depend on the Odoo Enterprise approvals app. 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), and report/ (QWeb report templates). Asset bundles for OWL components are declared in the assets key of the manifest, mapped onto web.assets_backend.
  • Server actions and crons: Scheduled work is registered in df_discover_fresh/data/cron_jobs.xml, and webhook registration lives in data/webhook_config.xml. Mail templates for transactional notifications are in data/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, with odoo-16.0/ retained for reference of the previous major version.
  • WhatsApp ordering bot: df_discover_fresh exposes webhook endpoints (data/webhook_config.xml) that consume orders pushed in from the WhatsApp bot. Bot-side documentation lives in Odoo/docs/WHATSAPP_BOT_API.md and Odoo/docs/WHATSAPP_BOT_SPRINT_BACKLOG.md.
  • Payment provider: df_discover_fresh/models/paystack_transaction.py records Paystack payment results; the matching template is in views/payment_result_template.xml.
  • BigQuery: bigquery_techfinna (third-party) ships scheduled jobs that export Odoo data into Google BigQuery. It declares external Python dependencies on google-cloud-bigquery, pandas, and pyarrow.
  • Hosted production instance: https://packetclouds-vendease.odoo.com, database packetclouds-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_first and pct_approval_rfq_po depend on the Odoo approvals app, which in stock Odoo is delivered as part of Enterprise. Local databases need an Enterprise build (or a community equivalent of the approvals module) 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 under Odoo/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 extends sale.order, stock.picking, purchase.order, res.partner, and product.template/product.product. Marked application=True.
  • df_logistics — adds the rider, vehicle, vehicle log, and trip models, plus a profitability/trip-summary report. Extends df.delivery.group and the dispatch wizard so that a delivery group can be turned into a logistics trip with drops. Depends on df_discover_fresh, account, and analytic.

Procurement / approval / accounting extensions

  • pct_advance_expense — employee expense advance request workflow with multi-currency support.
  • pct_foragers_report — a sibling module modelled on pct_advance_expense for forager (field buyer) disbursements.
  • pct_approval_manager_first — reorders the standard approvals workflow 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 of account.
  • pct_partner_constraint — relaxes the duplicate-partner constraint on res.partner.
  • pct_supplier_price — adds holding cost and logistics cost fields to product.product and a computed unit cost on purchase order lines.
  • account_move_remove_constraint — adds vendease_reference fields to account.move and no-ops the _check_duplicate_supplier_reference constraint 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) — extends hr.expense so an expense can be paid directly to a vendor rather than reimbursed to the employee.
  • partner_category — adds a partner_category field to res.partner for vendor segmentation.

Inventory and reporting

  • storage_locations — qty-limit rules per stock location; depends on purchase_order_inherit.
  • comprehensive_stock_report — XLSX and PDF variants of inbound, outbound, transfer, and per-location stock reports; depends on report_xlsx and delivery. Marked auto_install=True.
  • location_availability_report — per-location availability XLSX/PDF report. Also auto_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) — small stock.move extension 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.py adds to_approve, approved, and rejected states to account.move.state plus 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, and WHATSAPP_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 on sale.order, stock.picking, purchase.order, res.partner, and product.product. df_logistics then 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_vehicle is the most invasive of the two because it adds extra states to account.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:

  1. Clone the upstream Odoo 17 source (https://github.com/odoo/odoo, branch 17.0) into a sibling odoo-17.0/ directory. Follow Odoo's requirements.txt and odoo-bin instructions for the supported Python versions.
  2. Add this repository to the Odoo --addons-path, e.g.: ./odoo-bin --addons-path=odoo-17.0/addons,Odoo -d local_db
  3. Install or upgrade the required modules from the Apps menu (or via -i df_discover_fresh,df_logistics,... on the first run).
  4. For the production tenant, modules are uploaded via Odoo Online's module management page on the packetclouds-vendease-discoverfresh-29412875 database. 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 to asset_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_id was empty on most groups, so the delivery fee fell back to ir.config_parameter defaults instead of zone rates; trip drops snapshot a stale fee. Fix landed in df_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_orders remains documented but is harmless while solo and express zone rates are equal.

  • Repo hygiene — do NOT commit:

  • Local working-notes files (any non-tracked *.md containing 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, and diag_*.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_report and location_availability_report declare auto_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, the oe_chatter wrapper on the delivery zone form, and SKU bulk-upload header handling. The conventional main branch should be used as the PR base.

  • docs/ subdirectory inside Odoo/ exists and holds the user guide, WhatsApp bot API reference, and sprint backlog. The workspace-level docs/ 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__.py carefully orders its data keys — 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 through web.assets_backend. After editing a JS or XML template file, restart the server with --dev=xml,assets to avoid stale bundles.

  • Coexistence with paid third-party modules: bigquery_techfinna and pw_purchase_payment_status are commercial modules. Keep their licence keys / purchase records out of source control and refresh them when bringing up a new tenant.

  • Branch strategy: discoverfresh is the active feature branch. main is 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.