facturation: correction
This commit is contained in:
+1
-1
@@ -4,7 +4,7 @@
|
|||||||
<meta charset="UTF-8" />
|
<meta charset="UTF-8" />
|
||||||
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>GISE Nexus | Portail d'Infrastructure Centralisée</title>
|
<title>NEXUS by gise | Portail d'Infrastructure Centralisée</title>
|
||||||
<meta name="description" content="Accédez au portail GISE Nexus. Pilotez votre hébergement web, vos instances serveurs et votre stockage Cloud depuis une console unifiée.">
|
<meta name="description" content="Accédez au portail GISE Nexus. Pilotez votre hébergement web, vos instances serveurs et votre stockage Cloud depuis une console unifiée.">
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ export default function BillingHistory() {
|
|||||||
const [error, setError] = useState(null);
|
const [error, setError] = useState(null);
|
||||||
const [customAlert, setCustomAlert] = useState(null);
|
const [customAlert, setCustomAlert] = useState(null);
|
||||||
|
|
||||||
// 🎯 NOUVEL ÉTAT : La facture actuellement ouverte dans la modale
|
// NOUVEL ÉTAT : La facture actuellement ouverte dans la modale
|
||||||
const [selectedInvoice, setSelectedInvoice] = useState(null);
|
const [selectedInvoice, setSelectedInvoice] = useState(null);
|
||||||
|
|
||||||
const triggerAlert = (title, message, type) => {
|
const triggerAlert = (title, message, type) => {
|
||||||
@@ -26,7 +26,6 @@ export default function BillingHistory() {
|
|||||||
throw new Error("Impossible de vérifier votre identité ou session expirée.");
|
throw new Error("Impossible de vérifier votre identité ou session expirée.");
|
||||||
}
|
}
|
||||||
const invoicesData = await getInvoicesHistory(profileData.id);
|
const invoicesData = await getInvoicesHistory(profileData.id);
|
||||||
// On s'assure de bien cibler le tableau (correction précédente)
|
|
||||||
setInvoices(invoicesData.data || []);
|
setInvoices(invoicesData.data || []);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
setError(err.message || "Problème de connexion avec le serveur.");
|
setError(err.message || "Problème de connexion avec le serveur.");
|
||||||
@@ -43,12 +42,14 @@ export default function BillingHistory() {
|
|||||||
|
|
||||||
switch (status?.toLowerCase()) {
|
switch (status?.toLowerCase()) {
|
||||||
case 'paid':
|
case 'paid':
|
||||||
|
if (isNegative) {
|
||||||
|
return { label: 'REMBOURSÉE', css: 'bg-blue-500/10 text-blue-400 border-blue-500/20', icon: <RefreshCcw className="w-3.5 h-3.5" /> };
|
||||||
|
}
|
||||||
return { label: 'PAYÉE', css: 'bg-emerald-500/10 text-emerald-400 border-emerald-500/20', icon: <CheckCircle2 className="w-3.5 h-3.5" /> };
|
return { label: 'PAYÉE', css: 'bg-emerald-500/10 text-emerald-400 border-emerald-500/20', icon: <CheckCircle2 className="w-3.5 h-3.5" /> };
|
||||||
case 'refunded':
|
case 'refunded':
|
||||||
// 🎯 NOUVEAU STATUT : REMBOURSÉE
|
// NOUVEAU STATUT : REMBOURSÉE
|
||||||
return { label: 'REMBOURSÉE', css: 'bg-blue-500/10 text-blue-400 border-blue-500/20', icon: <RefreshCcw className="w-3.5 h-3.5" /> };
|
|
||||||
case 'unpaid':
|
case 'unpaid':
|
||||||
// 🎯 SI IMPAYÉE MAIS NÉGATIVE = EN COURS DE TRAITEMENT
|
// SI IMPAYÉE MAIS NÉGATIVE = EN COURS DE TRAITEMENT
|
||||||
if (isNegative) {
|
if (isNegative) {
|
||||||
return { label: 'REMBOURSEMENT EN COURS', css: 'bg-amber-500/10 text-amber-400 border-amber-500/20', icon: <Clock className="w-3.5 h-3.5" /> };
|
return { label: 'REMBOURSEMENT EN COURS', css: 'bg-amber-500/10 text-amber-400 border-amber-500/20', icon: <Clock className="w-3.5 h-3.5" /> };
|
||||||
}
|
}
|
||||||
@@ -118,7 +119,7 @@ export default function BillingHistory() {
|
|||||||
</thead>
|
</thead>
|
||||||
<tbody className="divide-y divide-gray-800/40 text-sm">
|
<tbody className="divide-y divide-gray-800/40 text-sm">
|
||||||
{invoices.map((invoice) => {
|
{invoices.map((invoice) => {
|
||||||
const badge = getStatusBadge(invoice.status);
|
const badge = getStatusBadge(invoice.status, invoice.total);
|
||||||
return (
|
return (
|
||||||
<tr key={invoice.id} className="hover:bg-gray-800/20 transition-colors">
|
<tr key={invoice.id} className="hover:bg-gray-800/20 transition-colors">
|
||||||
<td className="py-5 px-6 font-mono text-xs font-bold text-gray-300">
|
<td className="py-5 px-6 font-mono text-xs font-bold text-gray-300">
|
||||||
@@ -168,8 +169,7 @@ export default function BillingHistory() {
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
{/* ========================================== */}
|
{/* ========================================== */}
|
||||||
{/* 🌟 LA MODALE DE DÉTAILS DE FACTURE */}
|
{/* LA MODALE DE DÉTAILS DE FACTURE */}
|
||||||
{/* ========================================== */}
|
|
||||||
{selectedInvoice && (
|
{selectedInvoice && (
|
||||||
<div className="fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/80 backdrop-blur-sm">
|
<div className="fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/80 backdrop-blur-sm">
|
||||||
<div className="bg-[#090f1c] border border-gray-800 shadow-2xl shadow-cyan-500/10 rounded-2xl w-full max-w-2xl flex flex-col max-h-[90vh] overflow-hidden">
|
<div className="bg-[#090f1c] border border-gray-800 shadow-2xl shadow-cyan-500/10 rounded-2xl w-full max-w-2xl flex flex-col max-h-[90vh] overflow-hidden">
|
||||||
@@ -211,7 +211,7 @@ export default function BillingHistory() {
|
|||||||
<h4 className="text-xs font-bold text-gray-500 uppercase tracking-widest mb-3 border-b border-gray-800 pb-2">Détail des prestations</h4>
|
<h4 className="text-xs font-bold text-gray-500 uppercase tracking-widest mb-3 border-b border-gray-800 pb-2">Détail des prestations</h4>
|
||||||
<div className="space-y-4">
|
<div className="space-y-4">
|
||||||
{(() => {
|
{(() => {
|
||||||
// 🎯 FILTRE : On ne garde que les items dont le prix est strictement supérieur à 0
|
// FILTRE : On ne garde que les items dont le prix est strictement supérieur à 0
|
||||||
const validItems = selectedInvoice.items
|
const validItems = selectedInvoice.items
|
||||||
? selectedInvoice.items.filter(item => parseFloat(item.price) > 0)
|
? selectedInvoice.items.filter(item => parseFloat(item.price) > 0)
|
||||||
: [];
|
: [];
|
||||||
@@ -246,7 +246,7 @@ export default function BillingHistory() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* 🧠 CALCULS MATHÉMATIQUES (EXTRACTION TVA DEPUIS LE TTC) */}
|
{/* CALCULS (EXTRACTION TVA DEPUIS LE TTC) */}
|
||||||
{(() => {
|
{(() => {
|
||||||
// Le total récupéré de la BDD est considéré comme le PRIX FINAL (TTC)
|
// Le total récupéré de la BDD est considéré comme le PRIX FINAL (TTC)
|
||||||
const totalTTC = parseFloat(selectedInvoice.total) || 0;
|
const totalTTC = parseFloat(selectedInvoice.total) || 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user