fix(campaigns/wizard): always show parse summary, even on 0 drops

The previous breakdown only rendered when at least one of the drop
counters was > 0. When the Map CSV cleanly parses every row and the
imbalance comes purely from the Giftbit CSV having more entries than
the Map CSV, the operator was left with "13 surplus gifts" and no
explanation.

The summary now always shows "Map CSV: N raw rows → M contacts paired"
and, when no rows were dropped, explicitly states that the imbalance
must come from the Giftbit side (asks the operator to confirm the
generated gift count matches the Map file).

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
louispaulb 2026-05-22 11:49:30 -04:00
parent 5c55087198
commit 5b5df954c1

View File

@ -220,17 +220,28 @@
il y a plus de cartes-cadeaux que de contacts. Le surplus sera perdu si
la campagne est envoyée tel quel.
</div>
<!-- Parser skip breakdown: tells the operator exactly WHERE the missing
contacts went (no_email = lost forever; duplicate = couple/foyer
de-duped; multi_skip = couple skipped by their multi setting). -->
<div v-if="parseSkipped && (parseSkipped.no_email || parseSkipped.duplicate || parseSkipped.multi_skip)"
class="q-mt-sm text-caption" style="color:#7C3F00">
<q-icon name="info" size="14px" /> Ventilation des contacts droppés au parsing du Map CSV
(sur {{ parseSkipped.total_rows }} lignes brutes) :
<span v-if="parseSkipped.no_email"> <strong>{{ parseSkipped.no_email }}</strong> sans email valide ·</span>
<span v-if="parseSkipped.duplicate"> <strong>{{ parseSkipped.duplicate }}</strong> emails en double (déjà vu plus haut) ·</span>
<span v-if="parseSkipped.multi_skip"> <strong>{{ parseSkipped.multi_skip }}</strong> couples ignorés (selon le réglage "Emails multiples") ·</span>
<span v-if="parseSkipped.no_name"> <strong>{{ parseSkipped.no_name }}</strong> sans nom (gardés, utilisent "cher client" à l'envoi)</span>
<!-- Always-on parse summary: explains the imbalance precisely even
when no Map rows were dropped (= the Giftbit CSV simply had
more entries than the Map CSV upstream). -->
<div v-if="parseSkipped" class="q-mt-sm text-caption" style="color:#7C3F00">
<q-icon name="info" size="14px" />
<strong>Map CSV :</strong> {{ parseSkipped.total_rows }} ligne(s) brute(s)
<strong>{{ recipients.length }} contact(s)</strong> pairé(s) avec un cadeau.
<span v-if="(parseSkipped.no_email + parseSkipped.duplicate + parseSkipped.multi_skip) === 0">
Aucun contact n'a été droppé au parsing — l'imbalance vient probablement du fait
que le CSV Giftbit a {{ unusedGifts.length }} ligne(s) de plus que le CSV Map.
Vérifie que le nombre de cartes-cadeaux générées chez Giftbit correspond bien au
fichier Map utilisé.
</span>
<span v-else>
Ventilation des droppés :
<span v-if="parseSkipped.no_email"> <strong>{{ parseSkipped.no_email }}</strong> sans email valide</span><span v-if="parseSkipped.no_email && (parseSkipped.duplicate || parseSkipped.multi_skip)"> ·</span>
<span v-if="parseSkipped.duplicate"> <strong>{{ parseSkipped.duplicate }}</strong> emails en double</span><span v-if="parseSkipped.duplicate && parseSkipped.multi_skip"> ·</span>
<span v-if="parseSkipped.multi_skip"> <strong>{{ parseSkipped.multi_skip }}</strong> couples ignorés (réglage "Emails multiples")</span>.
</span>
<span v-if="parseSkipped.no_name">
({{ parseSkipped.no_name }} ligne(s) sans nom ont été <em>gardées</em> et utiliseront "cher client" à l'envoi.)
</span>
</div>
</q-banner>