255 lines
7.0 KiB
Go
255 lines
7.0 KiB
Go
// internal/services/export_service.go
|
|
package services
|
|
|
|
import (
|
|
"bytes"
|
|
"fmt"
|
|
"lost-and-found/internal/models"
|
|
"lost-and-found/internal/repositories"
|
|
"lost-and-found/internal/utils"
|
|
"time"
|
|
|
|
"gorm.io/gorm"
|
|
)
|
|
|
|
type ExportService struct {
|
|
itemRepo *repositories.ItemRepository
|
|
archiveRepo *repositories.ArchiveRepository
|
|
claimRepo *repositories.ClaimRepository
|
|
auditLogRepo *repositories.AuditLogRepository
|
|
}
|
|
|
|
func NewExportService(db *gorm.DB) *ExportService {
|
|
return &ExportService{
|
|
itemRepo: repositories.NewItemRepository(db),
|
|
archiveRepo: repositories.NewArchiveRepository(db),
|
|
claimRepo: repositories.NewClaimRepository(db),
|
|
auditLogRepo: repositories.NewAuditLogRepository(db),
|
|
}
|
|
}
|
|
|
|
// ExportRequest represents export request data
|
|
type ExportRequest struct {
|
|
Type string `json:"type"` // items, archives, claims, audit_logs
|
|
Format string `json:"format"` // pdf, excel
|
|
StartDate *time.Time `json:"start_date"`
|
|
EndDate *time.Time `json:"end_date"`
|
|
Status string `json:"status"`
|
|
}
|
|
|
|
// ExportItemsToPDF exports items to PDF
|
|
func (s *ExportService) ExportItemsToPDF(req ExportRequest, userID uint, ipAddress, userAgent string) (*bytes.Buffer, error) {
|
|
// Get items
|
|
items, _, err := s.itemRepo.FindAll(1, 10000, req.Status, "", "")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Filter by date range if provided
|
|
var filteredItems []models.Item
|
|
for _, item := range items {
|
|
if req.StartDate != nil && item.DateFound.Before(*req.StartDate) {
|
|
continue
|
|
}
|
|
if req.EndDate != nil && item.DateFound.After(*req.EndDate) {
|
|
continue
|
|
}
|
|
filteredItems = append(filteredItems, item)
|
|
}
|
|
|
|
// Generate PDF
|
|
pdf := utils.NewPDFExporter()
|
|
pdf.AddTitle("Laporan Barang Ditemukan")
|
|
pdf.AddSubtitle(fmt.Sprintf("Periode: %s - %s",
|
|
formatDate(req.StartDate),
|
|
formatDate(req.EndDate)))
|
|
pdf.AddNewLine()
|
|
|
|
// Add table
|
|
headers := []string{"No", "Nama Barang", "Kategori", "Lokasi", "Tanggal Ditemukan", "Status"}
|
|
var data [][]string
|
|
for i, item := range filteredItems {
|
|
data = append(data, []string{
|
|
fmt.Sprintf("%d", i+1),
|
|
item.Name,
|
|
item.Category.Name,
|
|
item.Location,
|
|
item.DateFound.Format("02 Jan 2006"),
|
|
item.Status,
|
|
})
|
|
}
|
|
pdf.AddTable(headers, data)
|
|
|
|
// Add footer
|
|
pdf.AddNewLine()
|
|
pdf.AddText(fmt.Sprintf("Total: %d barang", len(filteredItems)))
|
|
pdf.AddText(fmt.Sprintf("Dicetak pada: %s", time.Now().Format("02 January 2006 15:04")))
|
|
|
|
// Log audit
|
|
s.auditLogRepo.Log(&userID, models.ActionExport, "report", nil,
|
|
fmt.Sprintf("Exported items report (PDF, %d items)", len(filteredItems)),
|
|
ipAddress, userAgent)
|
|
|
|
return pdf.Output(), nil
|
|
}
|
|
|
|
// ExportItemsToExcel exports items to Excel
|
|
func (s *ExportService) ExportItemsToExcel(req ExportRequest, userID uint, ipAddress, userAgent string) (*bytes.Buffer, error) {
|
|
// Get items
|
|
items, _, err := s.itemRepo.FindAll(1, 10000, req.Status, "", "")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Filter by date range if provided
|
|
var filteredItems []models.Item
|
|
for _, item := range items {
|
|
if req.StartDate != nil && item.DateFound.Before(*req.StartDate) {
|
|
continue
|
|
}
|
|
if req.EndDate != nil && item.DateFound.After(*req.EndDate) {
|
|
continue
|
|
}
|
|
filteredItems = append(filteredItems, item)
|
|
}
|
|
|
|
// Generate Excel
|
|
excel := utils.NewExcelExporter()
|
|
excel.SetSheetName("Barang Ditemukan")
|
|
|
|
// Add headers
|
|
headers := []string{"No", "Nama Barang", "Kategori", "Lokasi", "Deskripsi",
|
|
"Tanggal Ditemukan", "Status", "Pelapor", "Kontak"}
|
|
excel.AddRow(headers)
|
|
|
|
// Add data
|
|
for i, item := range filteredItems {
|
|
excel.AddRow([]string{
|
|
fmt.Sprintf("%d", i+1),
|
|
item.Name,
|
|
item.Category.Name,
|
|
item.Location,
|
|
item.Description,
|
|
item.DateFound.Format("02 Jan 2006"),
|
|
item.Status,
|
|
item.ReporterName,
|
|
item.ReporterContact,
|
|
})
|
|
}
|
|
|
|
// Auto-size columns
|
|
excel.AutoSizeColumns(len(headers))
|
|
|
|
// Log audit
|
|
s.auditLogRepo.Log(&userID, models.ActionExport, "report", nil,
|
|
fmt.Sprintf("Exported items report (Excel, %d items)", len(filteredItems)),
|
|
ipAddress, userAgent)
|
|
|
|
return excel.Output()
|
|
}
|
|
|
|
// ExportArchivesToPDF exports archives to PDF
|
|
func (s *ExportService) ExportArchivesToPDF(req ExportRequest, userID uint, ipAddress, userAgent string) (*bytes.Buffer, error) {
|
|
archives, _, err := s.archiveRepo.FindAll(1, 10000, "", "")
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Filter by date range
|
|
var filteredArchives []models.Archive
|
|
for _, archive := range archives {
|
|
if req.StartDate != nil && archive.ArchivedAt.Before(*req.StartDate) {
|
|
continue
|
|
}
|
|
if req.EndDate != nil && archive.ArchivedAt.After(*req.EndDate) {
|
|
continue
|
|
}
|
|
filteredArchives = append(filteredArchives, archive)
|
|
}
|
|
|
|
pdf := utils.NewPDFExporter()
|
|
pdf.AddTitle("Laporan Barang yang Diarsipkan")
|
|
pdf.AddSubtitle(fmt.Sprintf("Periode: %s - %s",
|
|
formatDate(req.StartDate),
|
|
formatDate(req.EndDate)))
|
|
pdf.AddNewLine()
|
|
|
|
headers := []string{"No", "Nama Barang", "Kategori", "Alasan Arsip", "Tanggal Arsip"}
|
|
var data [][]string
|
|
for i, archive := range filteredArchives {
|
|
data = append(data, []string{
|
|
fmt.Sprintf("%d", i+1),
|
|
archive.Name,
|
|
archive.Category.Name,
|
|
archive.ArchivedReason,
|
|
archive.ArchivedAt.Format("02 Jan 2006"),
|
|
})
|
|
}
|
|
pdf.AddTable(headers, data)
|
|
|
|
pdf.AddNewLine()
|
|
pdf.AddText(fmt.Sprintf("Total: %d barang", len(filteredArchives)))
|
|
|
|
s.auditLogRepo.Log(&userID, models.ActionExport, "report", nil,
|
|
fmt.Sprintf("Exported archives report (PDF, %d items)", len(filteredArchives)),
|
|
ipAddress, userAgent)
|
|
|
|
return pdf.Output(), nil
|
|
}
|
|
|
|
// ExportClaimsToPDF exports claims to PDF
|
|
func (s *ExportService) ExportClaimsToPDF(req ExportRequest, userID uint, ipAddress, userAgent string) (*bytes.Buffer, error) {
|
|
claims, _, err := s.claimRepo.FindAll(1, 10000, req.Status, nil, nil)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
// Filter by date range
|
|
var filteredClaims []models.Claim
|
|
for _, claim := range claims {
|
|
if req.StartDate != nil && claim.CreatedAt.Before(*req.StartDate) {
|
|
continue
|
|
}
|
|
if req.EndDate != nil && claim.CreatedAt.After(*req.EndDate) {
|
|
continue
|
|
}
|
|
filteredClaims = append(filteredClaims, claim)
|
|
}
|
|
|
|
pdf := utils.NewPDFExporter()
|
|
pdf.AddTitle("Laporan Klaim Barang")
|
|
pdf.AddSubtitle(fmt.Sprintf("Periode: %s - %s",
|
|
formatDate(req.StartDate),
|
|
formatDate(req.EndDate)))
|
|
pdf.AddNewLine()
|
|
|
|
headers := []string{"No", "Barang", "Pengklaim", "Status", "Tanggal Klaim"}
|
|
var data [][]string
|
|
for i, claim := range filteredClaims {
|
|
data = append(data, []string{
|
|
fmt.Sprintf("%d", i+1),
|
|
claim.Item.Name,
|
|
claim.User.Name,
|
|
claim.Status,
|
|
claim.CreatedAt.Format("02 Jan 2006"),
|
|
})
|
|
}
|
|
pdf.AddTable(headers, data)
|
|
|
|
pdf.AddNewLine()
|
|
pdf.AddText(fmt.Sprintf("Total: %d klaim", len(filteredClaims)))
|
|
|
|
s.auditLogRepo.Log(&userID, models.ActionExport, "report", nil,
|
|
fmt.Sprintf("Exported claims report (PDF, %d claims)", len(filteredClaims)),
|
|
ipAddress, userAgent)
|
|
|
|
return pdf.Output(), nil
|
|
}
|
|
|
|
// Helper function to format date
|
|
func formatDate(date *time.Time) string {
|
|
if date == nil {
|
|
return "N/A"
|
|
}
|
|
return date.Format("02 Jan 2006")
|
|
} |