package dto import ( "time" entity "gitlab.com/mbugroup/lti-api.git/internal/entities" approvalDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/approvals/dto" kandangDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/kandangs/dto" nonstockDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/nonstocks/dto" supplierDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/suppliers/dto" ) // === DTO Structs === type RepportExpenseBaseDTO struct { Id uint64 `json:"id"` ReferenceNumber string `json:"reference_number"` PoNumber string `json:"po_number"` Category string `json:"category"` Supplier *supplierDTO.SupplierRelationDTO `json:"supplier,omitempty"` RealizationDate *time.Time `json:"realization_date,omitempty"` TransactionDate time.Time `json:"transaction_date"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` } type RepportExpensePengajuanDTO struct { Id uint64 `json:"id"` ExpenseId *uint64 `json:"expense_id,omitempty"` ProjectFlockKandangId *uint64 `json:"project_flock_kandang_id,omitempty"` Qty float64 `json:"qty"` Price float64 `json:"price"` Notes string `json:"notes"` Nonstock *nonstockDTO.NonstockRelationDTO `json:"nonstock,omitempty"` CreatedAt time.Time `json:"created_at"` } type RepportExpenseRealisasiDTO struct { Id *uint64 `json:"id,omitempty"` ExpenseNonstockId *uint64 `json:"expense_nonstock_id,omitempty"` Qty float64 `json:"qty"` Price float64 `json:"price"` Notes string `json:"notes"` Nonstock *nonstockDTO.NonstockRelationDTO `json:"nonstock,omitempty"` CreatedAt time.Time `json:"created_at"` } type RepportExpenseListDTO struct { RepportExpenseBaseDTO Kandang *kandangDTO.KandangRelationDTO `json:"kandang,omitempty"` Pengajuan RepportExpensePengajuanDTO `json:"pengajuan"` Realisasi RepportExpenseRealisasiDTO `json:"realisasi"` TotalPengajuan float64 `json:"total_pengajuan"` TotalRealisasi float64 `json:"total_realisasi"` LatestApproval *approvalDTO.ApprovalRelationDTO `json:"latest_approval,omitempty"` } // === MAPPERS === func ToRepportExpenseBaseDTO(e *entity.Expense) RepportExpenseBaseDTO { var realizationDate *time.Time if !e.RealizationDate.IsZero() { realizationDate = &e.RealizationDate } var supplier *supplierDTO.SupplierRelationDTO if e.Supplier != nil && e.Supplier.Id != 0 { mapped := supplierDTO.ToSupplierRelationDTO(*e.Supplier) supplier = &mapped } return RepportExpenseBaseDTO{ Id: e.Id, ReferenceNumber: e.ReferenceNumber, PoNumber: e.PoNumber, Category: e.Category, Supplier: supplier, RealizationDate: realizationDate, TransactionDate: e.TransactionDate, CreatedAt: e.CreatedAt, UpdatedAt: e.UpdatedAt, } } func ToRepportExpensePengajuanDTO(ns *entity.ExpenseNonstock) RepportExpensePengajuanDTO { var nonstock *nonstockDTO.NonstockRelationDTO if ns.Nonstock != nil && ns.Nonstock.Id != 0 { mapped := nonstockDTO.ToNonstockRelationDTO(*ns.Nonstock) nonstock = &mapped } return RepportExpensePengajuanDTO{ Id: ns.Id, ExpenseId: ns.ExpenseId, ProjectFlockKandangId: ns.ProjectFlockKandangId, Qty: ns.Qty, Price: ns.Price, Notes: ns.Notes, Nonstock: nonstock, CreatedAt: ns.CreatedAt, } } func ToRepportExpenseRealisasiDTO(r *entity.ExpenseRealization) RepportExpenseRealisasiDTO { var nonstock *nonstockDTO.NonstockRelationDTO if r.ExpenseNonstock != nil && r.ExpenseNonstock.Nonstock != nil && r.ExpenseNonstock.Nonstock.Id != 0 { mapped := nonstockDTO.ToNonstockRelationDTO(*r.ExpenseNonstock.Nonstock) nonstock = &mapped } return RepportExpenseRealisasiDTO{ Id: r.ExpenseNonstockId, ExpenseNonstockId: r.ExpenseNonstockId, Qty: r.Qty, Price: r.Price, Notes: r.Notes, Nonstock: nonstock, CreatedAt: r.CreatedAt, } } func ToRepportExpenseListDTO(baseDTO RepportExpenseBaseDTO, ns *entity.ExpenseNonstock, latestApproval *approvalDTO.ApprovalRelationDTO) RepportExpenseListDTO { var realisasi RepportExpenseRealisasiDTO if ns.Realization != nil { realisasi = ToRepportExpenseRealisasiDTO(ns.Realization) } totalPengajuan := ns.Qty * ns.Price totalRealisasi := float64(0) if ns.Realization != nil { totalRealisasi = ns.Realization.Qty * ns.Realization.Price } // Get kandang data at the main level var kandang *kandangDTO.KandangRelationDTO if ns.Kandang != nil && ns.Kandang.Id != 0 { mapped := kandangDTO.ToKandangRelationDTO(*ns.Kandang) kandang = &mapped } return RepportExpenseListDTO{ RepportExpenseBaseDTO: baseDTO, Kandang: kandang, Pengajuan: ToRepportExpensePengajuanDTO(ns), Realisasi: realisasi, TotalPengajuan: totalPengajuan, TotalRealisasi: totalRealisasi, LatestApproval: latestApproval, } } func ToRepportExpenseListDTOs(realizations []entity.ExpenseRealization) []RepportExpenseListDTO { result := make([]RepportExpenseListDTO, 0, len(realizations)) for _, realization := range realizations { if realization.ExpenseNonstock == nil || realization.ExpenseNonstock.Expense == nil { continue } expense := realization.ExpenseNonstock.Expense baseDTO := ToRepportExpenseBaseDTO(expense) var latestApproval *approvalDTO.ApprovalRelationDTO if expense.LatestApproval != nil { mapped := approvalDTO.ToApprovalDTO(*expense.LatestApproval) latestApproval = &mapped } // Create a temporary realization with the current realization data if realization.ExpenseNonstock.Realization == nil { realization.ExpenseNonstock.Realization = &realization } dto := ToRepportExpenseListDTO(baseDTO, realization.ExpenseNonstock, latestApproval) result = append(result, dto) } return result }