package dto import ( "fmt" "time" entity "gitlab.com/mbugroup/lti-api.git/internal/entities" customerDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/customers/dto" productDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/products/dto" warehouseDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/warehouses/dto" userDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/users/dto" ) type RepportMarketingItemDTO struct { ID int `json:"id"` SoDate time.Time `json:"so_date"` RealizationDate time.Time `json:"realization_date"` AgingDays int `json:"aging_days"` Warehouse *warehouseDTO.WarehouseRelationDTO `json:"warehouse,omitempty"` Customer *customerDTO.CustomerRelationDTO `json:"customer,omitempty"` DoNumber string `json:"do_number"` Sales *userDTO.UserRelationDTO `json:"sales,omitempty"` VehicleNumber string `json:"vehicle_number"` Product *productDTO.ProductRelationDTO `json:"product,omitempty"` MarketingType string `json:"marketing_type"` Qty float64 `json:"qty"` AverageWeightKg float64 `json:"average_weight_kg"` TotalWeightKg float64 `json:"total_weight_kg"` SalesPricePerKg float64 `json:"sales_price_per_kg"` HppPricePerKg float64 `json:"hpp_price_per_kg"` SalesAmount float64 `json:"sales_amount"` HppAmount float64 `json:"hpp_amount"` } type Summary struct { TotalQty int `json:"total_qty"` TotalWeightKg float64 `json:"total_weight_kg"` TotalSalesAmount int64 `json:"total_sales_amount"` TotalHppAmount int64 `json:"total_hpp_amount"` TotalHppPricePerKg float64 `json:"total_hpp_price_per_kg"` } type RepportMarketingResponseDTO struct { Items []RepportMarketingItemDTO `json:"items"` Total *Summary `json:"total,omitempty"` } func ToRepportMarketingItemDTO(mdp entity.MarketingDeliveryProduct, hppPricePerKg float64) RepportMarketingItemDTO { soDate := time.Time{} agingDays := 0 if mdp.MarketingProduct.Marketing.SoDate.Year() > 1 { soDate = mdp.MarketingProduct.Marketing.SoDate agingDays = int(time.Since(soDate).Hours() / 24) } realizationDate := time.Time{} if mdp.DeliveryDate != nil { realizationDate = *mdp.DeliveryDate } doNumber := generateDoNumber(mdp.MarketingProduct.Marketing.SoNumber, mdp.DeliveryDate, mdp.MarketingProduct.ProductWarehouse.WarehouseId) totalWeightKg := mdp.Qty * mdp.AvgWeight salesAmount := totalWeightKg * mdp.UnitPrice hppAmount := totalWeightKg * hppPricePerKg item := RepportMarketingItemDTO{ ID: int(mdp.Id), SoDate: soDate, RealizationDate: realizationDate, AgingDays: agingDays, DoNumber: doNumber, MarketingType: "ayam", Qty: mdp.Qty, AverageWeightKg: mdp.AvgWeight, TotalWeightKg: totalWeightKg, SalesPricePerKg: mdp.UnitPrice, HppPricePerKg: hppPricePerKg, SalesAmount: salesAmount, HppAmount: hppAmount, } if mdp.MarketingProduct.ProductWarehouse.WarehouseId != 0 { mapped := warehouseDTO.ToWarehouseRelationDTO(mdp.MarketingProduct.ProductWarehouse.Warehouse) item.Warehouse = &mapped } if mdp.MarketingProduct.Marketing.CustomerId != 0 { mapped := customerDTO.ToCustomerRelationDTO(mdp.MarketingProduct.Marketing.Customer) item.Customer = &mapped } if mdp.MarketingProduct.Marketing.SalesPersonId != 0 { mapped := userDTO.ToUserRelationDTO(mdp.MarketingProduct.Marketing.SalesPerson) item.Sales = &mapped } item.VehicleNumber = mdp.VehicleNumber if mdp.MarketingProduct.ProductWarehouse.ProductId != 0 { mapped := productDTO.ToProductRelationDTO(mdp.MarketingProduct.ProductWarehouse.Product) item.Product = &mapped } return item } func ToRepportMarketingItemDTOs(mdps []entity.MarketingDeliveryProduct, hppPricePerKg float64) []RepportMarketingItemDTO { items := make([]RepportMarketingItemDTO, 0, len(mdps)) for _, mdp := range mdps { items = append(items, ToRepportMarketingItemDTO(mdp, hppPricePerKg)) } return items } func ToRepportMarketingItemDTOsWithHppMap(mdps []entity.MarketingDeliveryProduct, hppMap map[uint]float64) []RepportMarketingItemDTO { items := make([]RepportMarketingItemDTO, 0, len(mdps)) for _, mdp := range mdps { hppPerKg := float64(0) if projectFlockKandang := mdp.MarketingProduct.ProductWarehouse.ProjectFlockKandang; projectFlockKandang != nil { if hpp, exists := hppMap[projectFlockKandang.ProjectFlockId]; exists { hppPerKg = hpp } } items = append(items, ToRepportMarketingItemDTO(mdp, hppPerKg)) } return items } func ToSummary(mdps []entity.MarketingDeliveryProduct, hppPricePerKg float64) *Summary { if len(mdps) == 0 { return nil } totalQty := 0 totalWeightKg := 0.0 totalSalesAmount := int64(0) totalHppAmount := int64(0) for _, mdp := range mdps { calculatedTotalWeight := mdp.Qty * mdp.AvgWeight totalQty += int(mdp.Qty) totalWeightKg += calculatedTotalWeight totalSalesAmount += int64(calculatedTotalWeight * mdp.UnitPrice) totalHppAmount += int64(calculatedTotalWeight * hppPricePerKg) } totalHppPricePerKg := float64(0) if totalWeightKg > 0 { totalHppPricePerKg = float64(totalHppAmount) / totalWeightKg } return &Summary{ TotalQty: totalQty, TotalWeightKg: totalWeightKg, TotalSalesAmount: totalSalesAmount, TotalHppAmount: totalHppAmount, TotalHppPricePerKg: totalHppPricePerKg, } } func generateDoNumber(soNumber string, deliveryDate *time.Time, warehouseId uint) string { dateStr := "" if deliveryDate != nil { dateStr = deliveryDate.Format("20060102") } return fmt.Sprintf("%s-%s-%d", soNumber, dateStr, warehouseId) } func ToSummaryFromDTOItems(items []RepportMarketingItemDTO) *Summary { if len(items) == 0 { return nil } totalQty := 0 totalWeightKg := 0.0 totalSalesAmount := int64(0) totalHppAmount := int64(0) for _, item := range items { totalQty += int(item.Qty) totalWeightKg += item.TotalWeightKg totalSalesAmount += int64(item.SalesAmount) totalHppAmount += int64(item.HppAmount) } totalHppPricePerKg := float64(0) if totalWeightKg > 0 { totalHppPricePerKg = float64(totalHppAmount) / totalWeightKg } return &Summary{ TotalQty: totalQty, TotalWeightKg: totalWeightKg, TotalSalesAmount: totalSalesAmount, TotalHppAmount: totalHppAmount, TotalHppPricePerKg: totalHppPricePerKg, } } func ToRepportMarketingResponseDTO(mdps []entity.MarketingDeliveryProduct, hppPricePerKg float64) RepportMarketingResponseDTO { items := ToRepportMarketingItemDTOs(mdps, hppPricePerKg) total := ToSummary(mdps, hppPricePerKg) return RepportMarketingResponseDTO{ Items: items, Total: total, } }