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>
91 lines
6.0 KiB
Markdown
91 lines
6.0 KiB
Markdown
---
|
||
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.
|