feat: fix parsing

This commit is contained in:
2026-01-18 10:33:09 +01:00
parent 6bad5fbaf9
commit ee1db93298
4 changed files with 210 additions and 40 deletions

View File

@@ -128,9 +128,10 @@
>
<div class="space-y-2">
<OperationCard
v-for="(cat, idx) in data.data?.recapitulatif_operations"
v-for="(group, idx) in operationsGroupedByCategory"
:key="idx"
:category="cat"
:categorie="group.categorie"
:operations="group.operations"
/>
</div>
</DataSection>
@@ -140,7 +141,7 @@
</template>
<script setup>
import { ref, reactive } from 'vue'
import { ref, reactive, computed } from 'vue'
import DataSection from './DataSection.vue'
import DataCard from './DataCard.vue'
import DataRow from './DataRow.vue'
@@ -158,6 +159,27 @@ const props = defineProps({
}
})
// Grouper les operations par categorie pour l'affichage
const operationsGroupedByCategory = computed(() => {
const operations = props.data?.data?.recapitulatif_operations
if (!operations || !Array.isArray(operations)) return []
// Grouper par categorie en preservant l'ordre d'apparition
const groups = []
const categoryIndex = {}
for (const op of operations) {
const cat = op.categorie || 'AUTRES'
if (!(cat in categoryIndex)) {
categoryIndex[cat] = groups.length
groups.push({ categorie: cat, operations: [] })
}
groups[categoryIndex[cat]].operations.push(op)
}
return groups
})
const copyLabel = ref('Copier')
const expandedSections = reactive({
metadata: true,

View File

@@ -15,9 +15,9 @@
>
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 5l7 7-7 7" />
</svg>
<span class="font-medium text-gray-800 text-sm">{{ category.categorie }}</span>
<span class="font-medium text-gray-800 text-sm">{{ formatCategorie(categorie) }}</span>
<span class="text-xs bg-gray-100 text-gray-600 px-2 py-0.5 rounded-full">
{{ category.operations?.length || 0 }} operations
{{ operations.length }} operation{{ operations.length > 1 ? 's' : '' }}
</span>
</div>
<div class="text-sm font-semibold text-gray-700">
@@ -29,18 +29,23 @@
<div v-show="expanded" class="border-t border-gray-100 bg-gray-50">
<div class="divide-y divide-gray-100">
<div
v-for="(op, idx) in category.operations"
v-for="(op, idx) in operations"
:key="idx"
class="px-3 py-2 bg-white text-xs"
>
<div class="flex items-start justify-between gap-2">
<div class="flex-1 min-w-0">
<div v-if="op.sous_categorie" class="text-gray-400 text-xs mb-0.5">
{{ op.sous_categorie }}
</div>
<div v-if="op.fournisseur" class="font-medium text-gray-800 truncate">
{{ op.fournisseur }}
</div>
<div class="text-gray-500 truncate">{{ op.description || op.type_operation || '-' }}</div>
<div v-if="op.lot_concerne" class="text-gray-400 text-xs mt-0.5">
Lot: {{ op.lot_concerne }}
<div class="text-gray-500 truncate">{{ op.description || '-' }}</div>
<div v-if="op.lot_numero || op.lot_concerne" class="text-blue-500 text-xs mt-0.5">
<span v-if="op.lot_numero" class="font-medium">Lot {{ op.lot_numero }}</span>
<span v-if="op.lot_numero && op.lot_concerne"> - </span>
<span v-if="op.lot_concerne">{{ op.lot_concerne }}</span>
</div>
</div>
<div class="text-right flex-shrink-0">
@@ -48,10 +53,27 @@
<div v-if="op.montants?.tva" class="text-gray-400">
TVA: {{ formatCurrency(op.montants.tva) }}
</div>
<div v-if="op.montants?.locatif" class="text-green-600 text-xs">
Locatif: {{ formatCurrency(op.montants.locatif) }}
</div>
<div v-if="op.montants?.deductible" class="text-orange-600 text-xs">
Deductible: {{ formatCurrency(op.montants.deductible) }}
</div>
</div>
</div>
</div>
</div>
<!-- Totaux de la categorie -->
<div class="px-3 py-2 bg-gray-100 border-t border-gray-200 text-xs">
<div class="flex justify-between items-center">
<span class="font-medium text-gray-600">Total {{ formatCategorie(categorie) }}</span>
<div class="text-right">
<span class="font-semibold text-gray-800">{{ formatCurrency(totalDebit) }}</span>
<span v-if="totalTva > 0" class="text-gray-500 ml-2">(TVA: {{ formatCurrency(totalTva) }})</span>
</div>
</div>
</div>
</div>
</div>
</template>
@@ -60,8 +82,12 @@
import { ref, computed } from 'vue'
const props = defineProps({
category: {
type: Object,
categorie: {
type: String,
required: true
},
operations: {
type: Array,
required: true
}
})
@@ -69,10 +95,22 @@ const props = defineProps({
const expanded = ref(false)
const totalDebit = computed(() => {
if (!props.category.operations) return 0
return props.category.operations.reduce((sum, op) => sum + (op.montants?.debit || 0), 0)
return props.operations.reduce((sum, op) => sum + (op.montants?.debit || 0), 0)
})
const totalTva = computed(() => {
return props.operations.reduce((sum, op) => sum + (op.montants?.tva || 0), 0)
})
function formatCategorie(cat) {
if (!cat) return '-'
// Convertir DEPENSES_LOCATIVES -> Depenses locatives
return cat
.replace(/_/g, ' ')
.toLowerCase()
.replace(/^\w/, c => c.toUpperCase())
}
function formatCurrency(value) {
if (value === null || value === undefined) return '-'
return new Intl.NumberFormat('fr-FR', { style: 'currency', currency: 'EUR' }).format(value)