Skip to main content

Phase 0 — Pre-flight

Read-only investigation. Establishes baseline and identifies risks before any change is made.

0.1 Backup

# DB backup
pg_dump -U odoo17 -h localhost rts_baywaters \
-F c -f ~/backups/rts_baywaters_$(date +%Y%m%d_%H%M).dump

# Filestore backup (path may vary)
tar czf ~/backups/rts_baywaters_filestore_$(date +%Y%m%d_%H%M).tar.gz \
~/.local/share/Odoo/filestore/rts_baywaters

Keep both for at least 30 days.

0.2 Current journal inventory

Companies

12 companies — 1 parent + 11 branches:

SELECT id, name, parent_id FROM res_company ORDER BY id;
idnameparent_id
1Baywaters Corp.(parent)
2Shawarma Shacks (Petron)1
4Jamaican Patties (Petron)1
5Miguelitos Ice Cream (Petron)1
6Auntie Annes (Petron)1
7Bibingkinitan (Caltex)1
8Jamaican Patties (Caltex)1
9Henlin (Caltex)1
10Potato Corner (Caltex)1
11Sam's Everything on Stick (Caltex)1
12Buko Juan (Petron)1
13Sams Everything on Sticks (Petron)1

Journals

SELECT j.code, j.name->>'en_US' AS name, j.type, j.company_id, c.name AS company
FROM account_journal j
JOIN res_company c ON c.id = j.company_id
ORDER BY j.company_id, j.type, j.code;

Finding: Only the parent has the full journal set. Branches have only STJ (Inventory Valuation). All sale/purchase/bank/cash/misc transactions across all 12 companies post to the parent's 9 journals.

CodeNameTypeCompany
BNK1AUB -PETRONbankBaywaters Corp.
BNK2AUB - CALTEXbankBaywaters Corp.
CSH1CashcashBaywaters Corp.
CABACash Basis TaxesgeneralBaywaters Corp.
EXCHExchange DifferencegeneralBaywaters Corp.
MISCMiscellaneous OperationsgeneralBaywaters Corp.
STJInventory ValuationgeneralBaywaters Corp. + per-branch
BILLVendor BillspurchaseBaywaters Corp.
INVCustomer InvoicessaleBaywaters Corp.

Cross-company posting concentration

SELECT j.code, COUNT(*) AS moves,
MIN(m.date) AS min_date, MAX(m.date) AS max_date,
COUNT(DISTINCT m.company_id) AS companies_using
FROM account_move m
JOIN account_journal j ON j.id = m.journal_id
WHERE m.state = 'posted'
GROUP BY j.code
ORDER BY moves DESC;
JournalPosted MovesCompanies Posting
BNK16589
BILL40712
MISC1288
BNK284

Implication: every shared journal is a sequence-collision hotspot.

0.3 Naming pattern split on MISC journal

SELECT SUBSTRING(name FROM '^[A-Z]+') AS prefix, COUNT(*)
FROM account_move WHERE journal_id = 3 GROUP BY 1;
PrefixCount
MISC51
JV100
(blank/draft)1076

Two patterns coexist on the same journal. MISC/YYYY/MM/NNNN is the standard Odoo pattern; JV-YYYY-MM-NN is from a custom module.

JV-* origin — rts-journal-sequence module

Located at /Users/jsalinga/odoo/odoo17/custom/ygc17/common/rts-journal-sequence/models/account_move.py.

Lines 32–35 of _compute_name_by_sequence():

seq = move.journal_id.sequence_id
seq.prefix = move.journal_id.code + "-" + str(move.date.strftime('%Y')) + "-" + \
str(move.date.strftime('%m')) + "-"
name = self._next_by_month(sequence=seq, sequence_date=move.date)

Status: module is currently uninstalled in rts_baywaters (verified via ir_module_module). The 100 JV-* records are residue from a prior period when it was active.

Implication: no code action needed to stop new JV-* names — the module is already off. Phase 3 reduces to ensuring nobody re-installs it.

:::warning Verify per-database Check ir_module_module on every YGC database before assuming the module is off site-wide:

SELECT name, state FROM ir_module_module
WHERE name IN ('rts_journal_sequence','rts-journal-sequence','od_journal_sequence');

:::

0.4 Stale drafts — 53 entries

Drafts whose assigned name no longer matches their date will throw the same validation error when posted. Inventory:

SELECT m.id, m.name, m.date, j.code AS journal, c.name AS branch, m.amount_total
FROM account_move m
JOIN account_journal j ON j.id = m.journal_id
JOIN res_company c ON c.id = m.company_id
WHERE m.state = 'draft' AND m.name <> '/' AND m.name IS NOT NULL
ORDER BY m.date;

Findings:

  • Oldest stale draft: MISC/2023/12/0001 (date 2023-12-31) — over 2 years old
  • Multiple monthly placeholder drafts (MISC/2025/0X/0001) likely created as month-opening templates
  • The specific draft from the user's screenshot: MISC/2026/03/0033 at Potato Corner (Caltex), dated 2026-04-18 (i.e., March-numbered, April-dated)

Cleanup procedure: see Phase 1 — Clean stale drafts.

0.5 Sequence configuration audit

SELECT s.id, s.name, s.padding, s.use_date_range, s.implementation, s.company_id
FROM ir_sequence s
WHERE s.name LIKE '%Check Number%'
ORDER BY s.company_id;

Currently the Check Number sequences (Odoo's secondary sequence used for hashing) are set to no_gap. The primary move-name sequencing uses Odoo 17's posted_before/name-based mechanism on account.move directly, not ir.sequence.

No urgent change needed. Phase 2 will validate per-journal sequence settings once branch journals exist.

0.6 Dependencies referencing current journals

Inventory before any rename or replacement:

-- Reconciliation models
SELECT id, name, journal_id FROM account_reconcile_model WHERE journal_id IS NOT NULL;

-- Bank statement import configs (if present)
SELECT id, name, journal_id FROM account_journal WHERE bank_statements_source IS NOT NULL;

-- Recurring invoice/bill templates (subscription-style addons)
-- (search for tables specific to installed modules)

Custom reports filtering by journal_id should be checked separately — grep the red17_base_accounting and per-company addon repos for hardcoded journal IDs or codes.

0.7 Communication

Notify accounting team:

  • Cutover date selected
  • Posting freeze window (typically 2–4 hours, scheduled off-hours)
  • Backup is in place; rollback path is pg_restore of the dump from §0.1

Exit criteria for Phase 0

  • Backups taken
  • Journal inventory documented
  • Naming pattern split investigated; rts-journal-sequence confirmed uninstalled
  • Stale drafts inventoried (53 entries)
  • Branch code map proposed
  • Dependency inventory (reconcile models, custom reports) — to be completed before Phase 4
  • Cutover date selected
  • Accounting team notified