feat: extraction locataires et opérations par cellules de tableau
Remplace les parseurs texte+regex (fragiles sur l'alignement en colonnes des PDF Oralia mal construits) par une extraction géométrique : reconstruction des lignes visuelles par regroupement vertical tolérant des mots, puis affectation de chaque valeur à sa colonne via les filets du tableau (pdfplumber find_tables). Corrections apportées : - locataires : montant/libellé « divers » dans la bonne colonne (plus le total cumulé du lot), nom de locataire correct (le logo/en-tête hors filets est ignoré), lignes multi-période et pages recollées. - opérations : fournisseur séparé de la description (TOTALENERGIES ≠ DIDIER NETTOYAGE, PPR ≠ BOUVARD), colonne Déductible remplie, Débit/Crédit distingués, fournisseur des honoraires reporté sur le bloc, fragments de description recollés (LATAPY, AUDOUIN). - code lot : gère « S10 - », « S 17 - » (espace) et « S01 SOLDE » (sans tiret). Branchés dans extractor.py avec repli sur les anciens parseurs si un tableau n'a pas de filets détectables. Validés par réconciliation comptable : locataires 124/124 lots, opérations 7/7 PDF et 25/25 catégories, au centime. Ajoute le bouton « Relancer l'extraction » dans l'écran d'édition : re-extrait depuis le PDF stocké et met en évidence les différences avec la version précédente (panneau récapitulatif + anneaux « modifié » sur les cartes). Le diff des opérations s'aligne par contenu (robuste aux changements d'ordre/nombre). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -116,6 +116,7 @@
|
||||
:locataire="loc"
|
||||
:index="idx"
|
||||
:highlighted="highlightedLocataireIndex === idx"
|
||||
:changed="changedLocataireSet.has(idx)"
|
||||
@update:locataire="updateLocataire(idx, $event)"
|
||||
@remove="removeLocataire(idx)"
|
||||
/>
|
||||
@@ -147,6 +148,7 @@
|
||||
:categorie="group.categorie"
|
||||
:operations="group.operations"
|
||||
:highlightIndex="group.categorie === highlightOperationCategorie ? highlightOperationIndex : -1"
|
||||
:changedIndices="changedOpByCategorie[group.categorie] || []"
|
||||
@update:operations="updateOperationsGroup(group.categorie, $event)"
|
||||
/>
|
||||
|
||||
@@ -187,6 +189,10 @@ const props = defineProps({
|
||||
highlight: {
|
||||
type: Object,
|
||||
default: null
|
||||
},
|
||||
diff: {
|
||||
type: Object,
|
||||
default: null
|
||||
}
|
||||
})
|
||||
|
||||
@@ -213,6 +219,30 @@ const operationsGroupedByCategory = computed(() => {
|
||||
return groups
|
||||
})
|
||||
|
||||
// Indices de locataires modifiés par la re-extraction (anneau « modifié »).
|
||||
const changedLocataireSet = computed(
|
||||
() => new Set(props.diff?.changedLocataireIndices || [])
|
||||
)
|
||||
|
||||
// Indices d'opérations modifiées, ramenés au repère (catégorie, index dans le groupe).
|
||||
const changedOpByCategorie = computed(() => {
|
||||
const result = {}
|
||||
const operations = props.data?.data?.recapitulatif_operations
|
||||
const changed = new Set(props.diff?.changedOperationIndices || [])
|
||||
if (!operations || !changed.size) return result
|
||||
const counters = {}
|
||||
operations.forEach((op, absIdx) => {
|
||||
const cat = op.categorie || 'AUTRES'
|
||||
if (!(cat in counters)) counters[cat] = 0
|
||||
if (changed.has(absIdx)) {
|
||||
if (!result[cat]) result[cat] = []
|
||||
result[cat].push(counters[cat])
|
||||
}
|
||||
counters[cat]++
|
||||
})
|
||||
return result
|
||||
})
|
||||
|
||||
const copyLabel = ref('Copier')
|
||||
const expandedSections = reactive({
|
||||
metadata: true,
|
||||
@@ -269,6 +299,17 @@ watch(
|
||||
{ immediate: true }
|
||||
)
|
||||
|
||||
// Déplier automatiquement les sections qui contiennent des différences.
|
||||
watch(
|
||||
() => props.diff,
|
||||
(diff) => {
|
||||
if (!diff) return
|
||||
if (diff.summary?.metadata) expandedSections.metadata = true
|
||||
if (diff.summary?.locataires) expandedSections.locataires = true
|
||||
if (diff.summary?.operations) expandedSections.operations = true
|
||||
}
|
||||
)
|
||||
|
||||
function toggleSection(section) {
|
||||
expandedSections[section] = !expandedSections[section]
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user