Compare commits
4 Commits
457d9b7dbf
...
449f29fc7f
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
449f29fc7f | ||
|
|
3c2fb22346 | ||
|
|
3a41370189 | ||
|
|
d6513ff7ab |
@@ -3,7 +3,7 @@
|
||||
# License OPL-1 (Odoo Proprietary License v1.0)
|
||||
{
|
||||
'name': 'Fusion Plating — Native Jobs',
|
||||
'version': '19.0.8.22.8',
|
||||
'version': '19.0.8.22.9',
|
||||
'category': 'Manufacturing/Plating',
|
||||
'summary': 'Native plating job model — replaces mrp.production / mrp.workorder bridge.',
|
||||
'author': 'Nexa Systems Inc.',
|
||||
|
||||
@@ -45,8 +45,8 @@
|
||||
<td><span t-esc="step['work_centre']"/></td>
|
||||
<td class="text-end"><span t-esc="step['duration_expected']"/></td>
|
||||
<td class="text-end"><span t-esc="step['duration_actual']"/></td>
|
||||
<td class="text-end"><span t-field="step['rate']" t-options="{'widget': 'monetary', 'display_currency': row['job'].currency_id}"/></td>
|
||||
<td class="text-end"><span t-field="step['cost']" t-options="{'widget': 'monetary', 'display_currency': row['job'].currency_id}"/></td>
|
||||
<td class="text-end"><span t-esc="step['rate']" t-options="{'widget': 'monetary', 'display_currency': row['job'].currency_id}"/></td>
|
||||
<td class="text-end"><span t-esc="step['cost']" t-options="{'widget': 'monetary', 'display_currency': row['job'].currency_id}"/></td>
|
||||
</tr>
|
||||
</t>
|
||||
<tr style="font-weight: bold; background: #f3f3f3;">
|
||||
@@ -54,16 +54,16 @@
|
||||
<td></td>
|
||||
<td class="text-end"><span t-esc="row['total_minutes']"/></td>
|
||||
<td></td>
|
||||
<td class="text-end"><span t-field="row['total_labour']" t-options="{'widget': 'monetary', 'display_currency': row['job'].currency_id}"/></td>
|
||||
<td class="text-end"><span t-esc="row['total_labour']" t-options="{'widget': 'monetary', 'display_currency': row['job'].currency_id}"/></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
|
||||
<h3 style="margin-top: 1.5em;">Margin Summary</h3>
|
||||
<table class="table table-sm" style="max-width: 400px;">
|
||||
<tr><th>Quoted Revenue</th><td class="text-end"><span t-field="row['quoted_revenue']" t-options="{'widget': 'monetary', 'display_currency': row['job'].currency_id}"/></td></tr>
|
||||
<tr><th>Actual Cost</th><td class="text-end"><span t-field="row['actual_cost']" t-options="{'widget': 'monetary', 'display_currency': row['job'].currency_id}"/></td></tr>
|
||||
<tr style="font-weight: bold;"><th>Margin</th><td class="text-end"><span t-field="row['margin']" t-options="{'widget': 'monetary', 'display_currency': row['job'].currency_id}"/></td></tr>
|
||||
<tr><th>Quoted Revenue</th><td class="text-end"><span t-esc="row['quoted_revenue']" t-options="{'widget': 'monetary', 'display_currency': row['job'].currency_id}"/></td></tr>
|
||||
<tr><th>Actual Cost</th><td class="text-end"><span t-esc="row['actual_cost']" t-options="{'widget': 'monetary', 'display_currency': row['job'].currency_id}"/></td></tr>
|
||||
<tr style="font-weight: bold;"><th>Margin</th><td class="text-end"><span t-esc="row['margin']" t-options="{'widget': 'monetary', 'display_currency': row['job'].currency_id}"/></td></tr>
|
||||
<tr><th>Margin %</th><td class="text-end"><span t-esc="round(row['margin_pct'], 1)"/>%</td></tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
26
nexa_coa_setup/README.md
Normal file
26
nexa_coa_setup/README.md
Normal file
@@ -0,0 +1,26 @@
|
||||
# Nexa Systems — Chart of Accounts Setup
|
||||
|
||||
Custom Odoo 19 module that configures the chart of accounts, taxes,
|
||||
fiscal positions, analytic plans, and partner records for Nexa Systems Inc.
|
||||
|
||||
## Install
|
||||
|
||||
```
|
||||
docker exec odoo-nexa-app odoo -c /etc/odoo/odoo.conf -d nexamain \
|
||||
-i nexa_coa_setup --no-http --stop-after-init
|
||||
```
|
||||
|
||||
## Update
|
||||
|
||||
```
|
||||
docker exec odoo-nexa-app odoo -c /etc/odoo/odoo.conf -d nexamain \
|
||||
-u nexa_coa_setup --no-http --stop-after-init
|
||||
```
|
||||
|
||||
## Design reference
|
||||
|
||||
See `docs/superpowers/specs/2026-05-12-nexa-coa-design.md`.
|
||||
|
||||
## Safety
|
||||
|
||||
Always take a pg_dump BEFORE running `-i` or `-u`. See `docs/superpowers/plans/2026-05-12-nexa-coa-setup.md` Phase 0.
|
||||
2
nexa_coa_setup/__init__.py
Normal file
2
nexa_coa_setup/__init__.py
Normal file
@@ -0,0 +1,2 @@
|
||||
from . import models
|
||||
from .hooks import post_init_hook
|
||||
38
nexa_coa_setup/__manifest__.py
Normal file
38
nexa_coa_setup/__manifest__.py
Normal file
@@ -0,0 +1,38 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
# Copyright 2026 Nexa Systems Inc.
|
||||
# License OPL-1
|
||||
{
|
||||
"name": "Nexa Systems — Chart of Accounts Setup",
|
||||
"version": "19.0.1.0.0",
|
||||
"category": "Accounting/Localizations/Chart of Accounts",
|
||||
"summary": "Custom CoA, taxes, fiscal positions, analytic plans, and intercompany partner setup for Nexa Systems Inc.",
|
||||
"author": "Nexa Systems Inc.",
|
||||
"website": "https://nexasystems.ca",
|
||||
"license": "OPL-1",
|
||||
"depends": [
|
||||
"account",
|
||||
"account_accountant",
|
||||
"l10n_ca",
|
||||
"analytic",
|
||||
"sale_management",
|
||||
"purchase",
|
||||
"sale_subscription",
|
||||
],
|
||||
"data": [
|
||||
"security/ir.model.access.csv",
|
||||
"data/01_account_account.xml",
|
||||
"data/02_account_journal.xml",
|
||||
"data/03_account_tax.xml",
|
||||
"data/04_account_fiscal_position.xml",
|
||||
"data/05_account_analytic_plan.xml",
|
||||
"data/06_account_analytic_account.xml",
|
||||
"data/07_product_category.xml",
|
||||
"data/08_res_partner_category.xml",
|
||||
"data/09_res_partner.xml",
|
||||
"data/10_account_reconcile_model.xml",
|
||||
],
|
||||
"post_init_hook": "post_init_hook",
|
||||
"installable": True,
|
||||
"application": False,
|
||||
"auto_install": False,
|
||||
}
|
||||
808
nexa_coa_setup/data/01_account_account.xml
Normal file
808
nexa_coa_setup/data/01_account_account.xml
Normal file
@@ -0,0 +1,808 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data noupdate="0">
|
||||
|
||||
<!-- ============================================================ -->
|
||||
<!-- 1xxxxx — ASSETS -->
|
||||
<!-- ============================================================ -->
|
||||
|
||||
<!-- NOTE: 115100 is l10n_ca "Customers Account" (240 postings — AR control) — kept as l10n_ca.
|
||||
115110 is l10n_ca "Customers Account (PoS)" — kept.
|
||||
Nexa intercompany receivables live in the 119xxx range to avoid all collisions. -->
|
||||
<record id="acct_119100" model="account.account">
|
||||
<field name="code">119100</field>
|
||||
<field name="name">Due From Shareholder — Gurpreet</field>
|
||||
<field name="account_type">asset_current</field>
|
||||
<field name="reconcile" eval="True"/>
|
||||
</record>
|
||||
|
||||
<record id="acct_119900" model="account.account">
|
||||
<field name="code">119900</field>
|
||||
<field name="name">Due From Associated Corporations</field>
|
||||
<field name="account_type">asset_current</field>
|
||||
<field name="reconcile" eval="True"/>
|
||||
</record>
|
||||
|
||||
<record id="acct_118100" model="account.account">
|
||||
<field name="code">118100</field>
|
||||
<field name="name">HST/GST Input Tax Credit (ITC) Receivable</field>
|
||||
<field name="account_type">asset_current</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_118200" model="account.account">
|
||||
<field name="code">118200</field>
|
||||
<field name="name">HST/GST Instalments Paid</field>
|
||||
<field name="account_type">asset_current</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_118300" model="account.account">
|
||||
<field name="code">118300</field>
|
||||
<field name="name">QST Input Tax Refund Receivable</field>
|
||||
<field name="account_type">asset_current</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_151100" model="account.account">
|
||||
<field name="code">151100</field>
|
||||
<field name="name">Computer Hardware & Equipment (CCA Class 50)</field>
|
||||
<field name="account_type">asset_fixed</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_151200" model="account.account">
|
||||
<field name="code">151200</field>
|
||||
<field name="name">Office Furniture & Equipment (CCA Class 8)</field>
|
||||
<field name="account_type">asset_fixed</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_151300" model="account.account">
|
||||
<field name="code">151300</field>
|
||||
<field name="name">Vehicles (CCA Class 10/10.1)</field>
|
||||
<field name="account_type">asset_fixed</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_151400" model="account.account">
|
||||
<field name="code">151400</field>
|
||||
<field name="name">Leasehold Improvements (CCA Class 13)</field>
|
||||
<field name="account_type">asset_fixed</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_151500" model="account.account">
|
||||
<field name="code">151500</field>
|
||||
<field name="name">Acquired Software & Intangibles (CCA Class 14.1)</field>
|
||||
<field name="account_type">asset_fixed</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_151600" model="account.account">
|
||||
<field name="code">151600</field>
|
||||
<field name="name">Tools & Small Equipment <$500 (CCA Class 12)</field>
|
||||
<field name="account_type">asset_fixed</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_154100" model="account.account">
|
||||
<field name="code">154100</field>
|
||||
<field name="name">Acc. Depreciation — Computer Hardware</field>
|
||||
<field name="account_type">asset_fixed</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_154200" model="account.account">
|
||||
<field name="code">154200</field>
|
||||
<field name="name">Acc. Depreciation — Office Furniture</field>
|
||||
<field name="account_type">asset_fixed</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_154300" model="account.account">
|
||||
<field name="code">154300</field>
|
||||
<field name="name">Acc. Depreciation — Vehicles</field>
|
||||
<field name="account_type">asset_fixed</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_154400" model="account.account">
|
||||
<field name="code">154400</field>
|
||||
<field name="name">Acc. Depreciation — Leasehold Improvements</field>
|
||||
<field name="account_type">asset_fixed</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_154500" model="account.account">
|
||||
<field name="code">154500</field>
|
||||
<field name="name">Acc. Depreciation — Acquired Software</field>
|
||||
<field name="account_type">asset_fixed</field>
|
||||
</record>
|
||||
|
||||
<!-- ============================================================ -->
|
||||
<!-- 2xxxxx — LIABILITIES -->
|
||||
<!-- ============================================================ -->
|
||||
|
||||
<record id="acct_213100" model="account.account">
|
||||
<field name="code">213100</field>
|
||||
<field name="name">HST/GST Collected on Sales</field>
|
||||
<field name="account_type">liability_current</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_213500" model="account.account">
|
||||
<field name="code">213500</field>
|
||||
<field name="name">QST Collected on Sales</field>
|
||||
<field name="account_type">liability_current</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_214100" model="account.account">
|
||||
<field name="code">214100</field>
|
||||
<field name="name">Net HST/GST Payable</field>
|
||||
<field name="account_type">liability_current</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_215100" model="account.account">
|
||||
<field name="code">215100</field>
|
||||
<field name="name">Source Deductions Payable — Federal Tax</field>
|
||||
<field name="account_type">liability_current</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_215200" model="account.account">
|
||||
<field name="code">215200</field>
|
||||
<field name="name">Source Deductions Payable — CPP</field>
|
||||
<field name="account_type">liability_current</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_215300" model="account.account">
|
||||
<field name="code">215300</field>
|
||||
<field name="name">Source Deductions Payable — EI</field>
|
||||
<field name="account_type">liability_current</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_216100" model="account.account">
|
||||
<field name="code">216100</field>
|
||||
<field name="name">Corporate Income Tax — Federal Payable</field>
|
||||
<field name="account_type">liability_current</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_216200" model="account.account">
|
||||
<field name="code">216200</field>
|
||||
<field name="name">Corporate Income Tax — Provincial Payable</field>
|
||||
<field name="account_type">liability_current</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_216300" model="account.account">
|
||||
<field name="code">216300</field>
|
||||
<field name="name">Corporate Tax Instalments Paid</field>
|
||||
<field name="account_type">asset_current</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_221100" model="account.account">
|
||||
<field name="code">221100</field>
|
||||
<field name="name">Due To Shareholder — Gurpreet (short-term)</field>
|
||||
<field name="account_type">liability_current</field>
|
||||
<field name="reconcile" eval="True"/>
|
||||
</record>
|
||||
|
||||
<record id="acct_221200" model="account.account">
|
||||
<field name="code">221200</field>
|
||||
<field name="name">Shareholder Loan — Gurpreet (long-term)</field>
|
||||
<field name="account_type">liability_non_current</field>
|
||||
<field name="reconcile" eval="True"/>
|
||||
</record>
|
||||
|
||||
<record id="acct_222900" model="account.account">
|
||||
<field name="code">222900</field>
|
||||
<field name="name">Due To Associated Corporations</field>
|
||||
<field name="account_type">liability_current</field>
|
||||
<field name="reconcile" eval="True"/>
|
||||
</record>
|
||||
|
||||
<!-- ============================================================ -->
|
||||
<!-- 3xxxxx — EQUITY -->
|
||||
<!-- ============================================================ -->
|
||||
|
||||
<record id="acct_311100" model="account.account">
|
||||
<field name="code">311100</field>
|
||||
<field name="name">Share Capital — Common Shares</field>
|
||||
<field name="account_type">equity</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_311200" model="account.account">
|
||||
<field name="code">311200</field>
|
||||
<field name="name">Share Capital — Preferred Shares</field>
|
||||
<field name="account_type">equity</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_311300" model="account.account">
|
||||
<field name="code">311300</field>
|
||||
<field name="name">Contributed Surplus</field>
|
||||
<field name="account_type">equity</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_321100" model="account.account">
|
||||
<field name="code">321100</field>
|
||||
<field name="name">Retained Earnings — Current Year</field>
|
||||
<field name="account_type">equity</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_321200" model="account.account">
|
||||
<field name="code">321200</field>
|
||||
<field name="name">Retained Earnings — Prior Years</field>
|
||||
<field name="account_type">equity</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_321900" model="account.account">
|
||||
<field name="code">321900</field>
|
||||
<field name="name">Dividends Declared</field>
|
||||
<field name="account_type">equity</field>
|
||||
</record>
|
||||
|
||||
<!-- ============================================================ -->
|
||||
<!-- 4xxxxx — REVENUE -->
|
||||
<!-- ============================================================ -->
|
||||
|
||||
<record id="acct_411100" model="account.account">
|
||||
<field name="code">411100</field>
|
||||
<field name="name">SaaS Subscription Revenue</field>
|
||||
<field name="account_type">income</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_411200" model="account.account">
|
||||
<field name="code">411200</field>
|
||||
<field name="name">Hosting & Infrastructure Revenue</field>
|
||||
<field name="account_type">income</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_411300" model="account.account">
|
||||
<field name="code">411300</field>
|
||||
<field name="name">Support & Maintenance Contracts Revenue</field>
|
||||
<field name="account_type">income</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_411400" model="account.account">
|
||||
<field name="code">411400</field>
|
||||
<field name="name">Domain/SSL/Renewal Pass-through Revenue</field>
|
||||
<field name="account_type">income</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_411500" model="account.account">
|
||||
<field name="code">411500</field>
|
||||
<field name="name">Setup / Onboarding Fees Revenue</field>
|
||||
<field name="account_type">income</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_412100" model="account.account">
|
||||
<field name="code">412100</field>
|
||||
<field name="name">Custom Software Development Revenue</field>
|
||||
<field name="account_type">income</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_412200" model="account.account">
|
||||
<field name="code">412200</field>
|
||||
<field name="name">Custom Web Application Development Revenue</field>
|
||||
<field name="account_type">income</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_412300" model="account.account">
|
||||
<field name="code">412300</field>
|
||||
<field name="name">Custom Website Development Revenue</field>
|
||||
<field name="account_type">income</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_412400" model="account.account">
|
||||
<field name="code">412400</field>
|
||||
<field name="name">ERP Implementation & Customization Revenue</field>
|
||||
<field name="account_type">income</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_412500" model="account.account">
|
||||
<field name="code">412500</field>
|
||||
<field name="name">Mobile App Development Revenue</field>
|
||||
<field name="account_type">income</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_412600" model="account.account">
|
||||
<field name="code">412600</field>
|
||||
<field name="name">Business App / Integration Revenue</field>
|
||||
<field name="account_type">income</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_413100" model="account.account">
|
||||
<field name="code">413100</field>
|
||||
<field name="name">Consulting & Advisory Revenue</field>
|
||||
<field name="account_type">income</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_413200" model="account.account">
|
||||
<field name="code">413200</field>
|
||||
<field name="name">Training & Workshops Revenue</field>
|
||||
<field name="account_type">income</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_413300" model="account.account">
|
||||
<field name="code">413300</field>
|
||||
<field name="name">Technical Support — Per-incident / Hourly Revenue</field>
|
||||
<field name="account_type">income</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_414100" model="account.account">
|
||||
<field name="code">414100</field>
|
||||
<field name="name">Third-party Software Resale Revenue</field>
|
||||
<field name="account_type">income</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_414200" model="account.account">
|
||||
<field name="code">414200</field>
|
||||
<field name="name">Hardware Resale Revenue</field>
|
||||
<field name="account_type">income</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_419100" model="account.account">
|
||||
<field name="code">419100</field>
|
||||
<field name="name">Sales Discounts</field>
|
||||
<field name="account_type">income</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_419200" model="account.account">
|
||||
<field name="code">419200</field>
|
||||
<field name="name">Sales Returns & Refunds</field>
|
||||
<field name="account_type">income</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_419300" model="account.account">
|
||||
<field name="code">419300</field>
|
||||
<field name="name">Bad Debt Recovery</field>
|
||||
<field name="account_type">income_other</field>
|
||||
</record>
|
||||
|
||||
<!-- ============================================================ -->
|
||||
<!-- 5xxxxx — DIRECT COSTS (COGS) -->
|
||||
<!-- ============================================================ -->
|
||||
|
||||
<!-- NOTE: 511100 was "Inside Purchases" in l10n_ca (1 posting from legacy bookkeeping) — kept as l10n_ca.
|
||||
Cloud Infrastructure sits at 511105 to avoid collision. -->
|
||||
<record id="acct_511105" model="account.account">
|
||||
<field name="code">511105</field>
|
||||
<field name="name">Cloud Infrastructure (AWS, Hetzner, OVH, DigitalOcean, Linode)</field>
|
||||
<field name="account_type">expense_direct_cost</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_511110" model="account.account">
|
||||
<field name="code">511110</field>
|
||||
<field name="name">CDN & Edge Services (Cloudflare, Fastly)</field>
|
||||
<field name="account_type">expense_direct_cost</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_511120" model="account.account">
|
||||
<field name="code">511120</field>
|
||||
<field name="name">Backup & Storage Services</field>
|
||||
<field name="account_type">expense_direct_cost</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_511130" model="account.account">
|
||||
<field name="code">511130</field>
|
||||
<field name="name">Database & Backend Services (Supabase, hosted Postgres, Redis)</field>
|
||||
<field name="account_type">expense_direct_cost</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_511140" model="account.account">
|
||||
<field name="code">511140</field>
|
||||
<field name="name">Monitoring & Observability (customer-facing only)</field>
|
||||
<field name="account_type">expense_direct_cost</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_511150" model="account.account">
|
||||
<field name="code">511150</field>
|
||||
<field name="name">SSL Certificates & Domains (wholesale for resale)</field>
|
||||
<field name="account_type">expense_direct_cost</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_511160" model="account.account">
|
||||
<field name="code">511160</field>
|
||||
<field name="name">DNS & Email Hosting (wholesale for resale)</field>
|
||||
<field name="account_type">expense_direct_cost</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_511200" model="account.account">
|
||||
<field name="code">511200</field>
|
||||
<field name="name">Third-party API Costs (Twilio, SendGrid, OpenAI)</field>
|
||||
<field name="account_type">expense_direct_cost</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_511210" model="account.account">
|
||||
<field name="code">511210</field>
|
||||
<field name="name">Per-customer Licensing & Royalties</field>
|
||||
<field name="account_type">expense_direct_cost</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_512100" model="account.account">
|
||||
<field name="code">512100</field>
|
||||
<field name="name">Subcontracted Labour — Canadian (T4A) — SR&ED-eligible</field>
|
||||
<field name="account_type">expense_direct_cost</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_512110" model="account.account">
|
||||
<field name="code">512110</field>
|
||||
<field name="name">Subcontracted Labour — Foreign — NOT SR&ED-eligible</field>
|
||||
<field name="account_type">expense_direct_cost</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_512200" model="account.account">
|
||||
<field name="code">512200</field>
|
||||
<field name="name">Project-specific Software & Licenses</field>
|
||||
<field name="account_type">expense_direct_cost</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_512300" model="account.account">
|
||||
<field name="code">512300</field>
|
||||
<field name="name">Project Travel & Onsite (rebilled)</field>
|
||||
<field name="account_type">expense_direct_cost</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_512400" model="account.account">
|
||||
<field name="code">512400</field>
|
||||
<field name="name">Project Hardware (passed through)</field>
|
||||
<field name="account_type">expense_direct_cost</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_513100" model="account.account">
|
||||
<field name="code">513100</field>
|
||||
<field name="name">Cost of Software Resold</field>
|
||||
<field name="account_type">expense_direct_cost</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_513200" model="account.account">
|
||||
<field name="code">513200</field>
|
||||
<field name="name">Cost of Hardware Resold</field>
|
||||
<field name="account_type">expense_direct_cost</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_519100" model="account.account">
|
||||
<field name="code">519100</field>
|
||||
<field name="name">COGS Adjustments / Write-offs</field>
|
||||
<field name="account_type">expense_direct_cost</field>
|
||||
</record>
|
||||
|
||||
<!-- ============================================================ -->
|
||||
<!-- 6xxxxx — OPERATING EXPENSES -->
|
||||
<!-- ============================================================ -->
|
||||
|
||||
<record id="acct_611100" model="account.account">
|
||||
<field name="code">611100</field>
|
||||
<field name="name">Salaries & Wages — Development (SR&ED-eligible)</field>
|
||||
<field name="account_type">expense</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_611200" model="account.account">
|
||||
<field name="code">611200</field>
|
||||
<field name="name">Salaries & Wages — Sales & Marketing</field>
|
||||
<field name="account_type">expense</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_611300" model="account.account">
|
||||
<field name="code">611300</field>
|
||||
<field name="name">Salaries & Wages — Admin & Operations</field>
|
||||
<field name="account_type">expense</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_611400" model="account.account">
|
||||
<field name="code">611400</field>
|
||||
<field name="name">Salary — Shareholder/Officer (Gurpreet)</field>
|
||||
<field name="account_type">expense</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_611500" model="account.account">
|
||||
<field name="code">611500</field>
|
||||
<field name="name">Employer CPP / QPP Contributions</field>
|
||||
<field name="account_type">expense</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_611600" model="account.account">
|
||||
<field name="code">611600</field>
|
||||
<field name="name">Employer EI Premiums</field>
|
||||
<field name="account_type">expense</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_611700" model="account.account">
|
||||
<field name="code">611700</field>
|
||||
<field name="name">Employer Health Tax (EHT/QHST)</field>
|
||||
<field name="account_type">expense</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_611800" model="account.account">
|
||||
<field name="code">611800</field>
|
||||
<field name="name">WCB / WSIB Premiums</field>
|
||||
<field name="account_type">expense</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_611900" model="account.account">
|
||||
<field name="code">611900</field>
|
||||
<field name="name">Employee Benefits (health, dental, group)</field>
|
||||
<field name="account_type">expense</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_611950" model="account.account">
|
||||
<field name="code">611950</field>
|
||||
<field name="name">Bonuses & Incentives</field>
|
||||
<field name="account_type">expense</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_611960" model="account.account">
|
||||
<field name="code">611960</field>
|
||||
<field name="name">Vacation Pay Accrual</field>
|
||||
<field name="account_type">expense</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_612100" model="account.account">
|
||||
<field name="code">612100</field>
|
||||
<field name="name">Contract Labour — Canadian (admin/marketing/freelance)</field>
|
||||
<field name="account_type">expense</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_612200" model="account.account">
|
||||
<field name="code">612200</field>
|
||||
<field name="name">Contract Labour — Foreign</field>
|
||||
<field name="account_type">expense</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_621100" model="account.account">
|
||||
<field name="code">621100</field>
|
||||
<field name="name">Rent — Commercial Office</field>
|
||||
<field name="account_type">expense</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_621200" model="account.account">
|
||||
<field name="code">621200</field>
|
||||
<field name="name">Home Office — Business Portion</field>
|
||||
<field name="account_type">expense</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_621300" model="account.account">
|
||||
<field name="code">621300</field>
|
||||
<field name="name">Utilities — Commercial</field>
|
||||
<field name="account_type">expense</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_621400" model="account.account">
|
||||
<field name="code">621400</field>
|
||||
<field name="name">Internet & Phone — Business</field>
|
||||
<field name="account_type">expense</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_621500" model="account.account">
|
||||
<field name="code">621500</field>
|
||||
<field name="name">Office Supplies & Consumables</field>
|
||||
<field name="account_type">expense</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_621600" model="account.account">
|
||||
<field name="code">621600</field>
|
||||
<field name="name">Cleaning & Maintenance</field>
|
||||
<field name="account_type">expense</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_621700" model="account.account">
|
||||
<field name="code">621700</field>
|
||||
<field name="name">Office Snacks & Refreshments</field>
|
||||
<field name="account_type">expense</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_631100" model="account.account">
|
||||
<field name="code">631100</field>
|
||||
<field name="name">Software — Productivity (M365, Slack, Notion, Linear, GitHub)</field>
|
||||
<field name="account_type">expense</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_631200" model="account.account">
|
||||
<field name="code">631200</field>
|
||||
<field name="name">Software — Development Tools (Cursor, Figma, IDEs)</field>
|
||||
<field name="account_type">expense</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_631300" model="account.account">
|
||||
<field name="code">631300</field>
|
||||
<field name="name">Software — Internal Infrastructure</field>
|
||||
<field name="account_type">expense</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_631400" model="account.account">
|
||||
<field name="code">631400</field>
|
||||
<field name="name">Software — Security & IT</field>
|
||||
<field name="account_type">expense</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_631500" model="account.account">
|
||||
<field name="code">631500</field>
|
||||
<field name="name">Software — Sales & Marketing</field>
|
||||
<field name="account_type">expense</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_641100" model="account.account">
|
||||
<field name="code">641100</field>
|
||||
<field name="name">Advertising — Digital Ads</field>
|
||||
<field name="account_type">expense</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_641200" model="account.account">
|
||||
<field name="code">641200</field>
|
||||
<field name="name">Advertising — Content / SEO</field>
|
||||
<field name="account_type">expense</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_641300" model="account.account">
|
||||
<field name="code">641300</field>
|
||||
<field name="name">Trade Shows & Conferences</field>
|
||||
<field name="account_type">expense</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_641400" model="account.account">
|
||||
<field name="code">641400</field>
|
||||
<field name="name">Promotional Items / Branded Swag</field>
|
||||
<field name="account_type">expense</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_641500" model="account.account">
|
||||
<field name="code">641500</field>
|
||||
<field name="name">Website — Own (nexasystems.ca)</field>
|
||||
<field name="account_type">expense</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_651100" model="account.account">
|
||||
<field name="code">651100</field>
|
||||
<field name="name">Legal Fees — General</field>
|
||||
<field name="account_type">expense</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_651200" model="account.account">
|
||||
<field name="code">651200</field>
|
||||
<field name="name">Accounting & Bookkeeping</field>
|
||||
<field name="account_type">expense</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_651300" model="account.account">
|
||||
<field name="code">651300</field>
|
||||
<field name="name">Tax Preparation (T2, T1, GST/HST)</field>
|
||||
<field name="account_type">expense</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_651400" model="account.account">
|
||||
<field name="code">651400</field>
|
||||
<field name="name">Business Consulting</field>
|
||||
<field name="account_type">expense</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_661100" model="account.account">
|
||||
<field name="code">661100</field>
|
||||
<field name="name">Insurance — Commercial General Liability</field>
|
||||
<field name="account_type">expense</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_661200" model="account.account">
|
||||
<field name="code">661200</field>
|
||||
<field name="name">Insurance — Professional Liability / E&O</field>
|
||||
<field name="account_type">expense</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_661300" model="account.account">
|
||||
<field name="code">661300</field>
|
||||
<field name="name">Insurance — Cyber Liability</field>
|
||||
<field name="account_type">expense</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_661400" model="account.account">
|
||||
<field name="code">661400</field>
|
||||
<field name="name">Insurance — Property</field>
|
||||
<field name="account_type">expense</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_661500" model="account.account">
|
||||
<field name="code">661500</field>
|
||||
<field name="name">Insurance — Directors & Officers</field>
|
||||
<field name="account_type">expense</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_671100" model="account.account">
|
||||
<field name="code">671100</field>
|
||||
<field name="name">Travel — Flights, Hotels, Ground Transport</field>
|
||||
<field name="account_type">expense</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_671200" model="account.account">
|
||||
<field name="code">671200</field>
|
||||
<field name="name">Meals & Entertainment — 50% Deductible</field>
|
||||
<field name="account_type">expense</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_671300" model="account.account">
|
||||
<field name="code">671300</field>
|
||||
<field name="name">Vehicle — Operating (gas, insurance, repairs, parking)</field>
|
||||
<field name="account_type">expense</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_671400" model="account.account">
|
||||
<field name="code">671400</field>
|
||||
<field name="name">Mileage Reimbursement — Personal Vehicle</field>
|
||||
<field name="account_type">expense</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_681100" model="account.account">
|
||||
<field name="code">681100</field>
|
||||
<field name="name">Conferences & Seminars (registration)</field>
|
||||
<field name="account_type">expense</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_681200" model="account.account">
|
||||
<field name="code">681200</field>
|
||||
<field name="name">Courses & Certifications</field>
|
||||
<field name="account_type">expense</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_681300" model="account.account">
|
||||
<field name="code">681300</field>
|
||||
<field name="name">Books & Publications</field>
|
||||
<field name="account_type">expense</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_681400" model="account.account">
|
||||
<field name="code">681400</field>
|
||||
<field name="name">Professional Memberships & Dues</field>
|
||||
<field name="account_type">expense</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_691100" model="account.account">
|
||||
<field name="code">691100</field>
|
||||
<field name="name">Bank Service Charges</field>
|
||||
<field name="account_type">expense</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_691200" model="account.account">
|
||||
<field name="code">691200</field>
|
||||
<field name="name">Merchant Processing Fees (Stripe, PayPal, Square)</field>
|
||||
<field name="account_type">expense</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_691300" model="account.account">
|
||||
<field name="code">691300</field>
|
||||
<field name="name">Wire Transfer & FX Fees</field>
|
||||
<field name="account_type">expense</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_691400" model="account.account">
|
||||
<field name="code">691400</field>
|
||||
<field name="name">Interest Expense — Bank Loans / LOC</field>
|
||||
<field name="account_type">expense</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_691500" model="account.account">
|
||||
<field name="code">691500</field>
|
||||
<field name="name">Interest Expense — Credit Cards</field>
|
||||
<field name="account_type">expense</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_691600" model="account.account">
|
||||
<field name="code">691600</field>
|
||||
<field name="name">Late Payment Penalties — Non-deductible</field>
|
||||
<field name="account_type">expense</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_699100" model="account.account">
|
||||
<field name="code">699100</field>
|
||||
<field name="name">Bad Debt Expense</field>
|
||||
<field name="account_type">expense</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_699200" model="account.account">
|
||||
<field name="code">699200</field>
|
||||
<field name="name">Donations & Sponsorships (deductible)</field>
|
||||
<field name="account_type">expense</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_699300" model="account.account">
|
||||
<field name="code">699300</field>
|
||||
<field name="name">Penalties & Fines — Non-deductible</field>
|
||||
<field name="account_type">expense</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_699400" model="account.account">
|
||||
<field name="code">699400</field>
|
||||
<field name="name">Realized FX Losses</field>
|
||||
<field name="account_type">expense</field>
|
||||
</record>
|
||||
|
||||
<record id="acct_699500" model="account.account">
|
||||
<field name="code">699500</field>
|
||||
<field name="name">Depreciation / CCA Expense</field>
|
||||
<field name="account_type">expense</field>
|
||||
</record>
|
||||
|
||||
</data>
|
||||
</odoo>
|
||||
5
nexa_coa_setup/data/02_account_journal.xml
Normal file
5
nexa_coa_setup/data/02_account_journal.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data noupdate="0">
|
||||
</data>
|
||||
</odoo>
|
||||
5
nexa_coa_setup/data/03_account_tax.xml
Normal file
5
nexa_coa_setup/data/03_account_tax.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data noupdate="0">
|
||||
</data>
|
||||
</odoo>
|
||||
5
nexa_coa_setup/data/04_account_fiscal_position.xml
Normal file
5
nexa_coa_setup/data/04_account_fiscal_position.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data noupdate="0">
|
||||
</data>
|
||||
</odoo>
|
||||
5
nexa_coa_setup/data/05_account_analytic_plan.xml
Normal file
5
nexa_coa_setup/data/05_account_analytic_plan.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data noupdate="0">
|
||||
</data>
|
||||
</odoo>
|
||||
5
nexa_coa_setup/data/06_account_analytic_account.xml
Normal file
5
nexa_coa_setup/data/06_account_analytic_account.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data noupdate="0">
|
||||
</data>
|
||||
</odoo>
|
||||
5
nexa_coa_setup/data/07_product_category.xml
Normal file
5
nexa_coa_setup/data/07_product_category.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data noupdate="0">
|
||||
</data>
|
||||
</odoo>
|
||||
5
nexa_coa_setup/data/08_res_partner_category.xml
Normal file
5
nexa_coa_setup/data/08_res_partner_category.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data noupdate="0">
|
||||
</data>
|
||||
</odoo>
|
||||
5
nexa_coa_setup/data/09_res_partner.xml
Normal file
5
nexa_coa_setup/data/09_res_partner.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data noupdate="0">
|
||||
</data>
|
||||
</odoo>
|
||||
5
nexa_coa_setup/data/10_account_reconcile_model.xml
Normal file
5
nexa_coa_setup/data/10_account_reconcile_model.xml
Normal file
@@ -0,0 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo>
|
||||
<data noupdate="0">
|
||||
</data>
|
||||
</odoo>
|
||||
68
nexa_coa_setup/hooks.py
Normal file
68
nexa_coa_setup/hooks.py
Normal file
@@ -0,0 +1,68 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import logging
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
def post_init_hook(env):
|
||||
"""Imperative one-shot operations after module data is loaded.
|
||||
|
||||
Each helper is idempotent — safe to re-run on -u.
|
||||
"""
|
||||
_logger.info("nexa_coa_setup: post_init_hook starting")
|
||||
_normalize_company_hst_number(env)
|
||||
_archive_unused_l10n_ca_accounts(env)
|
||||
_rename_legacy_accounts(env)
|
||||
_lock_fiscal_year_2025(env)
|
||||
_logger.info("nexa_coa_setup: post_init_hook complete")
|
||||
|
||||
|
||||
def _normalize_company_hst_number(env):
|
||||
"""Convert '741224877' to '741224877 RT0001' if not already in full form."""
|
||||
company = env.ref("base.main_company", raise_if_not_found=False)
|
||||
if not company:
|
||||
return
|
||||
vat = (company.partner_id.vat or "").strip()
|
||||
if vat == "741224877":
|
||||
company.partner_id.vat = "741224877 RT0001"
|
||||
_logger.info("nexa_coa_setup: normalized HST# to '741224877 RT0001'")
|
||||
|
||||
|
||||
def _archive_unused_l10n_ca_accounts(env):
|
||||
"""Stub — filled in Phase 4. Archives ~370 unused accounts."""
|
||||
pass
|
||||
|
||||
|
||||
def _rename_legacy_accounts(env):
|
||||
"""Stub — filled in Phase 4. Renames the 14xx/15xx legacy accounts."""
|
||||
pass
|
||||
|
||||
|
||||
def _lock_fiscal_year_2025(env):
|
||||
"""Try to set fiscalyear_lock_date = 2025-12-31 on main company.
|
||||
|
||||
If Odoo blocks the lock because unreconciled bank statement lines or other
|
||||
open items exist in the period, log a clear warning and continue. The user
|
||||
can set the lock manually via Accounting > Configuration > Settings > Lock
|
||||
Dates once those items are cleaned up.
|
||||
"""
|
||||
from datetime import date
|
||||
from odoo.exceptions import RedirectWarning, UserError, ValidationError
|
||||
company = env.ref("base.main_company", raise_if_not_found=False)
|
||||
if not company:
|
||||
return
|
||||
target = date(2025, 12, 31)
|
||||
if company.fiscalyear_lock_date and company.fiscalyear_lock_date >= target:
|
||||
_logger.info("nexa_coa_setup: fiscalyear_lock_date already at or after 2025-12-31")
|
||||
return
|
||||
try:
|
||||
company.fiscalyear_lock_date = target
|
||||
_logger.info("nexa_coa_setup: fiscalyear_lock_date set to 2025-12-31")
|
||||
except (RedirectWarning, UserError, ValidationError) as exc:
|
||||
_logger.warning(
|
||||
"nexa_coa_setup: could not auto-lock fiscal year 2025-12-31. "
|
||||
"Reason: %s. Set the lock manually via Accounting > Configuration > "
|
||||
"Settings > Lock Dates after the unreconciled items in the period "
|
||||
"are cleaned up.",
|
||||
exc,
|
||||
)
|
||||
1
nexa_coa_setup/models/__init__.py
Normal file
1
nexa_coa_setup/models/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
# no custom models — placeholder for future extensions
|
||||
1
nexa_coa_setup/security/ir.model.access.csv
Normal file
1
nexa_coa_setup/security/ir.model.access.csv
Normal file
@@ -0,0 +1 @@
|
||||
id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink
|
||||
|
Reference in New Issue
Block a user