Files
erp/.claude/skills/dolibarr-recurring-templates/SKILL.md
Gabriel Radureau f19b1d2ef2 add dolibarr-tva-reconciliation, dolibarr-recurring-templates, dolibarr-data-snapshot
V3 bundle — three sibling skills under .claude/skills/, all read-only,
all depending on the dolibarr base skill.

dolibarr-tva-reconciliation:
- tva-by-month.sh: HT + TVA grouped by (year-month × tva_tx), ready
  for CA3 / CA12 transcription.
- tva-line-detail.sh: per-line audit trail with country-based bucket
  assignment (A1 domestic / A4 intra-UE autoliquidation / E2 export
  hors UE). Documents the French TVA mental model.
- Today every Arcodange line is E2 (KissMetrics, US, autoliquidation
  259-1° CGI). The skill scales for the day a French B2B is invoiced.

dolibarr-recurring-templates:
- list-templates.sh: probes /invoices/templates/{id} since there's no
  list endpoint. Stops after 5 consecutive empty responses.
- inspect-template.sh: full audit per template, with health checks.
- Surfaces that the "Kiss Metrics Invoice" template has frequency=0
  and nb_gen_done=0 — it is NOT auto-firing. Every KM invoice today
  was manually duplicated. Cohort-review implication: the deferred
  9-month cycle depends on Gabriel clicking "Generate" each month,
  not on a Dolibarr cron.

dolibarr-data-snapshot:
- snapshot.sh: bundles every read endpoint the dolibarr-* family uses
  into one JSON with a content_hash (sha256 of data only, excluding
  timestamp — so identical state hashes identically across runs).
- Use cases: cohort evidence packs, drift detection, archival before
  a known-risky UI change.
- V1 baseline summary captured at examples/snapshot-summary.txt
  (the ~246 KB snapshot file itself is intentionally not committed).

Also extends dolibarr/SKILL.md endpoint catalogue with
/invoices/templates/{id} (and its no-list-endpoint quirk + the
id-null sentinel for missing ids), plus links to the three new
sibling skills.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-29 00:01:06 +02:00

