diff --git a/internal/modules/closings/controllers/closing.controller.go b/internal/modules/closings/controllers/closing.controller.go index 6ab2d398..1a472f03 100644 --- a/internal/modules/closings/controllers/closing.controller.go +++ b/internal/modules/closings/controllers/closing.controller.go @@ -108,12 +108,7 @@ func (u *ClosingController) GetPenjualan(c *fiber.Ctx) error { return fiber.NewError(fiber.StatusBadRequest, "Invalid Project Flock Id") } - projectFlock, err := u.ClosingService.GetProjectFlockByID(c, uint(projectFlockID)) - if err != nil { - return err - } - - result, err := u.ClosingService.GetPenjualan(c, uint(projectFlockID)) + result, err := u.ClosingService.GetPenjualan(c, uint(projectFlockID), nil) if err != nil { return err } @@ -123,7 +118,37 @@ func (u *ClosingController) GetPenjualan(c *fiber.Ctx) error { Code: fiber.StatusOK, Status: "success", Message: "Get closing penjualan successfully", - Data: dto.ToPenjualanRealisasiResponseDTO(projectFlock.Category, uint(projectFlockID), result), + Data: dto.ToPenjualanRealisasiResponseDTO(uint(projectFlockID), result), + }) +} + +func (u *ClosingController) GetPenjualanByProjectFlockKandang(c *fiber.Ctx) error { + projectParam := c.Params("project_flock_id") + kandangParam := c.Params("project_flock_kandang_id") + + projectFlockID, err := strconv.Atoi(projectParam) + if err != nil || projectFlockID <= 0 { + return fiber.NewError(fiber.StatusBadRequest, "Invalid project_flock_id") + } + + pfkID, err := strconv.Atoi(kandangParam) + if err != nil || pfkID <= 0 { + return fiber.NewError(fiber.StatusBadRequest, "Invalid project_flock_kandang_id") + } + + kandangID := uint(pfkID) + + result, err := u.ClosingService.GetPenjualan(c, uint(projectFlockID), &kandangID) + if err != nil { + return err + } + + return c.Status(fiber.StatusOK). + JSON(response.Success{ + Code: fiber.StatusOK, + Status: "success", + Message: "Get closing penjualan by project flock kandang successfully", + Data: dto.ToPenjualanRealisasiResponseDTO(uint(projectFlockID), result), }) } diff --git a/internal/modules/closings/dto/closingMarketing.dto.go b/internal/modules/closings/dto/closingMarketing.dto.go index 42d95be2..1a790ad6 100644 --- a/internal/modules/closings/dto/closingMarketing.dto.go +++ b/internal/modules/closings/dto/closingMarketing.dto.go @@ -87,7 +87,7 @@ func ToSalesDTOs(e []entity.MarketingDeliveryProduct) []SalesDTO { return result } -func ToPenjualanRealisasiResponseDTO(projectType string, projectFlockID uint, e []entity.MarketingDeliveryProduct) PenjualanRealisasiResponseDTO { +func ToPenjualanRealisasiResponseDTO(projectFlockID uint, e []entity.MarketingDeliveryProduct) PenjualanRealisasiResponseDTO { return PenjualanRealisasiResponseDTO{ diff --git a/internal/modules/closings/route.go b/internal/modules/closings/route.go index 79c83c22..a9d25758 100644 --- a/internal/modules/closings/route.go +++ b/internal/modules/closings/route.go @@ -23,6 +23,7 @@ func ClosingRoutes(v1 fiber.Router, u user.UserService, s closing.ClosingService route.Get("/", m.RequirePermissions(m.P_ClosingGetAll), ctrl.GetAll) route.Get("/:project_flock_id/penjualan", m.RequirePermissions(m.P_ClosingDetail), ctrl.GetPenjualan) + route.Get("/:project_flock_id/:project_flock_kandang_id/penjualan", m.RequirePermissions(m.P_ClosingDetail), ctrl.GetPenjualanByProjectFlockKandang) route.Get("/:projectFlockId", m.RequirePermissions(m.P_ClosingDetail), ctrl.GetClosingSummary) route.Get("/:project_flock_id/overhead", m.RequirePermissions(m.P_ClosingDetail), ctrl.GetOverhead) route.Get("/:project_flock_id/:project_flock_kandang_id/perhitungan_sapronak", m.RequirePermissions(m.P_ClosingDetail), ctrl.GetSapronakByKandang) @@ -32,4 +33,5 @@ func ClosingRoutes(v1 fiber.Router, u user.UserService, s closing.ClosingService route.Get("/:project_flock_id/:project_flock_kandang_id/expedition-hpp", m.RequirePermissions(m.P_ClosingDetail), ctrl.GetExpeditionHPPByKandang) route.Get("/:projectFlockId/production-data", m.RequirePermissions(m.P_ClosingDetail), ctrl.GetClosingDataProduksi) route.Get("/:projectFlockId/keuangan", m.RequirePermissions(m.P_ClosingDetail), ctrl.GetClosingKeuangan) + } diff --git a/internal/modules/closings/services/closing.service.go b/internal/modules/closings/services/closing.service.go index 245fd24c..6c682b9c 100644 --- a/internal/modules/closings/services/closing.service.go +++ b/internal/modules/closings/services/closing.service.go @@ -32,7 +32,7 @@ import ( type ClosingService interface { GetAll(ctx *fiber.Ctx, params *validation.Query) ([]dto.ClosingListItemDTO, int64, error) GetProjectFlockByID(ctx *fiber.Ctx, id uint) (*entity.ProjectFlock, error) - GetPenjualan(ctx *fiber.Ctx, projectFlockID uint) ([]entity.MarketingDeliveryProduct, error) + GetPenjualan(ctx *fiber.Ctx, projectFlockID uint, projectFlockKandangID *uint) ([]entity.MarketingDeliveryProduct, error) GetClosingSummary(ctx *fiber.Ctx, projectFlockID uint) (*dto.ClosingSummaryDTO, error) GetOverhead(ctx *fiber.Ctx, projectFlockID uint) (*dto.OverheadListDTO, error) GetClosingDataProduksi(ctx *fiber.Ctx, projectFlockID uint) (*dto.ClosingProductionReportDTO, error) @@ -129,24 +129,9 @@ func (s closingService) GetProjectFlockByID(c *fiber.Ctx, id uint) (*entity.Proj return projectFlock, nil } -func (s closingService) GetPenjualan(c *fiber.Ctx, projectFlockID uint) ([]entity.MarketingDeliveryProduct, error) { +func (s closingService) GetPenjualan(c *fiber.Ctx, projectFlockID uint, projectFlockKandangID *uint) ([]entity.MarketingDeliveryProduct, error) { - realisasi, err := s.MarketingDeliveryProductRepo.GetDeliveryProductsByProjectFlockID(c.Context(), projectFlockID, func(db *gorm.DB) *gorm.DB { - return db. - Preload("MarketingProduct"). - Preload("MarketingProduct.ProductWarehouse"). - Preload("MarketingProduct.ProductWarehouse.Product"). - Preload("MarketingProduct.ProductWarehouse.Product.ProductCategory"). - Preload("MarketingProduct.ProductWarehouse.Product.Uom"). - Preload("MarketingProduct.ProductWarehouse.Product.Flags"). - Preload("MarketingProduct.ProductWarehouse.Warehouse"). - Preload("MarketingProduct.ProductWarehouse.ProjectFlockKandang"). - Preload("MarketingProduct.ProductWarehouse.ProjectFlockKandang.Kandang"). - Preload("MarketingProduct.ProductWarehouse.ProjectFlockKandang.Chickins"). - Preload("MarketingProduct.Marketing"). - Preload("MarketingProduct.Marketing.Customer"). - Order("marketing_delivery_products.delivery_date DESC") - }) + realisasi, err := s.MarketingDeliveryProductRepo.GetClosingPenjualan(c.Context(), projectFlockID, projectFlockKandangID) if err != nil { return nil, err } @@ -154,16 +139,7 @@ func (s closingService) GetPenjualan(c *fiber.Ctx, projectFlockID uint) ([]entit return []entity.MarketingDeliveryProduct{}, nil } - filtered := make([]entity.MarketingDeliveryProduct, 0, len(realisasi)) - for _, item := range realisasi { - - if item.UsageQty != 0 || item.TotalWeight != 0 || item.AvgWeight != 0 || - item.UnitPrice != 0 || item.TotalPrice != 0 { - filtered = append(filtered, item) - } - } - - return filtered, nil + return realisasi, nil } func (s closingService) GetClosingSummary(c *fiber.Ctx, projectFlockID uint) (*dto.ClosingSummaryDTO, error) { diff --git a/internal/modules/marketing/repositories/salesorder_delivery_product.repository.go b/internal/modules/marketing/repositories/salesorder_delivery_product.repository.go index 04051009..bb1343a2 100644 --- a/internal/modules/marketing/repositories/salesorder_delivery_product.repository.go +++ b/internal/modules/marketing/repositories/salesorder_delivery_product.repository.go @@ -14,6 +14,7 @@ import ( type MarketingDeliveryProductRepository interface { repository.BaseRepository[entity.MarketingDeliveryProduct] GetDeliveryProductsByProjectFlockID(ctx context.Context, projectFlockID uint, callback func(*gorm.DB) *gorm.DB) ([]entity.MarketingDeliveryProduct, error) + GetClosingPenjualan(ctx context.Context, projectFlockID uint, projectFlockKandangID *uint) ([]entity.MarketingDeliveryProduct, error) GetByMarketingId(ctx context.Context, marketingId uint) ([]entity.MarketingDeliveryProduct, error) GetByMarketingProductID(ctx context.Context, marketingProductID uint) (*entity.MarketingDeliveryProduct, error) GetAllWithFilters(ctx context.Context, offset, limit int, filters *validation.MarketingQuery) ([]entity.MarketingDeliveryProduct, int64, error) @@ -53,6 +54,43 @@ func (r *MarketingDeliveryProductRepositoryImpl) GetDeliveryProductsByProjectFlo return deliveryProducts, nil } +func (r *MarketingDeliveryProductRepositoryImpl) GetClosingPenjualan(ctx context.Context, projectFlockID uint, projectFlockKandangID *uint) ([]entity.MarketingDeliveryProduct, error) { + var deliveryProducts []entity.MarketingDeliveryProduct + + db := r.DB().WithContext(ctx). + Joins("JOIN marketing_products ON marketing_products.id = marketing_delivery_products.marketing_product_id"). + Joins("JOIN product_warehouses ON product_warehouses.id = marketing_products.product_warehouse_id"). + Joins("JOIN project_flock_kandangs ON project_flock_kandangs.id = product_warehouses.project_flock_kandang_id"). + Where("project_flock_kandangs.project_flock_id = ?", projectFlockID). + Where("marketing_delivery_products.delivery_date IS NOT NULL"). + Distinct("marketing_delivery_products.*") + + if projectFlockKandangID != nil { + db = db.Where("product_warehouses.project_flock_kandang_id = ?", *projectFlockKandangID) + } + + db = db. + Preload("MarketingProduct"). + Preload("MarketingProduct.ProductWarehouse"). + Preload("MarketingProduct.ProductWarehouse.Product"). + Preload("MarketingProduct.ProductWarehouse.Product.ProductCategory"). + Preload("MarketingProduct.ProductWarehouse.Product.Uom"). + Preload("MarketingProduct.ProductWarehouse.Product.Flags"). + Preload("MarketingProduct.ProductWarehouse.Warehouse"). + Preload("MarketingProduct.ProductWarehouse.ProjectFlockKandang"). + Preload("MarketingProduct.ProductWarehouse.ProjectFlockKandang.Kandang"). + Preload("MarketingProduct.ProductWarehouse.ProjectFlockKandang.Chickins"). + Preload("MarketingProduct.Marketing"). + Preload("MarketingProduct.Marketing.Customer"). + Order("marketing_delivery_products.delivery_date DESC") + + if err := db.Find(&deliveryProducts).Error; err != nil { + return nil, err + } + + return deliveryProducts, nil +} + func (r *MarketingDeliveryProductRepositoryImpl) GetByMarketingId(ctx context.Context, marketingId uint) ([]entity.MarketingDeliveryProduct, error) { var deliveryProducts []entity.MarketingDeliveryProduct diff --git a/internal/modules/repports/dto/repportMarketing.dto.go b/internal/modules/repports/dto/repportMarketing.dto.go index 90c2fe50..3f133674 100644 --- a/internal/modules/repports/dto/repportMarketing.dto.go +++ b/internal/modules/repports/dto/repportMarketing.dto.go @@ -1,12 +1,16 @@ package dto import ( + "encoding/json" "time" entity "gitlab.com/mbugroup/lti-api.git/internal/entities" marketingDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/marketing/dto" customerDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/customers/dto" + productCategoryDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/product-categories/dto" productDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/products/dto" + supplierDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/suppliers/dto" + uomDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/uoms/dto" warehouseDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/warehouses/dto" userDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/users/dto" "gitlab.com/mbugroup/lti-api.git/internal/utils" @@ -22,7 +26,7 @@ type RepportMarketingItemDTO struct { DoNumber string `json:"do_number"` Sales *userDTO.UserRelationDTO `json:"sales,omitempty"` VehicleNumber string `json:"vehicle_number"` - Product *productDTO.ProductRelationDTO `json:"product,omitempty"` + Product *ProductRelationDTOFixed `json:"product,omitempty"` MarketingType string `json:"marketing_type"` Qty float64 `json:"qty"` AverageWeightKg float64 `json:"average_weight_kg"` @@ -46,6 +50,12 @@ type RepportMarketingResponseDTO struct { Total *Summary `json:"total,omitempty"` } +type ProductRelationDTOFixed struct { + productDTO.ProductRelationDTO + ProductPrice float64 `json:"product_price"` + SellingPrice *float64 `json:"selling_price,omitempty"` +} + func ToRepportMarketingItemDTO(mdp entity.MarketingDeliveryProduct, hppPricePerKg float64, category string) RepportMarketingItemDTO { soDate := time.Time{} agingDays := 0 @@ -106,7 +116,7 @@ func ToRepportMarketingItemDTO(mdp entity.MarketingDeliveryProduct, hppPricePerK if mdp.MarketingProduct.ProductWarehouse.ProductId != 0 { mapped := productDTO.ToProductRelationDTO(mdp.MarketingProduct.ProductWarehouse.Product) - item.Product = &mapped + item.Product = newProductRelationDTOFixedPtr(&mapped) } return item @@ -259,3 +269,39 @@ func ToRepportMarketingResponseDTO(mdps []entity.MarketingDeliveryProduct, hppPr Total: total, } } + +func newProductRelationDTOFixedPtr(original *productDTO.ProductRelationDTO) *ProductRelationDTOFixed { + if original == nil { + return nil + } + fixed := ProductRelationDTOFixed{ + ProductRelationDTO: *original, + ProductPrice: original.ProductPrice, + SellingPrice: original.SellingPrice, + } + return &fixed +} + +func (p ProductRelationDTOFixed) MarshalJSON() ([]byte, error) { + type Alias struct { + Id uint `json:"id"` + Name string `json:"name"` + ProductPrice float64 `json:"product_price"` + SellingPrice *float64 `json:"selling_price"` + Uom *uomDTO.UomRelationDTO `json:"uom,omitempty"` + Flags *[]string `json:"flags,omitempty"` + ProductCategory *productCategoryDTO.ProductCategoryRelationDTO `json:"product_category,omitempty"` + Suppliers []supplierDTO.SupplierRelationDTO `json:"suppliers"` + } + + return json.Marshal(&Alias{ + Id: p.ProductRelationDTO.Id, + Name: p.ProductRelationDTO.Name, + ProductPrice: p.ProductPrice, + SellingPrice: p.SellingPrice, + Uom: p.ProductRelationDTO.Uom, + Flags: p.ProductRelationDTO.Flags, + ProductCategory: p.ProductRelationDTO.ProductCategory, + Suppliers: p.ProductRelationDTO.Suppliers, + }) +}