'use client'; export const dynamic = 'force-dynamic'; import React, { useState, useEffect, useRef } from 'react'; import { useParams, useRouter } from 'next/navigation'; import { Card } from 'primereact/card'; import { Button } from 'primereact/button'; import { InputText } from 'primereact/inputtext'; import { InputTextarea } from 'primereact/inputtextarea'; import { Dropdown } from 'primereact/dropdown'; import { Calendar } from 'primereact/calendar'; import { DataTable } from 'primereact/datatable'; import { Column } from 'primereact/column'; import { Toast } from 'primereact/toast'; import { ProgressSpinner } from 'primereact/progressspinner'; import { Toolbar } from 'primereact/toolbar'; import { Divider } from 'primereact/divider'; import { Checkbox } from 'primereact/checkbox'; import { factureService, clientService } from '../../../../../services/api'; import { formatCurrency } from '../../../../../utils/formatters'; import type { Facture, Client } from '../../../../../types/btp'; import { StatutFacture, TypeFacture } from '../../../../../types/btp'; const FactureDuplicatePage = () => { const params = useParams(); const router = useRouter(); const toast = useRef(null); const [originalFacture, setOriginalFacture] = useState(null); const [newFacture, setNewFacture] = useState>({ numero: '', objet: '', description: '', typeFacture: TypeFacture.FACTURE, statut: StatutFacture.BROUILLON, dateEmission: new Date().toISOString(), dateEcheance: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString(), // +30 jours tauxTVA: 20, lignes: [] }); const [clients, setClients] = useState([]); const [loading, setLoading] = useState(true); const [saving, setSaving] = useState(false); const [copyLignes, setCopyLignes] = useState(true); const [copyClient, setCopyClient] = useState(true); const factureId = params.id as string; const typeOptions = [ { label: 'Facture', value: 'FACTURE' }, { label: 'Acompte', value: 'ACOMPTE' }, { label: 'Facture de situation', value: 'SITUATION' }, { label: 'Facture de solde', value: 'SOLDE' } ]; useEffect(() => { loadData(); }, [factureId]); useEffect(() => { if (originalFacture) { updateNewFacture(); } }, [originalFacture, copyLignes, copyClient]); const loadData = async () => { try { setLoading(true); // Charger la facture originale const factureResponse = await factureService.getById(factureId); setOriginalFacture(factureResponse); // Charger les clients const clientsResponse = await clientService.getAll(); setClients(clientsResponse); // Générer un nouveau numéro basé sur la date const now = new Date(); const numero = `FAC-${now.getFullYear()}${String(now.getMonth() + 1).padStart(2, '0')}${String(now.getDate()).padStart(2, '0')}-${String(Math.floor(Math.random() * 10000)).padStart(4, '0')}`; setNewFacture(prev => ({ ...prev, numero })); } catch (error) { console.error('Erreur lors du chargement:', error); toast.current?.show({ severity: 'error', summary: 'Erreur', detail: 'Impossible de charger la facture' }); } finally { setLoading(false); } }; const updateNewFacture = () => { if (!originalFacture) return; setNewFacture(prev => ({ ...prev, objet: `${originalFacture.objet} (Copie)`, description: originalFacture.description, typeFacture: originalFacture.typeFacture, tauxTVA: originalFacture.tauxTVA, client: copyClient ? originalFacture.client : undefined, lignes: copyLignes ? [...(originalFacture.lignes || [])] : [], montantHT: copyLignes ? originalFacture.montantHT : 0, montantTTC: copyLignes ? originalFacture.montantTTC : 0 })); }; const handleSave = async () => { try { setSaving(true); if (!newFacture.numero || !newFacture.objet || !newFacture.client) { toast.current?.show({ severity: 'warn', summary: 'Attention', detail: 'Veuillez remplir tous les champs obligatoires' }); return; } await factureService.create(newFacture); toast.current?.show({ severity: 'success', summary: 'Succès', detail: 'Facture dupliquée avec succès' }); router.push('/factures'); } catch (error) { console.error('Erreur lors de la duplication:', error); toast.current?.show({ severity: 'error', summary: 'Erreur', detail: 'Erreur lors de la duplication' }); } finally { setSaving(false); } }; const toolbarStartTemplate = () => (
); const toolbarEndTemplate = () => (
); if (loading) { return (
); } if (!originalFacture) { return (

Facture introuvable

La facture à dupliquer n'existe pas

); } return (
{/* Options de duplication */}
Options de duplication
setCopyClient(e.checked || false)} />
setCopyLignes(e.checked || false)} />
{/* Comparaison côte à côte */}
Numéro: {originalFacture.numero}
Objet: {originalFacture.objet}
Type: {originalFacture.typeFacture}
Client: {typeof originalFacture.client === 'string' ? originalFacture.client : originalFacture.client?.nom}
Montant TTC: {formatCurrency(originalFacture.montantTTC)}
Nombre de lignes: {originalFacture.lignes?.length || 0}
{originalFacture.description && (
Description:

{originalFacture.description}

)}
setNewFacture(prev => ({ ...prev, numero: e.target.value }))} className="w-full" />
setNewFacture(prev => ({ ...prev, objet: e.target.value }))} className="w-full" />
setNewFacture(prev => ({ ...prev, typeFacture: e.value }))} className="w-full" />
({ label: client.nom, value: client }))} onChange={(e) => setNewFacture(prev => ({ ...prev, client: e.value }))} className="w-full" placeholder="Sélectionner un client" filter />
setNewFacture(prev => ({ ...prev, dateEmission: (e.value as Date)?.toISOString() || new Date().toISOString() }))} className="w-full" dateFormat="dd/mm/yy" />
setNewFacture(prev => ({ ...prev, dateEcheance: (e.value as Date)?.toISOString() || new Date().toISOString() }))} className="w-full" dateFormat="dd/mm/yy" />
setNewFacture(prev => ({ ...prev, description: e.target.value }))} className="w-full" rows={3} />
{/* Aperçu des lignes copiées */} {copyLignes && newFacture.lignes && newFacture.lignes.length > 0 && (
rowData.quantite?.toLocaleString('fr-FR')} /> formatCurrency(rowData.prixUnitaire)} /> formatCurrency(rowData.montantHT)} />
Montant HT: {formatCurrency(newFacture.montantHT || 0)}
TVA ({newFacture.tauxTVA}%): {formatCurrency(((newFacture.montantHT || 0) * (newFacture.tauxTVA || 0)) / 100)}
Montant TTC: {formatCurrency(newFacture.montantTTC || 0)}
)} {/* Résumé de la duplication */}
Informations copiées
  • • Objet (modifié)
  • • Type de facture
  • • Taux de TVA
  • • Description
  • {copyClient &&
  • • Client
  • } {copyLignes &&
  • • Lignes de facturation
  • }
Nouvelles valeurs
  • • Nouveau numéro généré
  • • Statut: Brouillon
  • • Date d'émission: Aujourd'hui
  • • Date d'échéance: +30 jours
  • • Montants payés: Remis à zéro
À vérifier
  • • Objet de la facture
  • • Client sélectionné
  • • Dates d'émission et d'échéance
  • • Lignes de facturation
  • • Montants calculés
); }; export default FactureDuplicatePage;