Eliminate Python dependency: embed frontend assets in odoo-go

- Copy all OWL frontend assets (JS/CSS/XML/fonts/images) into frontend/
  directory (2925 files, 43MB) — no more runtime reads from Python Odoo
- Replace OdooAddonsPath config with FrontendDir pointing to local frontend/
- Rewire bundle.go, static.go, templates.go, webclient.go to read from
  frontend/ instead of external Python Odoo addons directory
- Auto-detect frontend/ and build/ dirs relative to binary in main.go
- Delete obsolete Python helper scripts (tools/*.py)

The Go server is now fully self-contained: single binary + frontend/ folder.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Marc
2026-03-31 23:09:12 +02:00
parent 0ed29fe2fd
commit 8741282322
2933 changed files with 280644 additions and 264 deletions

View File

@@ -0,0 +1,186 @@
<?xml version="1.0" encoding="UTF-8"?>
<templates>
<t t-name="purchase.PurchaseDashboard">
<div class="o_purchase_dashboard container-fluid py-4 border-bottom bg-view">
<div class="row justify-content-between gap-2 gap-lg-0">
<div class="col-12 col-lg-8 flex-grow-1 flex-lg-grow-0 flex-shrink-0">
<div class="grid gap-1 gap-lg-4">
<div class="g-col-12 g-col-lg-1 d-flex align-items-center pt-2 pb-lg-2 justify-content-lg-end text-break">
<t t-if="multiuser">All</t>
</div>
<div class="g-col-12 g-col-lg-11 grid gap-1" style="--columns: 61">
<div class="g-col-12 p-0" t-on-click="setSearchContext" title="All Draft RFQs" filter_name="draft_rfqs">
<a href="#" class="btn purchase-dashboard-card p-1 p-lg-2 text-truncate text-wrap"
t-attf-class="o_purchase_dashboard_card_{{ multiuser ? 'top' : 'sole' }}
{{ purchaseData['global']['draft']['all'] == 0
? 'bg-secondary-subtle text-secondary-emphasis'
: 'bg-info-subtle text-info-emphasis' }}">
<div class="fs-2">
<span t-out="purchaseData['global']['draft']['all']"/>
<span class="ps-4" t-if="purchaseData['global']['draft']['priority']">
<span class="o_priority_star fa fa-star "/> <span t-out="purchaseData['global']['draft']['priority']"/>
</span>
</div>New
</a>
</div>
<div class="g-col-12 p-0" t-on-click="setSearchContext" title="All Sent RFQs" filter_name="waiting_rfqs">
<a href="#" class="btn purchase-dashboard-card p-1 p-lg-2 bg-secondary-subtle text-secondary-emphasis text-truncate text-wrap"
t-attf-class="o_purchase_dashboard_card_{{ multiuser ? 'top' : 'sole' }}">
<div class="fs-2">
<span t-out="purchaseData['global']['sent']['all']"/>
<span class="ps-4" t-if="purchaseData['global']['sent']['priority']">
<span class="o_priority_star fa fa-star "/> <span t-out="purchaseData['global']['sent']['priority']"/>
</span>
</div>RFQ Sent
</a>
</div>
<div class="g-col-12 p-0" t-on-click="setSearchContext" title="All Late RFQs" filter_name="late">
<a href="#" class="btn purchase-dashboard-card p-1 p-lg-2 text-truncate text-wrap"
t-attf-class="o_purchase_dashboard_card_{{ multiuser ? 'top' : 'sole' }}
{{ purchaseData['global']['late']['all'] == 0
? 'bg-secondary-subtle text-secondary-emphasis'
: 'bg-warning-subtle text-warning-emphasis' }}">
<div class="fs-2">
<span t-out="purchaseData['global']['late']['all']"/>
<span class="ps-4" t-if="purchaseData['global']['late']['priority']">
<span class="o_priority_star fa fa-star "/> <span t-out="purchaseData['global']['late']['priority']"/>
</span>
</div>Late RFQ
</a>
</div>
<div class="g-col-1"/>
<div class="g-col-12 p-0" t-on-click="setSearchContext" title="All Not Acknowledged POs" filter_name="not_acknowledged">
<a href="#" class="btn purchase-dashboard-card p-1 p-lg-2 text-truncate text-wrap"
t-attf-class="o_purchase_dashboard_card_{{ multiuser ? 'top' : 'sole' }}
{{ purchaseData['global']['not_acknowledged']['all'] == 0
? 'bg-secondary-subtle text-secondary-emphasis'
: 'bg-info-subtle text-info-emphasis' }}">
<div class="fs-2">
<span t-out="purchaseData['global']['not_acknowledged']['all']"/>
<span class="ps-4" t-if="purchaseData['global']['not_acknowledged']['priority']">
<span class="o_priority_star fa fa-star "/> <span t-out="purchaseData['global']['not_acknowledged']['priority']"/>
</span>
</div>Not Acknowledged
</a>
</div>
<div class="g-col-12 p-0" t-on-click="setSearchContext" title="All Late Receipt POs" filter_name="late_receipt">
<a href="#" class="btn purchase-dashboard-card p-1 p-lg-2 text-truncate text-wrap"
t-attf-class="o_purchase_dashboard_card_{{ multiuser ? 'top' : 'sole' }}
{{ purchaseData['global']['late_receipt']['all'] == 0
? 'bg-secondary-subtle text-secondary-emphasis'
: 'bg-danger-subtle text-danger-emphasis' }}">
<div class="fs-2">
<span t-out="purchaseData['global']['late_receipt']['all']"/>
<span class="ps-4" t-if="purchaseData['global']['late_receipt']['priority']">
<span class="o_priority_star fa fa-star "/> <span t-out="purchaseData['global']['late_receipt']['priority']"/>
</span>
</div>Late Receipt
</a>
</div>
</div>
</div>
<div t-if="multiuser" class="grid gap-1 gap-lg-4">
<div class="g-col-12 g-col-lg-1 d-flex align-items-center pt-2 pb-lg-2 justify-content-lg-end text-break">
My
</div>
<div class="g-col-12 g-col-lg-11 grid gap-1 pt-0 pt-lg-1" style="--columns: 61">
<div class="g-col-12 p-0" t-on-click="setSearchContext" title="My Draft RFQs" filter_name="draft_rfqs,my_purchases">
<a href="#" class="o_purchase_dashboard_card_bottom btn purchase-dashboard-card p-1 p-lg-2 text-truncate text-wrap"
t-attf-class="{{ purchaseData['my']['draft']['all'] == 0 ? 'bg-secondary-subtle text-secondary-emphasis' : 'bg-info-subtle text-info-emphasis' }}">
<div>
<span t-out="purchaseData['my']['draft']['all']"/>
<span class="ps-4" t-if="purchaseData['my']['draft']['priority']">
<span class="o_priority_star fa fa-star "/> <span t-out="purchaseData['my']['draft']['priority']"/>
</span>
</div>
</a>
</div>
<div class="g-col-12 p-0" t-on-click="setSearchContext" title="My Waiting RFQs" filter_name="waiting_rfqs,my_purchases">
<a href="#" class="o_purchase_dashboard_card_bottom btn purchase-dashboard-card p-1 p-lg-2 bg-secondary-subtle text-secondary-emphasis text-truncate text-wrap">
<div>
<span t-out="purchaseData['my']['sent']['all']"/>
<span class="ps-4" t-if="purchaseData['my']['sent']['priority']">
<span class="o_priority_star fa fa-star "/> <span t-out="purchaseData['my']['sent']['priority']"/>
</span>
</div>
</a>
</div>
<div class="g-col-12 p-0" t-on-click="setSearchContext" title="My Late RFQs" filter_name="late,my_purchases">
<a href="#" class="o_purchase_dashboard_card_bottom btn purchase-dashboard-card p-1 p-lg-2 text-truncate text-wrap"
t-attf-class="{{ purchaseData['my']['late']['all'] == 0 ? 'bg-secondary-subtle text-secondary-emphasis' : 'bg-warning-subtle text-warning-emphasis' }}">
<div>
<span t-out="purchaseData['my']['late']['all']"/>
<span class="ps-4" t-if="purchaseData['my']['late']['priority']">
<span class="o_priority_star fa fa-star "/> <span t-out="purchaseData['my']['late']['priority']"/>
</span>
</div>
</a>
</div>
<div class="g-col-1"/>
<div class="g-col-12 p-0" t-on-click="setSearchContext" title="My Not Acknowledged POs" filter_name="not_acknowledged,my_purchases">
<a href="#" class="o_purchase_dashboard_card_bottom btn purchase-dashboard-card p-1 p-lg-2 text-truncate text-wrap"
t-attf-class="{{ purchaseData['my']['not_acknowledged']['all'] == 0 ? 'bg-secondary-subtle text-secondary-emphasis' : 'bg-info-subtle text-info-emphasis' }}">
<div>
<span t-out="purchaseData['my']['not_acknowledged']['all']"/>
<span class="ps-4" t-if="purchaseData['my']['not_acknowledged']['priority']">
<span class="o_priority_star fa fa-star "/> <span t-out="purchaseData['my']['not_acknowledged']['priority']"/>
</span>
</div>
</a>
</div>
<div class="g-col-12 p-0" t-on-click="setSearchContext" title="My Late Receipt POs" filter_name="late_receipt,my_purchases">
<a href="#" class="o_purchase_dashboard_card_bottom btn purchase-dashboard-card p-1 p-lg-2 text-truncate text-wrap"
t-attf-class="{{ purchaseData['my']['late_receipt']['all'] == 0 ? 'bg-secondary-subtle text-secondary-emphasis' : 'bg-danger-subtle text-danger-emphasis' }}">
<div>
<span t-out="purchaseData['my']['late_receipt']['all']"/>
<span class="ps-4" t-if="purchaseData['my']['late_receipt']['priority']">
<span class="o_priority_star fa fa-star "/> <span t-out="purchaseData['my']['late_receipt']['priority']"/>
</span>
</div>
</a>
</div>
</div>
</div>
</div>
<div class="col-12 col-lg-3 flex-shrink-0">
<div class="grid gap-1 gap-lg-4">
<div class="d-lg-none g-col-12 d-flex align-items-center pt-2 pb-lg-2 justify-content-lg-end text-break">
All
</div>
<div class="g-col-12 g-col-lg-12 grid gap-1">
<div class="d-none d-lg-block g-col-6 p-0" id="left_grid_top"/>
<div class="g-col-6 p-0" title="All Days to Order">
<div class="purchase-dashboard-card o_no_hover p-1 p-lg-2 text-truncate text-wrap"
t-attf-class="o_purchase_dashboard_card_{{ multiuser ? 'top' : 'sole' }}
{{ purchaseData['days_to_purchase'] and
purchaseData['global']['days_to_order'] > purchaseData['days_to_purchase']
? 'btn btn-warning'
: 'bg-100 text-center' }}">
<div class="fs-2" t-out="purchaseData['global']['days_to_order']"/>Days to Order
</div>
</div>
</div>
</div>
<div t-if="multiuser" class="grid gap-1 gap-lg-4 pt-0 pt-lg-1">
<div class="d-lg-none g-col-12 d-flex align-items-center pt-2 pb-lg-2 justify-content-lg-end text-break">
My
</div>
<div class="g-col-12 g-col-lg-12 grid gap-1">
<div class="d-none d-lg-block g-col-6 p-0" id="left_grid_bottom"/>
<div class="g-col-6 p-0" title="My Days to Order">
<div class="o_purchase_dashboard_card_bottom purchase-dashboard-card o_no_hover p-1 p-lg-2 text-truncate text-wrap"
t-attf-class="{{
purchaseData['days_to_purchase'] and
purchaseData['global']['days_to_order'] > purchaseData['days_to_purchase']
? 'btn btn-warning' : 'bg-100 text-center' }}">
<div t-out="purchaseData['my']['days_to_order']"/>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</t>
</templates>