Feat[BE-300]: creating API Get closing penjualan

This commit is contained in:
aguhh18
2025-12-05 12:31:52 +07:00
parent 8c883669d3
commit c279303b99
12 changed files with 256 additions and 80 deletions
@@ -74,3 +74,30 @@ func (u *ClosingController) GetOne(c *fiber.Ctx) error {
Data: dto.ToClosingListDTO(*result),
})
}
func (u *ClosingController) GetPenjualan(c *fiber.Ctx) error {
param := c.Params("project_flock_id")
projectFlockID, err := strconv.Atoi(param)
if err != nil {
return fiber.NewError(fiber.StatusBadRequest, "Invalid Project Flock Id")
}
projectFlock, err := u.ClosingService.GetOne(c, uint(projectFlockID))
if err != nil {
return err
}
result, err := u.ClosingService.GetPenjualan(c, uint(projectFlockID))
if err != nil {
return err
}
return c.Status(fiber.StatusOK).
JSON(response.Success{
Code: fiber.StatusOK,
Status: "success",
Message: "Get closing penjualan successfully",
Data: dto.ToPenjualanRealisasiResponseDTO(projectFlock.Category, uint(projectFlockID), result),
})
}
@@ -0,0 +1,107 @@
package dto
import (
"time"
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
deliveryOrdersDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/marketing/delivery-orderss/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"
)
// === Response DTO ===
type SalesDTO struct {
Id uint `json:"id"`
RealizationDate time.Time `json:"realization_date"`
Age int `json:"age"`
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"`
Price float64 `json:"price"`
TotalPrice float64 `json:"total_price"`
Kandang *kandangDTO.KandangRelationDTO `json:"kandang,omitempty"`
PaymentStatus string `json:"payment_status"`
}
type PenjualanRealisasiResponseDTO struct {
ProjectType string `json:"project_type"`
FlockId uint `json:"flock_id"`
Period int `json:"period"`
Sales []SalesDTO `json:"sales"`
}
// === Mapper Functions ===
func ToSalesDTO(e entity.MarketingDeliveryProduct) SalesDTO {
// todo: usia ayam masih dummy
age := 0
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
doNumber := deliveryOrdersDTO.GenerateDeliveryOrderNumber(e.MarketingProduct.Marketing.SoNumber, e.DeliveryDate, e.MarketingProduct.ProductWarehouse.Warehouse.Id)
return SalesDTO{
Id: e.Id,
RealizationDate: *e.DeliveryDate,
Age: age,
DoNumber: doNumber,
Product: product,
Customer: customer,
Qty: e.Qty,
Weight: e.TotalWeight,
AvgWeight: e.AvgWeight,
Price: e.UnitPrice,
TotalPrice: e.TotalPrice,
Kandang: kandang,
PaymentStatus: "Paid",
}
}
func ToSalesDTOs(e []entity.MarketingDeliveryProduct) []SalesDTO {
result := make([]SalesDTO, len(e))
for i, r := range e {
result[i] = ToSalesDTO(r)
}
return result
}
func ToPenjualanRealisasiResponseDTO(projectType string, projectFlockID uint, e []entity.MarketingDeliveryProduct) PenjualanRealisasiResponseDTO {
period := extractPeriodFromRealisasi(e)
return PenjualanRealisasiResponseDTO{
ProjectType: projectType,
FlockId: projectFlockID,
Period: period,
Sales: ToSalesDTOs(e),
}
}
func extractPeriodFromRealisasi(realisasi []entity.MarketingDeliveryProduct) int {
if len(realisasi) > 0 {
for _, item := range realisasi {
if item.MarketingProduct.ProductWarehouse.ProjectFlockKandang != nil {
return item.MarketingProduct.ProductWarehouse.ProjectFlockKandang.Period
}
}
}
return 0
}
+4 -2
View File
@@ -7,6 +7,7 @@ import (
rClosing "gitlab.com/mbugroup/lti-api.git/internal/modules/closings/repositories"
sClosing "gitlab.com/mbugroup/lti-api.git/internal/modules/closings/services"
rMarketings "gitlab.com/mbugroup/lti-api.git/internal/modules/marketing/sales-orders/repositories"
rUser "gitlab.com/mbugroup/lti-api.git/internal/modules/users/repositories"
sUser "gitlab.com/mbugroup/lti-api.git/internal/modules/users/services"
@@ -17,10 +18,11 @@ type ClosingModule struct{}
func (ClosingModule) RegisterRoutes(router fiber.Router, db *gorm.DB, validate *validator.Validate) {
closingRepo := rClosing.NewClosingRepository(db)
userRepo := rUser.NewUserRepository(db)
marketingRepo := rMarketings.NewMarketingRepository(db)
marketingDeliveryProductRepo := rMarketings.NewMarketingDeliveryProductRepository(db)
closingService := sClosing.NewClosingService(closingRepo, validate)
closingService := sClosing.NewClosingService(closingRepo, marketingRepo, marketingDeliveryProductRepo, validate)
userService := sUser.NewUserService(userRepo, validate)
ClosingRoutes(router, userService, closingService)
}
+2
View File
@@ -22,4 +22,6 @@ func ClosingRoutes(v1 fiber.Router, u user.UserService, s closing.ClosingService
route.Get("/", ctrl.GetAll)
route.Get("/:id", ctrl.GetOne)
route.Get("/:project_flock_id/penjualan", ctrl.GetPenjualan)
}
@@ -6,6 +6,8 @@ import (
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
repository "gitlab.com/mbugroup/lti-api.git/internal/modules/closings/repositories"
validation "gitlab.com/mbugroup/lti-api.git/internal/modules/closings/validations"
marketingDeliveryProductRepository "gitlab.com/mbugroup/lti-api.git/internal/modules/marketing/sales-orders/repositories"
marketingRepository "gitlab.com/mbugroup/lti-api.git/internal/modules/marketing/sales-orders/repositories"
"gitlab.com/mbugroup/lti-api.git/internal/utils"
"github.com/go-playground/validator/v10"
@@ -17,19 +19,24 @@ import (
type ClosingService interface {
GetAll(ctx *fiber.Ctx, params *validation.Query) ([]entity.ProjectFlock, int64, error)
GetOne(ctx *fiber.Ctx, id uint) (*entity.ProjectFlock, error)
GetPenjualan(ctx *fiber.Ctx, projectFlockID uint) ([]entity.MarketingDeliveryProduct, error)
}
type closingService struct {
Log *logrus.Logger
Validate *validator.Validate
Repository repository.ClosingRepository
Log *logrus.Logger
Validate *validator.Validate
Repository repository.ClosingRepository
MarketingRepo marketingRepository.MarketingRepository
MarketingDeliveryProductRepo marketingDeliveryProductRepository.MarketingDeliveryProductRepository
}
func NewClosingService(repo repository.ClosingRepository, validate *validator.Validate) ClosingService {
func NewClosingService(repo repository.ClosingRepository, marketingRepo marketingRepository.MarketingRepository, marketingDeliveryProductRepo marketingDeliveryProductRepository.MarketingDeliveryProductRepository, validate *validator.Validate) ClosingService {
return &closingService{
Log: utils.Log,
Validate: validate,
Repository: repo,
Log: utils.Log,
Validate: validate,
Repository: repo,
MarketingRepo: marketingRepo,
MarketingDeliveryProductRepo: marketingDeliveryProductRepo,
}
}
@@ -70,3 +77,28 @@ func (s closingService) GetOne(c *fiber.Ctx, id uint) (*entity.ProjectFlock, err
}
return closing, nil
}
func (s closingService) GetPenjualan(c *fiber.Ctx, projectFlockID 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.Marketing").
Preload("MarketingProduct.Marketing.Customer").
Order("marketing_delivery_products.delivery_date DESC")
})
if err != nil {
return nil, err
}
if len(realisasi) == 0 {
return nil, fiber.NewError(fiber.StatusNotFound, "Penjualan realisasi not found")
}
return realisasi, nil
}