mirror of
https://gitlab.com/mbugroup/lti-api.git
synced 2026-05-20 13:31:56 +00:00
feat[BE]: create GetOverhead API, and fixing chickin use newest productwarehouse schema
This commit is contained in:
@@ -123,3 +123,25 @@ func (u *ClosingController) GetPenjualan(c *fiber.Ctx) error {
|
||||
Data: dto.ToPenjualanRealisasiResponseDTO(projectFlock.Category, uint(projectFlockID), result),
|
||||
})
|
||||
}
|
||||
|
||||
func (u *ClosingController) GetOverhead(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")
|
||||
}
|
||||
|
||||
result, err := u.ClosingService.GetOverhead(c, uint(projectFlockID))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return c.Status(fiber.StatusOK).
|
||||
JSON(response.Success{
|
||||
Code: fiber.StatusOK,
|
||||
Status: "success",
|
||||
Message: "Get overhead successfully",
|
||||
Data: result,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@ import (
|
||||
)
|
||||
|
||||
// === Response DTO ===
|
||||
|
||||
type SalesDTO struct {
|
||||
Id uint `json:"id"`
|
||||
RealizationDate time.Time `json:"realization_date"`
|
||||
|
||||
@@ -0,0 +1,175 @@
|
||||
package dto
|
||||
|
||||
import (
|
||||
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
|
||||
)
|
||||
|
||||
// === DTO Structs ===
|
||||
|
||||
type OverheadDTO struct {
|
||||
ItemName string `json:"item_name"`
|
||||
UOMName string `json:"uom_name"`
|
||||
BudgetQuantity float64 `json:"budget_quantity"`
|
||||
BudgetUnitPrice float64 `json:"budget_unit_price"`
|
||||
BudgetTotalAmount float64 `json:"budget_total_amount"`
|
||||
ActualDate string `json:"actual_date"`
|
||||
ActualQuantity float64 `json:"actual_quantity"`
|
||||
ActualUnitPrice float64 `json:"actual_unit_price"`
|
||||
ActualTotalAmount float64 `json:"actual_total_amount"`
|
||||
CostPerBird float64 `json:"cost_per_bird"`
|
||||
}
|
||||
|
||||
type TotalDTO struct {
|
||||
BudgetQuantity float64 `json:"budget_quantity"`
|
||||
BudgetTotalAmount float64 `json:"budget_total_amount"`
|
||||
ActualQuantity float64 `json:"actual_quantity"`
|
||||
ActualTotalAmount float64 `json:"actual_total_amount"`
|
||||
CostPerBird float64 `json:"cost_per_bird"`
|
||||
}
|
||||
|
||||
type OverheadListDTO struct {
|
||||
Total TotalDTO `json:"total"`
|
||||
Overheads []OverheadDTO `json:"overheads"`
|
||||
}
|
||||
|
||||
// === Mapper Functions ===
|
||||
|
||||
func ToOverheadDTO(budget *entity.ProjectBudget, realization *entity.ExpenseRealization) OverheadDTO {
|
||||
if budget == nil && realization == nil {
|
||||
return OverheadDTO{}
|
||||
}
|
||||
|
||||
var itemName, itemUOM string
|
||||
if budget != nil {
|
||||
itemName, itemUOM = getItemInfo(budget.Nonstock)
|
||||
}
|
||||
|
||||
if itemName == "" && realization != nil && realization.ExpenseNonstock != nil {
|
||||
itemName, itemUOM = getItemInfo(realization.ExpenseNonstock.Nonstock)
|
||||
}
|
||||
|
||||
dto := OverheadDTO{
|
||||
ItemName: itemName,
|
||||
UOMName: itemUOM,
|
||||
}
|
||||
|
||||
if budget != nil {
|
||||
dto.BudgetQuantity = budget.Qty
|
||||
dto.BudgetUnitPrice = budget.Price
|
||||
dto.BudgetTotalAmount = calculateTotal(budget.Qty, budget.Price)
|
||||
}
|
||||
|
||||
if realization != nil {
|
||||
dto.ActualQuantity = realization.Qty
|
||||
dto.ActualUnitPrice = realization.Price
|
||||
dto.ActualTotalAmount = calculateTotal(realization.Qty, realization.Price)
|
||||
dto.ActualDate = formatRealizationDate(realization)
|
||||
}
|
||||
|
||||
return dto
|
||||
}
|
||||
|
||||
func ToOverheadListDTOs(budgets []entity.ProjectBudget, realizations []entity.ExpenseRealization, totalChickinQty float64) OverheadListDTO {
|
||||
overheadsByNonstockID := make(map[uint]*OverheadDTO)
|
||||
latestDateByNonstockID := make(map[uint]string)
|
||||
|
||||
for i := range budgets {
|
||||
nonstockID := budgets[i].NonstockId
|
||||
if overheadsByNonstockID[nonstockID] == nil {
|
||||
overheadsByNonstockID[nonstockID] = &OverheadDTO{}
|
||||
}
|
||||
|
||||
itemName, itemUOM := getItemInfo(budgets[i].Nonstock)
|
||||
overheadsByNonstockID[nonstockID].ItemName = itemName
|
||||
overheadsByNonstockID[nonstockID].UOMName = itemUOM
|
||||
overheadsByNonstockID[nonstockID].BudgetQuantity = budgets[i].Qty
|
||||
overheadsByNonstockID[nonstockID].BudgetUnitPrice = budgets[i].Price
|
||||
overheadsByNonstockID[nonstockID].BudgetTotalAmount = calculateTotal(budgets[i].Qty, budgets[i].Price)
|
||||
}
|
||||
|
||||
for i := range realizations {
|
||||
if realizations[i].ExpenseNonstock == nil || realizations[i].ExpenseNonstock.NonstockId == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
nonstockID := uint(*realizations[i].ExpenseNonstock.NonstockId)
|
||||
if overheadsByNonstockID[nonstockID] == nil {
|
||||
overheadsByNonstockID[nonstockID] = &OverheadDTO{}
|
||||
}
|
||||
|
||||
overheadsByNonstockID[nonstockID].ActualQuantity += realizations[i].Qty
|
||||
overheadsByNonstockID[nonstockID].ActualTotalAmount += calculateTotal(realizations[i].Qty, realizations[i].Price)
|
||||
|
||||
if overheadsByNonstockID[nonstockID].ItemName == "" {
|
||||
itemName, itemUOM := getItemInfo(realizations[i].ExpenseNonstock.Nonstock)
|
||||
overheadsByNonstockID[nonstockID].ItemName = itemName
|
||||
overheadsByNonstockID[nonstockID].UOMName = itemUOM
|
||||
}
|
||||
|
||||
realizationDateStr := formatRealizationDate(&realizations[i])
|
||||
if realizationDateStr != "" {
|
||||
if latestDateByNonstockID[nonstockID] == "" || realizationDateStr > latestDateByNonstockID[nonstockID] {
|
||||
latestDateByNonstockID[nonstockID] = realizationDateStr
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var totalBudgetQuantity, totalBudgetAmount, totalActualQuantity, totalActualAmount float64
|
||||
overheadItems := make([]OverheadDTO, 0, len(overheadsByNonstockID))
|
||||
|
||||
for nonstockID, overhead := range overheadsByNonstockID {
|
||||
overhead.ActualDate = latestDateByNonstockID[nonstockID]
|
||||
overhead.CostPerBird = calculateCostPerBird(overhead.ActualTotalAmount, totalChickinQty)
|
||||
|
||||
if overhead.ActualQuantity > 0 {
|
||||
overhead.ActualUnitPrice = overhead.ActualTotalAmount / overhead.ActualQuantity
|
||||
}
|
||||
|
||||
totalBudgetQuantity += overhead.BudgetQuantity
|
||||
totalBudgetAmount += overhead.BudgetTotalAmount
|
||||
totalActualQuantity += overhead.ActualQuantity
|
||||
totalActualAmount += overhead.ActualTotalAmount
|
||||
|
||||
overheadItems = append(overheadItems, *overhead)
|
||||
}
|
||||
|
||||
return OverheadListDTO{
|
||||
Total: TotalDTO{
|
||||
BudgetQuantity: totalBudgetQuantity,
|
||||
BudgetTotalAmount: totalBudgetAmount,
|
||||
ActualQuantity: totalActualQuantity,
|
||||
ActualTotalAmount: totalActualAmount,
|
||||
CostPerBird: calculateCostPerBird(totalActualAmount, totalChickinQty),
|
||||
},
|
||||
Overheads: overheadItems,
|
||||
}
|
||||
}
|
||||
|
||||
// === Helper Functions ===
|
||||
|
||||
func getItemInfo(nonstock *entity.Nonstock) (string, string) {
|
||||
if nonstock != nil && nonstock.Id != 0 {
|
||||
return nonstock.Name, nonstock.Uom.Name
|
||||
}
|
||||
return "", ""
|
||||
}
|
||||
|
||||
func calculateTotal(qty, price float64) float64 {
|
||||
return qty * price
|
||||
}
|
||||
|
||||
func calculateCostPerBird(totalPrice, totalChickinQty float64) float64 {
|
||||
if totalChickinQty > 0 {
|
||||
return totalPrice / totalChickinQty
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func formatRealizationDate(realization *entity.ExpenseRealization) string {
|
||||
if realization != nil && realization.ExpenseNonstock != nil && realization.ExpenseNonstock.Expense != nil {
|
||||
if !realization.ExpenseNonstock.Expense.RealizationDate.IsZero() {
|
||||
return realization.ExpenseNonstock.Expense.RealizationDate.Format("2006-01-02T15:04:05Z07:00")
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
@@ -9,7 +9,9 @@ import (
|
||||
commonSvc "gitlab.com/mbugroup/lti-api.git/internal/common/service"
|
||||
rClosing "gitlab.com/mbugroup/lti-api.git/internal/modules/closings/repositories"
|
||||
sClosing "gitlab.com/mbugroup/lti-api.git/internal/modules/closings/services"
|
||||
rExpenseRealization "gitlab.com/mbugroup/lti-api.git/internal/modules/expenses/repositories"
|
||||
rMarketings "gitlab.com/mbugroup/lti-api.git/internal/modules/marketing/sales-orders/repositories"
|
||||
rChickin "gitlab.com/mbugroup/lti-api.git/internal/modules/production/chickins/repositories"
|
||||
rProjectFlock "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/repositories"
|
||||
|
||||
rUser "gitlab.com/mbugroup/lti-api.git/internal/modules/users/repositories"
|
||||
@@ -22,12 +24,15 @@ func (ClosingModule) RegisterRoutes(router fiber.Router, db *gorm.DB, validate *
|
||||
closingRepo := rClosing.NewClosingRepository(db)
|
||||
userRepo := rUser.NewUserRepository(db)
|
||||
projectFlockRepo := rProjectFlock.NewProjectflockRepository(db)
|
||||
projectBudgetRepo := rProjectFlock.NewProjectBudgetRepository(db)
|
||||
marketingRepo := rMarketings.NewMarketingRepository(db)
|
||||
marketingDeliveryProductRepo := rMarketings.NewMarketingDeliveryProductRepository(db)
|
||||
expenseRealizationRepo := rExpenseRealization.NewExpenseRealizationRepository(db)
|
||||
chickinRepo := rChickin.NewChickinRepository(db)
|
||||
approvalRepo := commonRepo.NewApprovalRepository(db)
|
||||
approvalService := commonSvc.NewApprovalService(approvalRepo)
|
||||
|
||||
closingService := sClosing.NewClosingService(closingRepo, projectFlockRepo, marketingRepo, marketingDeliveryProductRepo, approvalService, validate)
|
||||
closingService := sClosing.NewClosingService(closingRepo, projectFlockRepo, marketingRepo, marketingDeliveryProductRepo, approvalService, expenseRealizationRepo, projectBudgetRepo, chickinRepo, validate)
|
||||
userService := sUser.NewUserService(userRepo, validate)
|
||||
|
||||
ClosingRoutes(router, userService, closingService)
|
||||
|
||||
@@ -22,5 +22,7 @@ func ClosingRoutes(v1 fiber.Router, u user.UserService, s closing.ClosingService
|
||||
|
||||
route.Get("/", ctrl.GetAll)
|
||||
route.Get("/:project_flock_id/penjualan", ctrl.GetPenjualan)
|
||||
route.Get("/:project_flock_id/overhead", ctrl.GetOverhead)
|
||||
route.Get("/:projectFlockId", ctrl.GetClosingSummary)
|
||||
|
||||
}
|
||||
|
||||
@@ -9,8 +9,10 @@ import (
|
||||
"gitlab.com/mbugroup/lti-api.git/internal/modules/closings/dto"
|
||||
repository "gitlab.com/mbugroup/lti-api.git/internal/modules/closings/repositories"
|
||||
validation "gitlab.com/mbugroup/lti-api.git/internal/modules/closings/validations"
|
||||
expenseRealizationRepository "gitlab.com/mbugroup/lti-api.git/internal/modules/expenses/repositories"
|
||||
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"
|
||||
chickinRepository "gitlab.com/mbugroup/lti-api.git/internal/modules/production/chickins/repositories"
|
||||
projectflockRepository "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/repositories"
|
||||
"gitlab.com/mbugroup/lti-api.git/internal/utils"
|
||||
approvalutils "gitlab.com/mbugroup/lti-api.git/internal/utils/approvals"
|
||||
@@ -26,6 +28,7 @@ type ClosingService interface {
|
||||
GetProjectFlockByID(ctx *fiber.Ctx, id uint) (*entity.ProjectFlock, error)
|
||||
GetPenjualan(ctx *fiber.Ctx, projectFlockID uint) ([]entity.MarketingDeliveryProduct, error)
|
||||
GetClosingSummary(ctx *fiber.Ctx, projectFlockID uint) (*dto.ClosingSummaryDTO, error)
|
||||
GetOverhead(ctx *fiber.Ctx, projectFlockID uint) (*dto.OverheadListDTO, error)
|
||||
}
|
||||
|
||||
type closingService struct {
|
||||
@@ -36,9 +39,12 @@ type closingService struct {
|
||||
MarketingRepo marketingRepository.MarketingRepository
|
||||
MarketingDeliveryProductRepo marketingDeliveryProductRepository.MarketingDeliveryProductRepository
|
||||
ApprovalSvc commonSvc.ApprovalService
|
||||
ExpenseRealizationRepo expenseRealizationRepository.ExpenseRealizationRepository
|
||||
ProjectBudgetRepo projectflockRepository.ProjectBudgetRepository
|
||||
ChickinRepo chickinRepository.ProjectChickinRepository
|
||||
}
|
||||
|
||||
func NewClosingService(repo repository.ClosingRepository, projectFlockRepo projectflockRepository.ProjectflockRepository, marketingRepo marketingRepository.MarketingRepository, marketingDeliveryProductRepo marketingDeliveryProductRepository.MarketingDeliveryProductRepository, approvalSvc commonSvc.ApprovalService, validate *validator.Validate) ClosingService {
|
||||
func NewClosingService(repo repository.ClosingRepository, projectFlockRepo projectflockRepository.ProjectflockRepository, marketingRepo marketingRepository.MarketingRepository, marketingDeliveryProductRepo marketingDeliveryProductRepository.MarketingDeliveryProductRepository, approvalSvc commonSvc.ApprovalService, expenseRealizationRepo expenseRealizationRepository.ExpenseRealizationRepository, projectBudgetRepo projectflockRepository.ProjectBudgetRepository, chickinRepo chickinRepository.ProjectChickinRepository, validate *validator.Validate) ClosingService {
|
||||
return &closingService{
|
||||
Log: utils.Log,
|
||||
Validate: validate,
|
||||
@@ -47,6 +53,9 @@ func NewClosingService(repo repository.ClosingRepository, projectFlockRepo proje
|
||||
MarketingRepo: marketingRepo,
|
||||
MarketingDeliveryProductRepo: marketingDeliveryProductRepo,
|
||||
ApprovalSvc: approvalSvc,
|
||||
ExpenseRealizationRepo: expenseRealizationRepo,
|
||||
ProjectBudgetRepo: projectBudgetRepo,
|
||||
ChickinRepo: chickinRepo,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -188,3 +197,29 @@ func (s closingService) getApprovalStatuses(ctx context.Context, projectFlockID
|
||||
|
||||
return statusProject, statusClosing, nil
|
||||
}
|
||||
|
||||
func (s closingService) GetOverhead(c *fiber.Ctx, projectFlockID uint) (*dto.OverheadListDTO, error) {
|
||||
budgets, err := s.ProjectBudgetRepo.GetByProjectFlockID(c.Context(), projectFlockID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
realizations, err := s.ExpenseRealizationRepo.GetByProjectFlockID(c.Context(), projectFlockID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
chickins, err := s.ChickinRepo.GetByProjectFlockID(c.Context(), projectFlockID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var totalChickinQty float64
|
||||
for _, chickin := range chickins {
|
||||
totalChickinQty += chickin.UsageQty
|
||||
}
|
||||
|
||||
result := dto.ToOverheadListDTOs(budgets, realizations, totalChickinQty)
|
||||
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ type ExpenseRealizationRepository interface {
|
||||
repository.BaseRepository[entity.ExpenseRealization]
|
||||
IdExists(ctx context.Context, id uint64) (bool, error)
|
||||
GetByExpenseNonstockID(ctx context.Context, expenseNonstockID uint64) (*entity.ExpenseRealization, error)
|
||||
GetByProjectFlockID(ctx context.Context, projectFlockID uint) ([]entity.ExpenseRealization, error)
|
||||
}
|
||||
|
||||
type ExpenseRealizationRepositoryImpl struct {
|
||||
@@ -30,11 +31,22 @@ func (r *ExpenseRealizationRepositoryImpl) IdExists(ctx context.Context, id uint
|
||||
|
||||
func (r *ExpenseRealizationRepositoryImpl) GetByExpenseNonstockID(ctx context.Context, expenseNonstockID uint64) (*entity.ExpenseRealization, error) {
|
||||
var realization entity.ExpenseRealization
|
||||
err := r.DB().WithContext(ctx).
|
||||
Where("expense_nonstock_id = ?", expenseNonstockID).
|
||||
First(&realization).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &realization, nil
|
||||
err := r.DB().WithContext(ctx).Where("expense_nonstock_id = ?", expenseNonstockID).First(&realization).Error
|
||||
return &realization, err
|
||||
}
|
||||
|
||||
func (r *ExpenseRealizationRepositoryImpl) GetByProjectFlockID(ctx context.Context, projectFlockID uint) ([]entity.ExpenseRealization, error) {
|
||||
var realizations []entity.ExpenseRealization
|
||||
err := r.DB().WithContext(ctx).
|
||||
Preload("ExpenseNonstock").
|
||||
Preload("ExpenseNonstock.Nonstock").
|
||||
Preload("ExpenseNonstock.Nonstock.Uom").
|
||||
Preload("ExpenseNonstock.Expense").
|
||||
Joins("JOIN expense_nonstocks ON expense_nonstocks.id = expense_realizations.expense_nonstock_id").
|
||||
Joins("JOIN project_flock_kandangs ON project_flock_kandangs.id = expense_nonstocks.project_flock_kandang_id").
|
||||
Joins("JOIN expenses ON expenses.id = expense_nonstocks.expense_id").
|
||||
Where("project_flock_kandangs.project_flock_id = ?", projectFlockID).
|
||||
Where("expenses.category = ?", "BOP").
|
||||
Find(&realizations).Error
|
||||
return realizations, err
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
commonRepo "gitlab.com/mbugroup/lti-api.git/internal/common/repository"
|
||||
commonSvc "gitlab.com/mbugroup/lti-api.git/internal/common/service"
|
||||
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
|
||||
middleware "gitlab.com/mbugroup/lti-api.git/internal/middleware"
|
||||
expenseDto "gitlab.com/mbugroup/lti-api.git/internal/modules/expenses/dto"
|
||||
repository "gitlab.com/mbugroup/lti-api.git/internal/modules/expenses/repositories"
|
||||
validation "gitlab.com/mbugroup/lti-api.git/internal/modules/expenses/validations"
|
||||
@@ -188,7 +189,11 @@ func (s *expenseService) CreateOne(c *fiber.Ctx, req *validation.Create) (*expen
|
||||
return fiber.NewError(fiber.StatusInternalServerError, "Failed to generate reference number")
|
||||
}
|
||||
|
||||
createdBy := uint64(1) //todo get from auth
|
||||
actorID, err := middleware.ActorIDFromContext(c)
|
||||
if err != nil {
|
||||
return fiber.NewError(fiber.StatusUnauthorized, "Failed to get actor ID from context")
|
||||
}
|
||||
createdBy := uint64(actorID)
|
||||
expense = &entity.Expense{
|
||||
ReferenceNumber: referenceNumber,
|
||||
PoNumber: req.PoNumber,
|
||||
@@ -496,7 +501,10 @@ func (s expenseService) UpdateOne(c *fiber.Ctx, req *validation.Update, id uint)
|
||||
}
|
||||
}
|
||||
|
||||
actorID := uint(1) // TODO: replace with authenticated user id
|
||||
actorID, err := middleware.ActorIDFromContext(c)
|
||||
if err != nil {
|
||||
return fiber.NewError(fiber.StatusUnauthorized, "Failed to get actor ID from context")
|
||||
}
|
||||
if *latestApproval.Action != entity.ApprovalActionUpdated {
|
||||
|
||||
approvalAction := entity.ApprovalActionUpdated
|
||||
@@ -655,7 +663,10 @@ func (s *expenseService) CompleteExpense(c *fiber.Ctx, id uint, notes *string) (
|
||||
return nil, err
|
||||
}
|
||||
|
||||
actorID := uint(1) // TODO: replace with authenticated user id
|
||||
actorID, err := middleware.ActorIDFromContext(c)
|
||||
if err != nil {
|
||||
return nil, fiber.NewError(fiber.StatusUnauthorized, "Failed to get actor ID from context")
|
||||
}
|
||||
|
||||
latestApproval, err := s.ApprovalSvc.LatestByTarget(c.Context(), utils.ApprovalWorkflowExpense, id, nil)
|
||||
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
@@ -960,11 +971,14 @@ func (s *expenseService) Approval(c *fiber.Ctx, req *validation.ApprovalRequest,
|
||||
return nil, fiber.NewError(fiber.StatusBadRequest, "No expense IDs provided")
|
||||
}
|
||||
|
||||
actorID := uint(1) // TODO: replace with authenticated user id
|
||||
actorID, err := middleware.ActorIDFromContext(c)
|
||||
if err != nil {
|
||||
return nil, fiber.NewError(fiber.StatusUnauthorized, "Failed to get actor ID from context")
|
||||
}
|
||||
|
||||
var results []expenseDto.ExpenseDetailDTO
|
||||
|
||||
err := s.Repository.DB().WithContext(c.Context()).Transaction(func(tx *gorm.DB) error {
|
||||
err = s.Repository.DB().WithContext(c.Context()).Transaction(func(tx *gorm.DB) error {
|
||||
|
||||
approvalSvcTx := commonSvc.NewApprovalService(commonRepo.NewApprovalRepository(tx))
|
||||
expenseRepoTx := repository.NewExpenseRepository(tx)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package adjustments
|
||||
|
||||
import (
|
||||
// m "gitlab.com/mbugroup/lti-api.git/internal/middleware"
|
||||
m "gitlab.com/mbugroup/lti-api.git/internal/middleware"
|
||||
controller "gitlab.com/mbugroup/lti-api.git/internal/modules/inventory/adjustments/controllers"
|
||||
adjustment "gitlab.com/mbugroup/lti-api.git/internal/modules/inventory/adjustments/services"
|
||||
user "gitlab.com/mbugroup/lti-api.git/internal/modules/users/services"
|
||||
@@ -13,7 +13,7 @@ func AdjustmentRoutes(v1 fiber.Router, u user.UserService, s adjustment.Adjustme
|
||||
ctrl := controller.NewAdjustmentController(s)
|
||||
|
||||
route := v1.Group("/adjustments")
|
||||
|
||||
route.Use(m.Auth(u))
|
||||
// Standard CRUD routes following master data pattern
|
||||
route.Get("/", ctrl.AdjustmentHistory) // Get all with pagination and filters
|
||||
route.Post("/", ctrl.Adjustment) // Create adjustment
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
type ProjectChickinRepository interface {
|
||||
repository.BaseRepository[entity.ProjectChickin]
|
||||
GetFirstByProjectFlockID(ctx context.Context, projectFlockID uint) (*entity.ProjectChickin, error)
|
||||
GetByProjectFlockID(ctx context.Context, projectFlockID uint) ([]entity.ProjectChickin, error)
|
||||
GetByProjectFlockKandangID(ctx context.Context, projectFlockKandangID uint) ([]entity.ProjectChickin, error)
|
||||
GetPendingByProjectFlockKandangID(ctx context.Context, projectFlockKandangID uint) ([]entity.ProjectChickin, error)
|
||||
GetTotalPendingUsageQtyByProjectFlockKandangID(ctx context.Context, projectFlockKandangID uint) (float64, error)
|
||||
@@ -40,6 +41,16 @@ func (r *ChickinRepositoryImpl) GetFirstByProjectFlockID(ctx context.Context, pr
|
||||
return &chickin, nil
|
||||
}
|
||||
|
||||
func (r *ChickinRepositoryImpl) GetByProjectFlockID(ctx context.Context, projectFlockID uint) ([]entity.ProjectChickin, error) {
|
||||
var chickins []entity.ProjectChickin
|
||||
err := r.db.WithContext(ctx).
|
||||
Joins("JOIN project_flock_kandangs ON project_flock_kandangs.id = project_chickins.project_flock_kandang_id").
|
||||
Where("project_flock_kandangs.project_flock_id = ?", projectFlockID).
|
||||
Order("project_chickins.created_at DESC").
|
||||
Find(&chickins).Error
|
||||
return chickins, err
|
||||
}
|
||||
|
||||
func (r *ChickinRepositoryImpl) GetByProjectFlockKandangID(ctx context.Context, projectFlockKandangID uint) ([]entity.ProjectChickin, error) {
|
||||
var chickins []entity.ProjectChickin
|
||||
err := r.db.WithContext(ctx).
|
||||
|
||||
@@ -197,7 +197,7 @@ func (s *chickinService) CreateOne(c *fiber.Ctx, req *validation.Create) ([]enti
|
||||
|
||||
if category == string(utils.ProjectFlockCategoryLaying) {
|
||||
for _, chickin := range newChikins {
|
||||
updates := map[string]any{"quantity": gorm.Expr("quantity - ?", chickin.PendingUsageQty)}
|
||||
updates := map[string]any{"qty": gorm.Expr("qty - ?", chickin.PendingUsageQty)}
|
||||
|
||||
if err := productWarehouseTx.PatchOne(c.Context(), chickin.ProductWarehouseId, updates, nil); err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
@@ -498,7 +498,7 @@ func (s chickinService) Approval(c *fiber.Ctx, req *validation.Approve) ([]entit
|
||||
for _, chickin := range chickins {
|
||||
|
||||
if categoryForRejection == string(utils.ProjectFlockCategoryGrowing) {
|
||||
updates := map[string]any{"quantity": gorm.Expr("quantity + ?", chickin.PendingUsageQty)}
|
||||
updates := map[string]any{"qty": gorm.Expr("qty + ?", chickin.PendingUsageQty)}
|
||||
|
||||
if err := productWarehouseTx.PatchOne(c.Context(), chickin.ProductWarehouseId, updates, nil); err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
@@ -600,7 +600,7 @@ func (s *chickinService) convertChickinsToTarget(ctx *fiber.Ctx, chickins []enti
|
||||
|
||||
if chickin.ProductWarehouseId != targetPW.Id {
|
||||
if err := productWarehouseTx.PatchOne(ctx.Context(), chickin.ProductWarehouseId, map[string]any{
|
||||
"quantity": gorm.Expr("quantity - ?", quantityToConvert),
|
||||
"qty": gorm.Expr("qty - ?", quantityToConvert),
|
||||
}, nil); err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return fiber.NewError(fiber.StatusNotFound, fmt.Sprintf("Source product warehouse %d not found", chickin.ProductWarehouseId))
|
||||
@@ -610,7 +610,7 @@ func (s *chickinService) convertChickinsToTarget(ctx *fiber.Ctx, chickins []enti
|
||||
}
|
||||
|
||||
if err := productWarehouseTx.PatchOne(ctx.Context(), targetPW.Id, map[string]any{
|
||||
"quantity": gorm.Expr("quantity + ?", quantityToConvert),
|
||||
"qty": gorm.Expr("qty + ?", quantityToConvert),
|
||||
}, nil); err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return fiber.NewError(fiber.StatusNotFound, fmt.Sprintf("Target product warehouse %d not found", targetPW.Id))
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"gitlab.com/mbugroup/lti-api.git/internal/common/repository"
|
||||
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
|
||||
"gorm.io/gorm"
|
||||
@@ -8,6 +10,7 @@ import (
|
||||
|
||||
type ProjectBudgetRepository interface {
|
||||
repository.BaseRepository[entity.ProjectBudget]
|
||||
GetByProjectFlockID(ctx context.Context, projectFlockID uint) ([]entity.ProjectBudget, error)
|
||||
}
|
||||
|
||||
type ProjectBudgetRepositoryImpl struct {
|
||||
@@ -21,3 +24,13 @@ func NewProjectBudgetRepository(db *gorm.DB) ProjectBudgetRepository {
|
||||
db: db,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *ProjectBudgetRepositoryImpl) GetByProjectFlockID(ctx context.Context, projectFlockID uint) ([]entity.ProjectBudget, error) {
|
||||
var budgets []entity.ProjectBudget
|
||||
err := r.db.WithContext(ctx).
|
||||
Where("project_flock_id = ?", projectFlockID).
|
||||
Preload("Nonstock").
|
||||
Preload("Nonstock.Uom").
|
||||
Find(&budgets).Error
|
||||
return budgets, err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user