package dto import ( "time" entity "gitlab.com/mbugroup/lti-api.git/internal/entities" deliveryOrdersDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/marketing/dto" customerDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/customers/dto" kandangDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/kandangs/dto" productDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/products/dto" "gitlab.com/mbugroup/lti-api.git/internal/utils" ) // === Response DTO === type SalesDTO struct { Id uint `json:"id"` RealizationDate time.Time `json:"realization_date"` Age int `json:"age"` Week int `json:"week"` DoNumber string `json:"do_number"` Product *productDTO.ProductRelationDTO `json:"product,omitempty"` Customer *customerDTO.CustomerRelationDTO `json:"customer,omitempty"` Qty float64 `json:"qty"` Weight float64 `json:"weight"` AvgWeight float64 `json:"avg_weight"` SalesPrice float64 `json:"sales_price"` TotalSalesPrice float64 `json:"total_sales_price"` ActualPrice float64 `json:"actual_price"` TotalActualPrice float64 `json:"total_actual_price"` Kandang *kandangDTO.KandangRelationDTO `json:"kandang,omitempty"` } type SummaryDTO struct { TotalSalesPrice float64 `json:"total_sales_price"` AvgSalesPrice float64 `json:"avg_sales_price"` TotalActualPrice float64 `json:"total_actual_price"` AvgActualPrice float64 `json:"avg_actual_price"` } type PenjualanRealisasiResponseDTO struct { Sales []SalesDTO `json:"sales"` Summary SummaryDTO `json:"summary"` } // === Mapper Functions === func ToSalesDTO(e entity.MarketingDeliveryProduct) SalesDTO { productFlags := make([]string, len(e.MarketingProduct.ProductWarehouse.Product.Flags)) for i, f := range e.MarketingProduct.ProductWarehouse.Product.Flags { productFlags[i] = f.Name } var category string if e.MarketingProduct.ProductWarehouse.ProjectFlockKandang != nil { category = e.MarketingProduct.ProductWarehouse.ProjectFlockKandang.ProjectFlock.Category } ageInDay, ageInWeeks := calculateAgeFromChickin(e.MarketingProduct.ProductWarehouse.ProjectFlockKandang, e.DeliveryDate, productFlags, category) var product *productDTO.ProductRelationDTO if e.MarketingProduct.ProductWarehouse.Product.Id != 0 { mapped := productDTO.ToProductRelationDTO(e.MarketingProduct.ProductWarehouse.Product) product = &mapped } var customer *customerDTO.CustomerRelationDTO if e.MarketingProduct.Marketing.Customer.Id != 0 { mapped := customerDTO.ToCustomerRelationDTO(e.MarketingProduct.Marketing.Customer) customer = &mapped } var kandang *kandangDTO.KandangRelationDTO if e.MarketingProduct.ProductWarehouse.ProjectFlockKandang != nil && e.MarketingProduct.ProductWarehouse.ProjectFlockKandang.Kandang.Id != 0 { mapped := kandangDTO.ToKandangRelationDTO(e.MarketingProduct.ProductWarehouse.ProjectFlockKandang.Kandang) kandang = &mapped } var realizationDate time.Time if e.DeliveryDate != nil { realizationDate = *e.DeliveryDate } doNumber := deliveryOrdersDTO.GenerateDeliveryOrderNumber(e.MarketingProduct.Marketing.SoNumber, e.DeliveryDate, e.MarketingProduct.ProductWarehouse.Warehouse.Id) return SalesDTO{ Id: e.Id, RealizationDate: realizationDate, Age: ageInDay, Week: ageInWeeks, DoNumber: doNumber, Product: product, Customer: customer, Qty: e.UsageQty, Weight: e.TotalWeight, AvgWeight: e.AvgWeight, SalesPrice: e.MarketingProduct.UnitPrice, TotalSalesPrice: e.MarketingProduct.TotalPrice, ActualPrice: e.UnitPrice, TotalActualPrice: e.TotalPrice, Kandang: kandang, } } func ToSalesAgeDTO(e entity.MarketingDeliveryProduct) SalesDTO { productFlags := make([]string, len(e.MarketingProduct.ProductWarehouse.Product.Flags)) for i, f := range e.MarketingProduct.ProductWarehouse.Product.Flags { productFlags[i] = f.Name } var category string if e.MarketingProduct.ProductWarehouse.ProjectFlockKandang != nil { category = e.MarketingProduct.ProductWarehouse.ProjectFlockKandang.ProjectFlock.Category } ageInDay, _ := calculateAgeFromChickin(e.MarketingProduct.ProductWarehouse.ProjectFlockKandang, e.DeliveryDate, productFlags, category) return SalesDTO{ Age: ageInDay, Qty: e.UsageQty, } } func ToSummaryDto(e []entity.MarketingDeliveryProduct) SummaryDTO { var totalSalesPrice, totalActualPrice, sumSales, sumActual float64 count := len(e) for _, item := range e { totalSalesPrice += item.MarketingProduct.TotalPrice totalActualPrice += item.TotalPrice sumSales += item.MarketingProduct.UnitPrice sumActual += item.UnitPrice } return SummaryDTO{ TotalSalesPrice: totalSalesPrice, TotalActualPrice: totalActualPrice, AvgSalesPrice: sumSales / float64(count), AvgActualPrice: sumActual / float64(count), } } func ToSalesDTOs(e []entity.MarketingDeliveryProduct) []SalesDTO { result := make([]SalesDTO, len(e)) for i, r := range e { result[i] = ToSalesDTO(r) } return result } func ToPenjualanRealisasiResponseDTO(e []entity.MarketingDeliveryProduct) PenjualanRealisasiResponseDTO { return PenjualanRealisasiResponseDTO{ Sales: ToSalesDTOs(e), Summary: ToSummaryDto(e), } } func calculateAgeFromChickin(projectFlockKandang *entity.ProjectFlockKandang, deliveryDate *time.Time, productFlags []string, category string) (int, int) { if projectFlockKandang == nil || deliveryDate == nil || len(projectFlockKandang.Chickins) == 0 { return 0, 0 } for _, flag := range productFlags { if flag == string(utils.FlagOVK) || flag == string(utils.FlagPakan) || flag == string(utils.FlagPreStarter) || flag == string(utils.FlagStarter) || flag == string(utils.FlagFinisher) || flag == string(utils.FlagObat) || flag == string(utils.FlagVitamin) || flag == string(utils.FlagKimia) || flag == string(utils.FlagEkspedisi) || flag == string(utils.FlagTelur) || flag == string(utils.FlagTelurUtuh) || flag == string(utils.FlagTelurPecah) || flag == string(utils.FlagTelurPutih) || flag == string(utils.FlagTelurRetak) { return 0, 0 } } earliestChickinDate := projectFlockKandang.Chickins[0].ChickInDate for _, chickin := range projectFlockKandang.Chickins { if chickin.ChickInDate.Before(earliestChickinDate) { earliestChickinDate = chickin.ChickInDate } } diff := deliveryDate.Sub(earliestChickinDate) ageInDays := int(diff.Hours() / 24) var ageInWeeks int if ageInDays <= 0 { ageInWeeks = 0 } else { if category == string(utils.ProjectFlockCategoryLaying) { ageInDays = ageInDays + 119 ageInWeeks = ((ageInDays - 1) / 7) + 1 } else { ageInWeeks = ((ageInDays - 1) / 7) + 1 } } return ageInDays, ageInWeeks }