mirror of
https://gitlab.com/mbugroup/lti-api.git
synced 2026-05-25 07:45:44 +00:00
Feat[BE-261,265]: createing BOP and BOP realization(Unfinished)
This commit is contained in:
@@ -1,68 +1,322 @@
|
||||
package dto
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
|
||||
approvalDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/approvals/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"
|
||||
userDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/users/dto"
|
||||
)
|
||||
|
||||
// === DTO Structs ===
|
||||
// === Base DTO ===
|
||||
|
||||
type ExpenseBaseDTO struct {
|
||||
Id uint64 `json:"id"`
|
||||
PoNumber string `json:"po_number"`
|
||||
ExpenseDate time.Time `json:"expense_date"`
|
||||
GrandTotal float64 `json:"grand_total"`
|
||||
Id uint64 `json:"id"`
|
||||
ReferenceNumber string `json:"reference_number"`
|
||||
PoNumber *string `json:"po_number,omitempty"`
|
||||
Category string `json:"category"`
|
||||
ExpenseDate time.Time `json:"expense_date"`
|
||||
GrandTotal float64 `json:"grand_total"`
|
||||
}
|
||||
|
||||
// === List DTO (untuk GetAll) ===
|
||||
|
||||
type ExpenseListDTO struct {
|
||||
Id uint64 `json:"id"`
|
||||
ReferenceNumber string `json:"reference_number"`
|
||||
PoNumber string `json:"po_number"`
|
||||
Category string `json:"category"`
|
||||
ExpenseDate time.Time `json:"expense_date"`
|
||||
GrandTotal float64 `json:"grand_total"`
|
||||
CreatedUser *userDTO.UserBaseDTO `json:"created_user,omitempty"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
ExpenseBaseDTO
|
||||
CreatedUser *userDTO.UserBaseDTO `json:"created_user,omitempty"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
LatestApproval *approvalDTO.ApprovalBaseDTO `json:"latest_approval,omitempty"`
|
||||
}
|
||||
|
||||
// === Detail DTO (untuk GetOne) ===
|
||||
|
||||
type ExpenseDetailDTO struct {
|
||||
ExpenseBaseDTO
|
||||
Supplier *supplierDTO.SupplierBaseDTO `json:"supplier,omitempty"`
|
||||
CreatedUser *userDTO.UserBaseDTO `json:"created_user,omitempty"`
|
||||
Kandangs []KandangGroupDTO `json:"kandangs,omitempty"`
|
||||
TotalPengajuan float64 `json:"total_pengajuan"`
|
||||
TotalRealisasi float64 `json:"total_realisasi"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
LatestApproval *approvalDTO.ApprovalBaseDTO `json:"latest_approval,omitempty"`
|
||||
}
|
||||
|
||||
// === Nested DTO ===
|
||||
|
||||
type ExpenseNonstockDTO struct {
|
||||
Id uint64 `json:"id"`
|
||||
Qty float64 `json:"qty"`
|
||||
UnitPrice float64 `json:"unit_price"`
|
||||
TotalPrice float64 `json:"total_price"`
|
||||
Note *string `json:"note,omitempty"`
|
||||
Nonstock *nonstockDTO.NonstockBaseDTO `json:"nonstock,omitempty"`
|
||||
ProjectFlockKandang *ProjectFlockKandangNestedDTO `json:"project_flock_kandang,omitempty"`
|
||||
Realization *ExpenseRealizationDTO `json:"realization,omitempty"`
|
||||
}
|
||||
|
||||
type ProjectFlockKandangNestedDTO struct {
|
||||
Id uint64 `json:"id"`
|
||||
KandangId uint64 `json:"kandang_id"`
|
||||
}
|
||||
|
||||
type ExpenseRealizationDTO struct {
|
||||
Id uint64 `json:"id"`
|
||||
RealizationQty float64 `json:"realization_qty"`
|
||||
RealizationUnitPrice float64 `json:"realization_unit_price"`
|
||||
RealizationTotalPrice float64 `json:"realization_total_price"`
|
||||
RealizationDate time.Time `json:"realization_date"`
|
||||
Note *string `json:"note,omitempty"`
|
||||
}
|
||||
|
||||
type RealizationOnlyDTO struct {
|
||||
Id uint64 `json:"id"`
|
||||
RealizationQty float64 `json:"realization_qty"`
|
||||
RealizationUnitPrice float64 `json:"realization_unit_price"`
|
||||
RealizationTotalPrice float64 `json:"realization_total_price"`
|
||||
RealizationDate time.Time `json:"realization_date"`
|
||||
Note *string `json:"note,omitempty"`
|
||||
Nonstock *nonstockDTO.NonstockBaseDTO `json:"nonstock,omitempty"`
|
||||
ProjectFlockKandang *ProjectFlockKandangNestedDTO `json:"project_flock_kandang,omitempty"`
|
||||
}
|
||||
|
||||
type KandangDTO struct {
|
||||
Id uint64 `json:"id"`
|
||||
KandangId uint64 `json:"kandang_id"`
|
||||
Name string `json:"name,omitempty"`
|
||||
}
|
||||
|
||||
type KandangGroupDTO struct {
|
||||
Id uint64 `json:"id"`
|
||||
KandangId uint64 `json:"kandang_id"`
|
||||
Name string `json:"name,omitempty"`
|
||||
Pengajuans []ExpenseNonstockDTO `json:"pengajuans,omitempty"`
|
||||
Realisasi []RealizationOnlyDTO `json:"realisasi,omitempty"`
|
||||
}
|
||||
|
||||
// === Helper Functions ===
|
||||
|
||||
func getStringValue(s *string) string {
|
||||
if s == nil {
|
||||
return ""
|
||||
}
|
||||
return *s
|
||||
}
|
||||
|
||||
// === Mapper Functions ===
|
||||
|
||||
func ToExpenseBaseDTO(e entity.Expense) ExpenseBaseDTO {
|
||||
func ToExpenseBaseDTO(e *entity.Expense) ExpenseBaseDTO {
|
||||
return ExpenseBaseDTO{
|
||||
Id: e.Id,
|
||||
PoNumber: e.PoNumber,
|
||||
ExpenseDate: e.ExpenseDate,
|
||||
GrandTotal: e.GrandTotal,
|
||||
}
|
||||
}
|
||||
|
||||
func ToExpenseListDTO(e entity.Expense) ExpenseListDTO {
|
||||
var createdUser *userDTO.UserBaseDTO
|
||||
if e.CreatedUser.Id != 0 {
|
||||
mapped := userDTO.ToUserBaseDTO(*e.CreatedUser)
|
||||
createdUser = &mapped
|
||||
}
|
||||
|
||||
return ExpenseListDTO{
|
||||
Id: e.Id,
|
||||
ReferenceNumber: *e.ReferenceNumber,
|
||||
ReferenceNumber: getStringValue(e.ReferenceNumber),
|
||||
PoNumber: e.PoNumber,
|
||||
Category: e.Category,
|
||||
ExpenseDate: e.ExpenseDate,
|
||||
GrandTotal: e.GrandTotal,
|
||||
CreatedAt: e.CreatedAt,
|
||||
UpdatedAt: e.UpdatedAt,
|
||||
CreatedUser: createdUser,
|
||||
}
|
||||
}
|
||||
|
||||
func ToExpenseListDTOs(e []entity.Expense) []ExpenseListDTO {
|
||||
result := make([]ExpenseListDTO, len(e))
|
||||
for i, r := range e {
|
||||
result[i] = ToExpenseListDTO(r)
|
||||
func ToExpenseListDTO(e *entity.Expense) ExpenseListDTO {
|
||||
var createdUser *userDTO.UserBaseDTO
|
||||
if e.CreatedUser != nil && e.CreatedUser.Id != 0 {
|
||||
mapped := userDTO.ToUserBaseDTO(*e.CreatedUser)
|
||||
createdUser = &mapped
|
||||
}
|
||||
|
||||
var latestApproval *approvalDTO.ApprovalBaseDTO
|
||||
if e.LatestApproval != nil {
|
||||
mapped := approvalDTO.ToApprovalDTO(*e.LatestApproval)
|
||||
latestApproval = &mapped
|
||||
}
|
||||
|
||||
return ExpenseListDTO{
|
||||
ExpenseBaseDTO: ToExpenseBaseDTO(e),
|
||||
CreatedUser: createdUser,
|
||||
CreatedAt: e.CreatedAt,
|
||||
UpdatedAt: e.UpdatedAt,
|
||||
LatestApproval: latestApproval,
|
||||
}
|
||||
}
|
||||
|
||||
func ToExpenseListDTOs(expenses []entity.Expense) []ExpenseListDTO {
|
||||
result := make([]ExpenseListDTO, len(expenses))
|
||||
for i, expense := range expenses {
|
||||
result[i] = ToExpenseListDTO(&expense)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func ToExpenseDetailDTO(e *entity.Expense) ExpenseDetailDTO {
|
||||
var createdUser *userDTO.UserBaseDTO
|
||||
if e.CreatedUser != nil && e.CreatedUser.Id != 0 {
|
||||
mapped := userDTO.ToUserBaseDTO(*e.CreatedUser)
|
||||
createdUser = &mapped
|
||||
}
|
||||
|
||||
var supplier *supplierDTO.SupplierBaseDTO
|
||||
if e.Supplier != nil && e.Supplier.Id != 0 {
|
||||
mapped := supplierDTO.ToSupplierBaseDTO(*e.Supplier)
|
||||
supplier = &mapped
|
||||
}
|
||||
|
||||
var latestApproval *approvalDTO.ApprovalBaseDTO
|
||||
if e.LatestApproval != nil {
|
||||
mapped := approvalDTO.ToApprovalDTO(*e.LatestApproval)
|
||||
latestApproval = &mapped
|
||||
}
|
||||
|
||||
var pengajuans []ExpenseNonstockDTO
|
||||
var realisasi []RealizationOnlyDTO
|
||||
|
||||
if len(e.Nonstocks) > 0 {
|
||||
pengajuans = make([]ExpenseNonstockDTO, 0)
|
||||
realisasi = make([]RealizationOnlyDTO, 0)
|
||||
|
||||
for _, ns := range e.Nonstocks {
|
||||
// Create DTO without realization for pengajuans
|
||||
pengajuanDTO := ToExpenseNonstockDTO(ns)
|
||||
pengajuanDTO.Realization = nil // Remove realization from pengajuan
|
||||
pengajuans = append(pengajuans, pengajuanDTO)
|
||||
|
||||
// Create separate DTO with realization data if it exists
|
||||
if ns.Realization != nil && ns.Realization.Id != 0 {
|
||||
// Create realization DTO with only realization data
|
||||
var nonstock *nonstockDTO.NonstockBaseDTO
|
||||
if ns.Nonstock != nil && ns.Nonstock.Id != 0 {
|
||||
mapped := nonstockDTO.ToNonstockBaseDTO(*ns.Nonstock)
|
||||
nonstock = &mapped
|
||||
}
|
||||
|
||||
var projectFlockKandang *ProjectFlockKandangNestedDTO
|
||||
if ns.ProjectFlockKandang != nil && ns.ProjectFlockKandang.Id != 0 {
|
||||
projectFlockKandang = &ProjectFlockKandangNestedDTO{
|
||||
Id: uint64(ns.ProjectFlockKandang.Id),
|
||||
KandangId: uint64(ns.ProjectFlockKandang.KandangId),
|
||||
}
|
||||
}
|
||||
|
||||
realisasiDTO := RealizationOnlyDTO{
|
||||
Id: ns.Realization.Id,
|
||||
RealizationQty: ns.Realization.RealizationQty,
|
||||
RealizationUnitPrice: ns.Realization.RealizationUnitPrice,
|
||||
RealizationTotalPrice: ns.Realization.RealizationTotalPrice,
|
||||
RealizationDate: ns.Realization.RealizationDate,
|
||||
Note: ns.Realization.Note,
|
||||
Nonstock: nonstock,
|
||||
ProjectFlockKandang: projectFlockKandang,
|
||||
}
|
||||
realisasi = append(realisasi, realisasiDTO)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Calculate total pengajuan and realisasi
|
||||
var totalPengajuan float64
|
||||
for _, p := range pengajuans {
|
||||
totalPengajuan += p.TotalPrice
|
||||
}
|
||||
|
||||
var totalRealisasi float64
|
||||
for _, r := range realisasi {
|
||||
totalRealisasi += r.RealizationTotalPrice
|
||||
}
|
||||
|
||||
// Group pengajuans and realisasi by kandang
|
||||
kandangMap := make(map[uint64]*KandangGroupDTO)
|
||||
|
||||
// Process pengajuans
|
||||
for _, p := range pengajuans {
|
||||
if p.ProjectFlockKandang != nil {
|
||||
kandangId := p.ProjectFlockKandang.KandangId
|
||||
if kandangMap[kandangId] == nil {
|
||||
kandangMap[kandangId] = &KandangGroupDTO{
|
||||
Id: p.ProjectFlockKandang.Id,
|
||||
KandangId: kandangId,
|
||||
Name: fmt.Sprintf("Kandang %d", kandangId),
|
||||
}
|
||||
}
|
||||
kandangMap[kandangId].Pengajuans = append(kandangMap[kandangId].Pengajuans, p)
|
||||
}
|
||||
}
|
||||
|
||||
// Process realisasi
|
||||
for _, r := range realisasi {
|
||||
if r.ProjectFlockKandang != nil {
|
||||
kandangId := r.ProjectFlockKandang.KandangId
|
||||
if kandangMap[kandangId] == nil {
|
||||
kandangMap[kandangId] = &KandangGroupDTO{
|
||||
Id: r.ProjectFlockKandang.Id,
|
||||
KandangId: kandangId,
|
||||
Name: fmt.Sprintf("Kandang %d", kandangId),
|
||||
}
|
||||
}
|
||||
kandangMap[kandangId].Realisasi = append(kandangMap[kandangId].Realisasi, r)
|
||||
}
|
||||
}
|
||||
|
||||
// Convert map to slice
|
||||
var kandangs []KandangGroupDTO
|
||||
for _, k := range kandangMap {
|
||||
kandangs = append(kandangs, *k)
|
||||
}
|
||||
|
||||
return ExpenseDetailDTO{
|
||||
ExpenseBaseDTO: ToExpenseBaseDTO(e),
|
||||
Supplier: supplier,
|
||||
CreatedUser: createdUser,
|
||||
Kandangs: kandangs,
|
||||
TotalPengajuan: totalPengajuan,
|
||||
TotalRealisasi: totalRealisasi,
|
||||
CreatedAt: e.CreatedAt,
|
||||
UpdatedAt: e.UpdatedAt,
|
||||
LatestApproval: latestApproval,
|
||||
}
|
||||
}
|
||||
|
||||
func ToExpenseNonstockDTO(ns entity.ExpenseNonstock) ExpenseNonstockDTO {
|
||||
var nonstock *nonstockDTO.NonstockBaseDTO
|
||||
if ns.Nonstock != nil && ns.Nonstock.Id != 0 {
|
||||
mapped := nonstockDTO.ToNonstockBaseDTO(*ns.Nonstock)
|
||||
nonstock = &mapped
|
||||
}
|
||||
|
||||
var projectFlockKandang *ProjectFlockKandangNestedDTO
|
||||
if ns.ProjectFlockKandang != nil && ns.ProjectFlockKandang.Id != 0 {
|
||||
projectFlockKandang = &ProjectFlockKandangNestedDTO{
|
||||
Id: uint64(ns.ProjectFlockKandang.Id),
|
||||
KandangId: uint64(ns.ProjectFlockKandang.KandangId),
|
||||
}
|
||||
}
|
||||
|
||||
var realization *ExpenseRealizationDTO
|
||||
if ns.Realization != nil && ns.Realization.Id != 0 {
|
||||
mapped := ToExpenseRealizationDTO(*ns.Realization)
|
||||
realization = &mapped
|
||||
}
|
||||
|
||||
return ExpenseNonstockDTO{
|
||||
Id: ns.Id,
|
||||
Qty: ns.Qty,
|
||||
UnitPrice: ns.UnitPrice,
|
||||
TotalPrice: ns.TotalPrice,
|
||||
Note: ns.Note,
|
||||
Nonstock: nonstock,
|
||||
ProjectFlockKandang: projectFlockKandang,
|
||||
Realization: realization,
|
||||
}
|
||||
}
|
||||
|
||||
func ToExpenseRealizationDTO(r entity.ExpenseRealization) ExpenseRealizationDTO {
|
||||
return ExpenseRealizationDTO{
|
||||
Id: r.Id,
|
||||
RealizationQty: r.RealizationQty,
|
||||
RealizationUnitPrice: r.RealizationUnitPrice,
|
||||
RealizationTotalPrice: r.RealizationTotalPrice,
|
||||
RealizationDate: r.RealizationDate,
|
||||
Note: r.Note,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user