91 lines
6.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
name: dolibarr-recurring-templates
description: Inspect Arcodange recurring invoice templates (modèles de factures récurrentes) — the templates that auto-generate monthly invoices for KissMetrics and any future recurring billing. Two workflows — (1) enumerate all templates (the API has no list endpoint, this skill probes ids 1..N and stops after consecutive empties); (2) inspect one template end-to-end (identification, schedule frequency / unit / next-fire / last-fire / counts, customer, payment terms, lines with French legal mentions, child invoices generated from it). Surfaces health issues: `frequency=0` (NOT auto-firing — every child was manually duplicated), `nb_gen_done=0` while children exist (mismatched counter), `date_when` in the past (overdue), `suspended=1` (paused). Use when the user asks "le template KM va-t-il auto-générer la prochaine facture", "quand fire la prochaine M-N", "audit des templates récurrents", "pourquoi la facture n'a pas été émise automatiquement". Depends on the `dolibarr` skill. SKIP for one-off invoice audits (handled by `dolibarr-invoice-audit`), for payment tracking (`dolibarr-payments-state`), for TVA basis (`dolibarr-tva-reconciliation`), or for writing/triggering a template fire (the API is read-only — manual fire goes through the Dolibarr UI).
requires:
bins: ["curl", "jq", "python3"]
auth: true
---
# dolibarr-recurring-templates — modèles de factures récurrentes
Recurring invoice templates are the Dolibarr objects that drive automated monthly (or arbitrary-frequency) billing. This skill answers: **does the template actually fire on schedule? when's the next one? and what does it generate?**
Depends on the [dolibarr](../dolibarr/SKILL.md) base skill.
## API quirks worth knowing
The Dolibarr API exposes templates only via `GET /invoices/templates/{id}` — there's **no list endpoint**. Two consequences:
1. **Enumerating requires probing.** `list-templates.sh` probes `id=1`, then `id=2`, etc., until it hits 5 consecutive empty responses.
2. **"Empty" looks like 200.** A non-existent id returns HTTP **200** with a hollow object (`id=null`, `ref=null`). The script treats `id=null` as the sentinel — Dolibarr returns mostly-null fields for missing templates rather than a clean 404.
(Captured for reference at [../dolibarr/examples/invoice_template_km.json](../dolibarr/examples/invoice_template_km.json).)
## Workflow 1 — Enumerate templates
```bash
./scripts/list-templates.sh # probe 1..50, default
./scripts/list-templates.sh --max-id 200 # raise the upper bound
```
Live output (captured at [examples/list-templates.txt](examples/list-templates.txt)):
```
# Probed ids 1..6, found 1 template(s) (stopped after 5 consecutive empties)
id ref socid freq gen next last sus auto_val total_ht
-------------------------------------------------------------------------------------------------------------------
1 Kiss Metrics Invoice 1 OFF (0) 0/∞ - - 0 0 5100.00000000
```
Columns:
- **freq** — `OFF (0)` if `frequency=0` (no auto-fire). Otherwise `every Nu` (e.g. `every 1m` = monthly).
- **gen** — `nb_gen_done / nb_gen_max`. `∞` means unbounded.
- **next** / **last**`date_when` / `date_last_gen`.
- **sus** — `suspended` flag.
## Workflow 2 — Inspect one template (full audit)
```bash
./scripts/inspect-template.sh 1
echo "exit: $?" # 0 if no health issues, 1 otherwise
```
Live output (captured at [examples/inspect-template-1.txt](examples/inspect-template-1.txt)):
```
================================================================================
Template 1 — Kiss Metrics Invoice
================================================================================
Customer : socid=1
Schedule : frequency=0 m (OFF — manual generation only)
Counts : generated=0 / max=unbounded
Next fire date : (unset)
Last fire date : (none)
Suspended : False
...
Lines:
- ref=KM-cloud-devops qty=10 subprice=510.00000000 tva=0.0000 HT=5100.00000000
TVA non applicable Article 259-1 du CGI Prestation de services localisée hors de France (USA)
Generated children (by note_private match on 'Kiss Metrics Invoice'):
- 2026-02-24 id= 12 FAC002-CL0001002 HT=5100.00000000 paye=1
- 2026-02-24 id= 13 FAC003-CL0001003 HT=2550.00000000 paye=1
Health checks:
[!!] frequency=0 — template is NOT auto-generating; every child was created manually
[!!] nb_gen_done=0 but 2 child invoice(s) match by note — they were duplicated, not auto-generated
```
**The Kiss Metrics Invoice template is OFF.** It exists, it has the right lines and the 259-1° CGI mention, it points at the right bank account (Wise), but its `frequency=0` and `nb_gen_done=0` mean **Dolibarr is not auto-generating M3 / M4 / etc.** Each cohort-month invoice today is a manual duplication from the Dolibarr UI.
**Cohort-review implication:** the deferred 9-month cycle depends on someone (Gabriel) clicking "Generate" each month. If you want it automated, the template's frequency needs to be set to `1m` (monthly), the `date_when` set to the next fire date, and ideally `auto_validate=1`. That's a UI configuration change — not done by this read-only skill.
**Children matching by note_private** is a heuristic: when an invoice is generated from a template, Dolibarr writes `"Généré depuis la facture modèle récurrente <ref>"` to `note_private`. We grep for the template ref in that field. False positives are rare in practice but possible; treat it as a strong signal, not proof.
## Out of scope
- **Triggering a fire.** Manual fire is a UI button; programmatic fire would need `POST /invoices/templates/{id}/createrecurringinvoices` (or similar), which isn't read-only.
- **Changing frequency / auto-validate / suspended.** UI-only from this skill's perspective.
- **Templates for things other than invoices** (recurring quotes, recurring orders) — would be sibling skills.