Initial commit
This commit is contained in:
127
src/app/api/reports/export/sales/route.ts
Normal file
127
src/app/api/reports/export/sales/route.ts
Normal file
@@ -0,0 +1,127 @@
|
||||
import { NextRequest, NextResponse } from 'next/server'
|
||||
import { db } from '@/lib/db'
|
||||
import { startOfDay, endOfDay, startOfWeek, endOfWeek, startOfMonth, endOfMonth, startOfYear, endOfYear, format } from 'date-fns'
|
||||
|
||||
export async function GET(request: NextRequest) {
|
||||
try {
|
||||
const searchParams = request.nextUrl.searchParams
|
||||
const range = searchParams.get('range') || 'month'
|
||||
|
||||
const now = new Date()
|
||||
let startDate: Date
|
||||
let endDate: Date
|
||||
|
||||
switch (range) {
|
||||
case 'today':
|
||||
startDate = startOfDay(now)
|
||||
endDate = endOfDay(now)
|
||||
break
|
||||
case 'week':
|
||||
startDate = startOfWeek(now, { weekStartsOn: 1 })
|
||||
endDate = endOfWeek(now, { weekStartsOn: 1 })
|
||||
break
|
||||
case 'year':
|
||||
startDate = startOfYear(now)
|
||||
endDate = endOfYear(now)
|
||||
break
|
||||
case 'month':
|
||||
default:
|
||||
startDate = startOfMonth(now)
|
||||
endDate = endOfMonth(now)
|
||||
break
|
||||
}
|
||||
|
||||
// Get sales with details
|
||||
const sales = await db.vente.findMany({
|
||||
where: {
|
||||
date: { gte: startDate, lte: endDate },
|
||||
statut: 'PAYEE'
|
||||
},
|
||||
include: {
|
||||
client: {
|
||||
select: {
|
||||
nom: true,
|
||||
prenom: true
|
||||
}
|
||||
},
|
||||
employe: {
|
||||
select: {
|
||||
nom: true,
|
||||
prenom: true
|
||||
}
|
||||
},
|
||||
lignes: {
|
||||
include: {
|
||||
produit: {
|
||||
select: {
|
||||
reference: true,
|
||||
designation: true,
|
||||
categorie: true
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
paiements: true
|
||||
},
|
||||
orderBy: {
|
||||
date: 'desc'
|
||||
}
|
||||
})
|
||||
|
||||
// Generate CSV content
|
||||
const headers = [
|
||||
'Numéro vente',
|
||||
'Date',
|
||||
'Client',
|
||||
'Employé',
|
||||
'Produits',
|
||||
'Quantité totale',
|
||||
'Montant HT',
|
||||
'Montant TVA',
|
||||
'Montant TTC',
|
||||
'Remise',
|
||||
'Modes de paiement',
|
||||
'Statut atelier'
|
||||
]
|
||||
|
||||
const rows = sales.map((sale) => {
|
||||
const products = sale.lignes.map((l) =>
|
||||
`${l.produit.designation} (${l.produit.categorie})`
|
||||
).join('; ')
|
||||
const quantities = sale.lignes.reduce((sum, l) => sum + l.quantite, 0)
|
||||
const paymentMethods = sale.paiements.map((p) => p.mode).join(', ')
|
||||
const atelierStatus = sale.statutAtelier
|
||||
|
||||
return [
|
||||
sale.numero,
|
||||
format(sale.date, 'dd/MM/yyyy HH:mm'),
|
||||
sale.client ? `${sale.client.prenom} ${sale.client.nom}` : '',
|
||||
sale.employe ? `${sale.employe.prenom} ${sale.employe.nom}` : '',
|
||||
`"${products}"`,
|
||||
quantities.toString(),
|
||||
sale.montantHT.toFixed(2),
|
||||
sale.montantTVA.toFixed(2),
|
||||
sale.montantTTC.toFixed(2),
|
||||
sale.remise.toFixed(2),
|
||||
paymentMethods,
|
||||
atelierStatus
|
||||
].join(',')
|
||||
})
|
||||
|
||||
const csvContent = [headers.join(','), ...rows].join('\n')
|
||||
|
||||
// Return as CSV file
|
||||
return new NextResponse(csvContent, {
|
||||
headers: {
|
||||
'Content-Type': 'text/csv; charset=utf-8',
|
||||
'Content-Disposition': `attachment; filename="ventes_${format(now, 'yyyy-MM-dd')}.csv"`
|
||||
}
|
||||
})
|
||||
} catch (error) {
|
||||
console.error('Error exporting sales data:', error)
|
||||
return NextResponse.json(
|
||||
{ error: 'Failed to export sales data' },
|
||||
{ status: 500 }
|
||||
)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user