Commit Graph

1429 Commits

Author SHA1 Message Date
gsinghpal
4949856336 fix(plating): drop Specification + Delivery Date from customer reports
Remove the unused Customer Specification field and the redundant
Delivery Date (Lead Time covers it) from the customer-facing SO
confirmation and invoice PDFs (portrait + landscape). SO info row goes
5->4 columns (Delivery Date gone); the Customer Job # / Spec / Delivery
Method row goes 3->2 (Spec gone). Internal docs (traveller, sticker) and
the CoC process "Specification(s)" section are left untouched.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 00:19:40 -04:00
gsinghpal
9826e03b4e fix(plating): show additional charge under subtotal on SO + invoice PDFs
Tooling/additional charge lines (any product line with no part catalog)
no longer print in the parts table — they render in the totals block
under the subtotal with their entered label + amount. Subtotal is now
parts-only; tax + grand total are unchanged (the charge is still a real
taxed line in the data). Applies to SO confirmation and invoice, both
portrait and landscape. Also aligns the invoice S/N cell to the SO's
multi-serial rendering.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-30 00:04:33 -04:00
gsinghpal
69aa6b050b style(plating): subtle plum accents + gradients on the express order form
Add a cohesive, restrained colour layer using the existing express
tokens (light/dark aware): faint plum gradient washes on the PO card,
legend bar, table header, and Order Summary header; filled accent
gradient pills (EXPRESS / CAD); accent rules on the section title,
summary header, and Grand Total footer. Adds an $xpr-accent-tint token
plus four composed gradient tokens.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-29 23:12:46 -04:00
gsinghpal
5675784916 fix(plating): stop charge/tax pickers collapsing in order summary
The right-aligned value column squeezed the Additional Charge and Tax
dropdowns to a sliver. Move each picker into the (wider) label column,
stacked under its label at full width, so every value cell is now a
single amount that lines up cleanly in the right column under the
vertical divider.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-29 23:01:14 -04:00
gsinghpal
0d4a871d0c style(plating): add vertical column divider to order summary table
Switch the summary rows from a flex space-between layout to a fixed
two-column grid (label | value) so a vertical divider on the label
cell's right edge lines up across every row. Values are right-aligned
into a clean amount column; the Grand Total footer keeps the divider at
the heavier rule weight.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-29 22:54:52 -04:00
gsinghpal
aac95ee16b style(plating): express order summary as a bordered table
Restyle the Order Summary card into a clean bordered table — a tinted
"Order Summary" caption bar, a divider line under every row, and an
accent-tinted Grand Total footer with a strong top rule. Uses the
existing light/dark express tokens so it renders correctly in both
colour schemes.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-29 22:49:11 -04:00
gsinghpal
028814b292 fix(plating): order-level Lot Order toggle replaces per-line lot checkbox
Express order entry now has a single "Lot Order" toggle on the header
instead of a per-line "Lot" checkbox. When on, every line shows Lot
Total and prices as a flat lot (unit price derived = lot total / qty,
qty preserved for production); when off, the Lot Total column is hidden
and lines price per unit as usual. Keeps the order summary clean for the
common per-unit case.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-29 22:44:07 -04:00
gsinghpal
2bd0672b52 fix(configurator): lot pricing robust in totals + SO-create (not reliant on onchange)
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-29 21:48:43 -04:00
gsinghpal
dc1dacddc2 feat(configurator): express summary — charge type + tax type + lot column 2026-05-29 21:42:42 -04:00
gsinghpal
6dde3ec2b1 feat(configurator): SO-create applies one tax to all lines + typed charge line
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-29 21:40:52 -04:00
gsinghpal
a2ac804238 feat(configurator): per-line lot pricing (derive unit price, keep qty) 2026-05-29 21:38:49 -04:00
gsinghpal
f8929eb686 feat(configurator): totals = one tax on (subtotal + charge) 2026-05-29 21:37:00 -04:00
gsinghpal
a07a5f931a feat(configurator): wizard charge_type_id + charge_amount + order-level tax_id 2026-05-29 21:34:47 -04:00
gsinghpal
c6022c70f9 feat(configurator): fp.additional.charge.type model + config menu + seed 2026-05-29 21:32:49 -04:00
gsinghpal
7efaadc1c1 docs(plating): implementation plan for charge type + order-level tax + lot pricing
Bite-sized TDD plan: charge-type model + config UI, wizard charge/tax fields,
totals = one tax on (subtotal+charge), per-line lot pricing, SO-create tax on
all lines + typed charge line, and the express summary/line view changes.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-29 21:25:25 -04:00
gsinghpal
21300db8e8 docs(plating): spec — configurable charge type + order-level tax + lot pricing
Direct/Express order entry: a searchable/creatable fp.additional.charge.type
replaces the fixed Tooling Charge; one order-level account.tax applies to
(subtotal + charge); per-line lot pricing (flat lot total, derived unit price,
qty preserved). Reordered summary. Quotes out of scope.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-29 21:17:55 -04:00
gsinghpal
1e9ffccd6b feat(invoicing): managers (+QM+Owner) can create customer invoices
Grant Odoo Billing (account.group_account_invoice) to group_fp_manager via
implied_ids; Quality Manager + Owner inherit it. Billing only (not Accountant);
the SO-origin workflow gate in fusion_plating_jobs is unchanged, so managers
invoice from the Sale Order's Create Invoice action. Tests assert Manager/Owner
get Billing and Shop Manager does not.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-29 20:33:40 -04:00
gsinghpal
b2186ab032 feat(configurator): Description History list on the part Descriptions tab
Read-only per-part version history (version#, reference, customer-facing,
order, by/when) below the curated templates list.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-29 19:57:57 -04:00
gsinghpal
855b160752 feat(configurator): auto-load latest part description version on order entry
Wizard line (direct + express) and SO line now pre-fill BOTH internal +
customer-facing from the part's latest version (fallback to
default_specification_text), without clobbering typed text.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-29 19:57:16 -04:00
gsinghpal
da7ec59474 feat(configurator): save a part description version on SO confirm
Each part-bearing line writes a deduped version (final order# + date) via
_fp_save_description_version, after the parent-number rename so the title
reflects the confirmed order number.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-29 19:56:01 -04:00
gsinghpal
2ed3dcee58 feat(configurator): per-part description version model + part load/save helpers
fp.part.description.version: immutable per-part snapshots with version_no/
is_latest maintained in create(), titled "<SO#> · <date>". fp.part.catalog
gains description_version_ids + _fp_resolve_line_descriptions (load latest,
fallback to default_specification_text) and _fp_save_description_version
(dedup + sync default). ACL mirrors fp.sale.description.template.

Tests deferred to entech (local Docker unavailable this session).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-29 19:55:14 -04:00
gsinghpal
9b18f77e06 docs(plating): implementation plan for per-part description history
Bite-sized TDD plan: version model + part load/save helpers, save-on-confirm
hook, wizard + SO-line auto-load, and the part Descriptions-tab history list.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-29 19:51:10 -04:00
gsinghpal
1ae83e187e docs(plating): spec — per-part description history (auto-version on order entry)
Dedicated fp.part.description.version model: latest auto-loads both internal +
customer-facing into a new order line; on SO confirm, a changed description
saves a new version titled "S#### · date". Browsable per-part history;
default_specification_text kept synced. SO surfaces only (not quotes).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-29 19:38:20 -04:00
gsinghpal
1b0657bd76 fix(configurator): drop the first-time-part "no saved specification" popup
The order-line onchange still auto-ticks "Save as Default" (so a new part's
spec is remembered next time) — only the explanatory popup is removed, per
client request. The ticked checkbox on the line is the cue now.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-29 12:11:34 -04:00
gsinghpal
f75e082e67 feat(shopfloor): tablet Shipping panel on the Job Workspace
Carrier/service/weight inputs + Generate Label + Mark Shipped, shown when the
job is awaiting_ship and gated read-only ("Waiting on: WO-xxxx") until every
job on the order is ready. Reuses workspace card tokens; dark-mode accent
override included.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-29 09:19:51 -04:00
gsinghpal
f1273798cd feat(shopfloor): tablet shipping endpoints + /load shipping payload
generate_label (sudo'd FedEx machinery) and mark_shipped (as the technician),
both enforcing the order-level ship-together gate. /load now returns a
shipping block (carrier/service/weight + readiness + any existing label)
when the job is awaiting_ship.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-29 09:16:36 -04:00
gsinghpal
bb814a46ff feat(jobs): order-level ship-readiness helpers
_fp_order_ship_state + _fp_mark_order_shipped enforce spec D4 ship-together:
the order ships only when every active job on it is awaiting_ship/done.
Shared by the tablet shipping endpoints and /fp/workspace/load.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-29 09:14:36 -04:00
gsinghpal
be7256ce4c feat(logistics): technicians can create/edit delivery, POD, chain-of-custody
Spec D5 delivery-completion set. Dispatch records (route/vehicle/pickup)
stay read-only for technicians.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-29 09:13:11 -04:00
gsinghpal
d37f10f1c3 feat(receiving): technicians can count+close receivings from the tablet
ACL: grant group_fp_technician write+create on fp.receiving / line / damage.
sudo the internal sale.order x_fc_receiving_status write so a non-privileged
technician isn't blocked inside action_mark_counted / action_close.

Tests deferred to entech (local Docker unavailable this session).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-29 09:11:39 -04:00
gsinghpal
b98ee8a6fb docs(plating): implementation plan for technician receiving + shipping tablet
Bite-sized TDD plan across receiving ACL+sudo, delivery ACL, fp.job
ship-readiness helpers, shipping endpoints, and the workspace shipping
panel. Also patches the spec to record the sale.order status-write sudo
fix found during planning.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-29 00:50:23 -04:00
gsinghpal
df0de97a68 docs(plating): spec — technician receiving + shipping from the workstation tablet
Design for letting Technicians receive a confirmed order and ship a finished
order from the fp_job_workspace tablet surface. Receiving is ACL-only (the
panel + endpoints already exist); shipping adds a workspace panel + two
sudo-backed endpoints (generate label, mark shipped) gated on all order jobs
being awaiting_ship.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-29 00:35:40 -04:00
gsinghpal
49a0a953e5 fix(plating): single bilingual CoC — remove the separate French print action
The CoC body now renders English + the French translation together, so the
separate "Certificat de Conformité (Français)" print option was redundant.

- Removed the action_report_coc_fr report action and the now-dead
  report_coc_fr template; renamed action_report_coc_en to "Certificate of
  Conformance" (print filename "CoC - <name>").
- fp_notification_template: dropped the per-partner-language EN/FR branch —
  CoC email attachments always render the single bilingual action_report_coc_en.
- fp_hide_default_reports: dropped the FR sequence record.
- Refreshed the report_coc.xml design note.
- Bump reports 19.0.11.32.0, notifications 19.0.7.1.0.

Deployed on entech (-u removed the orphan FR action + template). Verified the
cert Print menu now lists only "Certificate of Conformance" and it renders
clean. The dead action_report_coc_fr ref in the uninstalled
fusion_plating_bridge_mrp is left as-is (module not loaded).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-28 23:33:00 -04:00
gsinghpal
64eb34cdff fix(plating): CoC signer follows Settings "Certificate Owner" (no stale freeze)
Changing Settings -> Certificate Owner didn't move existing certs: the signer
was snapshotted from the company owner at cert-creation time, and the CoC
prefers that snapshot over the live owner.

- _fp_create_certificates no longer freezes the company owner into
  certified_by_id; it snapshots ONLY a deliberate per-spec signer. Empty
  certified_by_id then resolves the LIVE company owner in the CoC report.
- action_issue lazy-fill made robust: resolves the company via the SO /
  env.company (fp.certificate has no company_id) so it fills the CURRENT
  owner at issue and the "Certified By" gate still passes.
- Settings help text corrected: signature comes from the user's Plating
  Signature (Preferences -> My Profile), not "HR Employee".
- Data fix on entech: cleared certified_by_id on 5 stale draft CoCs with no
  per-spec signer so they follow the current owner.

Bump certificates 19.0.9.3.0, jobs 19.0.11.4.0. Verified: CoC-30058 resolves
signer = Garry Singh (has Plating Signature), renders clean.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-28 23:20:38 -04:00
gsinghpal
cd0c08f348 fix(plating): parse Fischerscope .doc/.docx/RTF dropped on the cert form
The cert form's x_fc_local_thickness_pdf field only stored the upload; only
the Issue Certs wizard parsed it. Add create/write hooks on the jobs-side
fp.certificate that, when a NON-PDF is written to that field, run the wizard's
parser: readings -> thickness_reading_ids, header metadata -> x_fc_thickness_*,
microscope image (RTF) -> x_fc_thickness_image_id, then relocate the source to
x_fc_local_thickness_evidence_id and clear the PDF field (mirrors the wizard's
non-PDF end state). Real PDFs pass through untouched for the page-2 merge.
Re-entry guarded via the fp_skip_thickness_parse context flag. Bump jobs
19.0.11.3.0.

Deployed + verified on entech: CoC-30065 (.doc) back-filled to 3 readings +
metadata (operator BK) + extracted microscope image, renders inline (242KB);
PDF cert CoC-30040-02 correctly left untouched.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-28 23:01:02 -04:00
gsinghpal
6a5364e053 fix(plating): compact CoC first column + 3-line part data
- Column titles now render inline "English / French" on one line (was
  stacked), cutting header height. First column drops "Line Item": it is
  now Part Number / No. de pièce, Description / Description, Serial Number /
  Numéro de série with a tight line-height.
- First-column DATA shows three lines — part number, part name, serial
  number — via new fp.certificate._fp_resolve_part_identity() (part name
  from the job's part catalog, serials from the matching SO line; blanks
  fall back to "-"). Bump certificates 19.0.9.2.0, reports 19.0.11.31.0.

Deployed + verified on entech (CoC-30059: ('9876699373',
'VALVE BODY - COMPLETE - ASSY', ''), 243KB render).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-28 22:28:04 -04:00
gsinghpal
ec78fc148d feat(plating): fully bilingual CoC — all labels EN/FR
Convert every remaining CoC label from single-language (is_fr branch) to
bilingual EN/FR: document title, customer block (Name / Address / Contact /
Email / Phone), Fischerscope thickness report title + metadata (Equipment /
Product / Application / Directory / Calibration Std. / Operator / Measured /
Measuring Time), reading stats (Mean / Std Dev / Range), Source file,
Certified By, Name, and the Certification Statement heading. The statement
paragraph now prints both English and French. Reuses the SO report's inline
.fp-bl-en/.fp-bl-fr bilingual classes. Bump reports 19.0.11.30.0.

Deployed + render-verified on entech (CoC-30059 with thickness block, 243KB).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-28 22:11:40 -04:00
gsinghpal
9d9be17542 feat(plating): bilingual EN/FR column titles on the CoC
Make every CoC classic-body column title bilingual — English (bold) over
the French translation (italic grey), matching Steelhead and the SO
report's stacked-header convention. Cert-info headers (Date of
Certification / Generated By / Work Order #) and line-item headers
(Process / Customer PO / Shipped / NC Qty / Customer Job No.) now show
both languages. First column carries Part Number / Line Item,
Description, and Serial Number, each translated. Bump reports 19.0.11.29.0.

Deployed + render-verified on entech (CoC-30065, 224KB).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-28 21:54:45 -04:00
gsinghpal
1d1bbfe612 fix(plating): border the CoC signature/statement table
My prior change removed the .cert-statement-box border but the signature +
statement table was never bordered, leaving the whole section borderless.
Add class="bordered" so the two main columns (Certified By | Certification
Statement) get the outer box + divider like the other report tables; the
statement text keeps no separate inner box. Bump reports 19.0.11.28.2.

Deployed on entech (fusion_plating_reports upgrade clean).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-28 21:37:28 -04:00
gsinghpal
b1257b6983 fix(plating): remove border around CoC certification statement
The .cert-statement-box border was redundant next to the bordered tables;
render the statement as plain text (padding 0). Bump reports 19.0.11.28.1.

Deployed on entech (fusion_plating_reports upgrade clean).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-28 21:32:53 -04:00
gsinghpal
687decca28 fix(plating): clean up CoC layout — drop empty logo column + separating lines
- Customer block: remove the (usually empty) customer-logo third column;
  Address | Contact now split 50/50.
- Remove the heavy header bottom border (the Sale Order header has none) and
  the hr.heavy rule between the customer block and the cert info table.
- Drop now-dead CSS (.fp-coc h1, hr.heavy, .customer-logo). Bump reports to
  19.0.11.28.0.

Deployed + render-verified on entech (CoC-30065, 222KB PDF, no QWeb errors).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-28 21:25:32 -04:00
gsinghpal
307afbf3c0 feat(plating): CoC spec-optional + SO-style header + thickness for any cert
- Drop the hard spec_reference gate on fp.certificate.action_issue. The
  customer-facing description (_fp_resolve_customer_facing_description,
  walks job -> SO line, reuses fp_customer_description) now drives the CoC
  Process column; spec_reference prints only when an estimator fills it.
- CoC EN/FR reports swap web.external_layout for fp_external_layout_clean +
  paperformat_fp_a4_portrait. New shared coc_header (company logo + address
  left, Nadcap logo centre, title + Code128 barcode right) mirrors the Sale
  Order header. Removed the 3-logo Nadcap/AS9100/CGP accreditation strip and
  the body H1s; padding-top 0 on both body wrappers.
- Un-gate the Issue Certs wizard thickness upload (was invisible unless the
  customer was thickness-flagged) so a Fischerscope report can be attached to
  ANY cert; merge (page 2) + inline readings already render unconditionally.
- Update issue-gate tests, bump versions (certificates 19.0.9.1.0,
  reports 19.0.11.27.0, jobs 19.0.11.2.0), record CLAUDE.md rule 14c.

Deployed + render-verified on entech (CoC-30065, 223KB PDF, no QWeb errors).

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-28 21:17:09 -04:00
gsinghpal
fecd2415f6 changes 2026-05-27 19:23:17 -04:00
gsinghpal
e36318f7a5 feat(billing): Stripe/Lago-verified go-forward sync + activate daily cron
The NexaCloud->Odoo ledger now verifies every new invoice against its
SOURCE billing system before posting, instead of trusting NexaCloud's
unreliable created_at/status/paid_at:

- _fc_verify routes by stripe_invoice_id prefix (in_ -> Stripe REST,
  lago: -> Lago REST) and returns source-truth
  {invoice_date, void, draft, paid, paid_at, amount_paid}, or None when it
  can't be determined/reached (left for the next run).
- _ingest_invoices(post=True, verified=...) uses the source invoice date
  (and accounting date), and reconciles a payment ONLY when the source
  confirms paid.
- _cron_sync_verified posts only finalized invoices; skips void + draft,
  logs unverified for retry. Replaces the old _cron_ingest_recent.

Cron cron_fc_invoice_ledger is enabled daily on nexamain. First live run:
23 already-posted, 1 void + 2 Stripe drafts + 5 zero-amount all skipped,
0 new posted, ledger intact at $3,403.46.

Tests: routing/guards (no network), verified date+reconcile, and the cron's
void/draft/unverified filtering (sources patched). FCB_EXIT=0 on odoo-trial.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-27 18:37:36 -04:00
gsinghpal
feddca19d6 docs(billing): record verified backfill (Stripe+Lago) + go-forward verification caveat 2026-05-27 17:57:27 -04:00
gsinghpal
95378ff1da fix(billing): skip zero-amount invoices (no lines) — drop empty move, don't post nothing 2026-05-27 17:33:36 -04:00
gsinghpal
c8529b8a99 feat(billing): post + reconcile only PAID invoices, keeping original dates
_post_and_reconcile_paid: for invoices NexaCloud marks paid, set the ledger
entry's invoice_date AND accounting date to the original NexaCloud date,
post, then reconcile the Stripe payment dated to the actual paid_at. Unpaid
invoices stay draft. Per-invoice isolated. 76 tests green on odoo-trial.
2026-05-27 17:29:41 -04:00
gsinghpal
7a66d7849d fix(billing): name ledger partners by company, not the NexaCloud user's full_name
One operator (e.g. "Gurpreet Singh") manages several distinct customer
businesses; naming partners from full_name mislabeled Mobility Specialties
Inc and Apex Vita Corporation as "Gurpreet Singh". Read the company field,
name the partner by company (mark is_company), and rewrite existing partners
so prior full_name-based names are corrected on re-ingest. 75 tests green.
2026-05-27 17:24:48 -04:00
gsinghpal
9ad09c32b0 fix(billing): robust shadow prune (charges before products + archive fallback) 2026-05-27 17:02:43 -04:00
gsinghpal
6b63df8c3d fix(billing): ledger live-run fixes — UUID cast, UTF-8, reconciling line
Surfaced by the nexamain dry-run against real data:
- reader: cast invoice_items.invoice_id::text (uuid = text[] mismatch).
- readers: set_client_encoding('UTF8') — invoice descriptions contain "×".
- ingest: add a balancing line when invoice.subtotal != sum(items). 9 paid
  base-plan invoices store the charge in subtotal with NO invoice_items, so
  itemized ingestion under-recorded revenue by ~$1,143 (37%); the reconciling
  line makes the Odoo invoice total match what Stripe billed.
74 tests green on odoo-trial.
2026-05-27 16:57:00 -04:00
gsinghpal
72d3130c88 feat(billing): NexaCloud invoice ledger — ingest invoices to account.move
Odoo becomes the accounting SoR by ingesting NexaCloud's real Stripe
invoices (read-only via the existing DSN) into native account.move
customer invoices: per-service-family income accounts, tax derived to
match the source invoice.tax, Stripe payments reconciled via
account.payment.register (invoice shows paid), idempotent on
x_fc_nexacloud_invoice_id, draft-first with bulk-post + a daily cron
(inactive). Plus a prune helper for the now-obsolete metered shadow data.
73 tests green on odoo-trial. Account codes use dots (Odoo 19 rejects '-').
2026-05-27 16:50:31 -04:00