feat: add current stock tracking to inventory request line responses and implement GetNewestByProductId in inventory storage
Deploy Application / deploy (push) Successful in 21s Details

This commit is contained in:
Habib Fatkhul Rohman 2025-12-08 15:08:21 +07:00
parent 8317e10754
commit 923cbaba6a
5 changed files with 83 additions and 27 deletions

View File

@ -172,7 +172,7 @@ func ToInventoryRequestResponse(e entities.TInventoryRequestEntity) InventoryReq
} }
} }
func ToInventoryRequestLineResponse(e entities.TInventoryRequestLineEntity) InventoryRequestLineResponse { func ToInventoryRequestLineResponse(e entities.TInventoryRequestLineEntity, currentStock float64) InventoryRequestLineResponse {
product := InventoryRequestLineProductResponse{} product := InventoryRequestLineProductResponse{}
if e.Product.ID != uuid.Nil { if e.Product.ID != uuid.Nil {
product = InventoryRequestLineProductResponse{ product = InventoryRequestLineProductResponse{
@ -188,7 +188,7 @@ func ToInventoryRequestLineResponse(e entities.TInventoryRequestLineEntity) Inve
return InventoryRequestLineResponse{ return InventoryRequestLineResponse{
ID: e.ID.String(), ID: e.ID.String(),
Quantity: e.Quantity, Quantity: e.Quantity,
// CurrentStock: e.CurrentStock, CurrentStock: currentStock,
Product: product, Product: product,
ClientID: e.ClientID.String(), ClientID: e.ClientID.String(),
} }
@ -213,6 +213,7 @@ func ToInventoryRequestLineResponses(linesEntity []entities.TInventoryRequestLin
ID: line.ID.String(), ID: line.ID.String(),
Quantity: line.Quantity, Quantity: line.Quantity,
Product: product, Product: product,
CurrentStock: 0,
ClientID: line.ClientID.String(), ClientID: line.ClientID.String(),
}) })
} }

View File

@ -7,6 +7,7 @@ import (
dtodomain "github.com/Caknoooo/go-gin-clean-starter/modules/inventory_request/dto" dtodomain "github.com/Caknoooo/go-gin-clean-starter/modules/inventory_request/dto"
"github.com/Caknoooo/go-gin-clean-starter/modules/inventory_request/query" "github.com/Caknoooo/go-gin-clean-starter/modules/inventory_request/query"
"github.com/Caknoooo/go-gin-clean-starter/modules/inventory_request/repository" "github.com/Caknoooo/go-gin-clean-starter/modules/inventory_request/repository"
invstorageservice "github.com/Caknoooo/go-gin-clean-starter/modules/inventory_storage/service"
sequenceservice "github.com/Caknoooo/go-gin-clean-starter/modules/sequence/service" sequenceservice "github.com/Caknoooo/go-gin-clean-starter/modules/sequence/service"
"github.com/Caknoooo/go-gin-clean-starter/pkg/constants" "github.com/Caknoooo/go-gin-clean-starter/pkg/constants"
pkgdto "github.com/Caknoooo/go-gin-clean-starter/pkg/dto" pkgdto "github.com/Caknoooo/go-gin-clean-starter/pkg/dto"
@ -33,6 +34,7 @@ type inventoryRequestService struct {
db *gorm.DB db *gorm.DB
requestRepo repository.InventoryRequestRepository requestRepo repository.InventoryRequestRepository
requestLineRepo repository.InventoryRequestLineRepository requestLineRepo repository.InventoryRequestLineRepository
invStorageService invstorageservice.InventoryStorageService
sequenceService sequenceservice.SequenceService sequenceService sequenceservice.SequenceService
log *logrus.Logger log *logrus.Logger
} }
@ -43,7 +45,17 @@ func (s *inventoryRequestService) GetLineById(ctx context.Context, lineId string
if err != nil { if err != nil {
return dtodomain.InventoryRequestLineResponse{}, err return dtodomain.InventoryRequestLineResponse{}, err
} }
return dtodomain.ToInventoryRequestLineResponse(line), nil
var currentStock float64
if line.ProductID != uuid.Nil {
storage, err := s.invStorageService.GetNewestByProductId(ctx, line.ProductID.String())
if err != nil {
return dtodomain.InventoryRequestLineResponse{}, err
}
currentStock = storage.AvailableQuantity
}
return dtodomain.ToInventoryRequestLineResponse(line, currentStock), nil
} }
// GetLinesByRequestId implements InventoryRequestService. // GetLinesByRequestId implements InventoryRequestService.
@ -52,7 +64,18 @@ func (s *inventoryRequestService) GetLinesByRequestId(ctx context.Context, reque
if err != nil { if err != nil {
return nil, err return nil, err
} }
return dtodomain.ToInventoryRequestLineResponses(lines), nil responses := make([]dtodomain.InventoryRequestLineResponse, 0)
for _, line := range lines {
var currentStock float64
if line.ProductID != uuid.Nil {
storage, err := s.invStorageService.GetNewestByProductId(ctx, line.ProductID.String())
if err == nil {
currentStock = storage.AvailableQuantity
}
}
responses = append(responses, dtodomain.ToInventoryRequestLineResponse(line, currentStock))
}
return responses, nil
} }
func (s *inventoryRequestService) DeleteLine(ctx context.Context, lineId string) error { func (s *inventoryRequestService) DeleteLine(ctx context.Context, lineId string) error {
@ -376,11 +399,12 @@ func (s *inventoryRequestService) CreateLine(ctx context.Context, requestId stri
}, nil }, nil
} }
func NewInventoryRequestService(db *gorm.DB, requestRepo repository.InventoryRequestRepository, requestLineRepo repository.InventoryRequestLineRepository, sequenceService sequenceservice.SequenceService, log *logrus.Logger) InventoryRequestService { func NewInventoryRequestService(db *gorm.DB, requestRepo repository.InventoryRequestRepository, requestLineRepo repository.InventoryRequestLineRepository, invStorageService invstorageservice.InventoryStorageService, sequenceService sequenceservice.SequenceService, log *logrus.Logger) InventoryRequestService {
return &inventoryRequestService{ return &inventoryRequestService{
db: db, db: db,
requestRepo: requestRepo, requestRepo: requestRepo,
requestLineRepo: requestLineRepo, requestLineRepo: requestLineRepo,
invStorageService: invStorageService,
sequenceService: sequenceService, sequenceService: sequenceService,
log: log, log: log,
} }

View File

@ -18,12 +18,33 @@ type InventoryStorageRepository interface {
BulkCreate(ctx context.Context, tx *gorm.DB, inventoryStorages []entities.InventoryStorageEntity) error BulkCreate(ctx context.Context, tx *gorm.DB, inventoryStorages []entities.InventoryStorageEntity) error
GetLatestByProductAndClient(ctx context.Context, tx *gorm.DB, productId string, clientId string) (entities.InventoryStorageEntity, error) GetLatestByProductAndClient(ctx context.Context, tx *gorm.DB, productId string, clientId string) (entities.InventoryStorageEntity, error)
GetStoragesByProductAndClient(ctx context.Context, tx *gorm.DB, productId string, clientId string) ([]entities.InventoryStorageEntity, error) GetStoragesByProductAndClient(ctx context.Context, tx *gorm.DB, productId string, clientId string) ([]entities.InventoryStorageEntity, error)
GetNewestByProductId(ctx context.Context, tx *gorm.DB, productId string) (entities.InventoryStorageEntity, error)
} }
type inventoryStorageRepository struct { type inventoryStorageRepository struct {
db *gorm.DB db *gorm.DB
} }
// GetNewestByProductId implements InventoryStorageRepository.
func (r *inventoryStorageRepository) GetNewestByProductId(ctx context.Context, tx *gorm.DB, productId string) (entities.InventoryStorageEntity, error) {
if tx == nil {
tx = r.db
}
var inventoryStorage entities.InventoryStorageEntity
if err := tx.WithContext(ctx).
Preload("Product").
Preload("Aisle").
Preload("Uom").
Preload("Client").
// Preload("InvRequest").
// Preload("InvReceipt").
Order("created_at DESC").
First(&inventoryStorage, "product_id = ?", productId).Error; err != nil {
return inventoryStorage, err
}
return inventoryStorage, nil
}
// GetStoragesByProductAndClient implements InventoryStorageRepository. // GetStoragesByProductAndClient implements InventoryStorageRepository.
func (r *inventoryStorageRepository) GetStoragesByProductAndClient(ctx context.Context, tx *gorm.DB, productId string, clientId string) ([]entities.InventoryStorageEntity, error) { func (r *inventoryStorageRepository) GetStoragesByProductAndClient(ctx context.Context, tx *gorm.DB, productId string, clientId string) ([]entities.InventoryStorageEntity, error) {
if tx == nil { if tx == nil {

View File

@ -20,6 +20,7 @@ type InventoryStorageService interface {
GetAll(ctx context.Context, filter query.InventoryStorageFilter) ([]dtodomain.InventoryStorageResponse, int64, error) GetAll(ctx context.Context, filter query.InventoryStorageFilter) ([]dtodomain.InventoryStorageResponse, int64, error)
Update(ctx context.Context, req dtodomain.InventoryStorageUpdateRequest, inventoryStorageId string) (dtodomain.InventoryStorageResponse, error) Update(ctx context.Context, req dtodomain.InventoryStorageUpdateRequest, inventoryStorageId string) (dtodomain.InventoryStorageResponse, error)
Delete(ctx context.Context, inventoryStorageId string) error Delete(ctx context.Context, inventoryStorageId string) error
GetNewestByProductId(ctx context.Context, productId string) (dtodomain.InventoryStorageResponse, error)
} }
type inventoryStorageService struct { type inventoryStorageService struct {
@ -28,6 +29,15 @@ type inventoryStorageService struct {
log *logrus.Logger log *logrus.Logger
} }
// GetNewestByProductId implements InventoryStorageService.
func (s *inventoryStorageService) GetNewestByProductId(ctx context.Context, productId string) (dtodomain.InventoryStorageResponse, error) {
inventoryStorage, err := s.inventoryStorageRepo.GetNewestByProductId(ctx, nil, productId)
if err != nil {
return dtodomain.InventoryStorageResponse{}, err
}
return dtodomain.ToInventoryStorageResponse(inventoryStorage), nil
}
func (s *inventoryStorageService) Create(ctx context.Context, req dtodomain.InventoryStorageCreateRequest) (dtodomain.InventoryStorageResponse, error) { func (s *inventoryStorageService) Create(ctx context.Context, req dtodomain.InventoryStorageCreateRequest) (dtodomain.InventoryStorageResponse, error) {
tx := s.db.Begin() tx := s.db.Begin()
defer func() { defer func() {

View File

@ -187,14 +187,14 @@ func RegisterDependencies(injector *do.Injector) {
warehouseServ := warehouseService.NewWarehouseService(warehouseRepository, db, log) warehouseServ := warehouseService.NewWarehouseService(warehouseRepository, db, log)
zonaServ := zonaService.NewZonaService(zonaRepository, db, log) zonaServ := zonaService.NewZonaService(zonaRepository, db, log)
aisleServ := aisleService.NewAisleService(aisleRepository, db, log) aisleServ := aisleService.NewAisleService(aisleRepository, db, log)
inventoryStorageServ := inventoryStorageService.NewInventoryStorageService(db, inventoryStorageRepository, log)
inventoryTransactionServ := inventoryTransactionService.NewInventoryTransactionService(db, inventoryTransactionRepository, log)
inventoryReceiptServ := inventoryReceiptService.NewInventoryReceiptService(db, inventoryReceiptRepository, inventoryReceiptLineRepository, productRepository, uomRepository, inventoryStorageRepository, sequenceServ, log) inventoryReceiptServ := inventoryReceiptService.NewInventoryReceiptService(db, inventoryReceiptRepository, inventoryReceiptLineRepository, productRepository, uomRepository, inventoryStorageRepository, sequenceServ, log)
assignmentServ := assignmentService.NewAssignmentService(db, assignmentRepository, assignmentUserRepository) assignmentServ := assignmentService.NewAssignmentService(db, assignmentRepository, assignmentUserRepository)
inventoryRequestServ := inventoryRequestService.NewInventoryRequestService(db, inventoryRequestRepository, inventoryRequestLineRepository, sequenceServ, log) inventoryRequestServ := inventoryRequestService.NewInventoryRequestService(db, inventoryRequestRepository, inventoryRequestLineRepository, inventoryStorageServ, sequenceServ, log)
inventoryIssueServ := inventoryIssueService.NewInventoryIssueService(db, inventoryIssueRepository, inventoryIssueLineRepository, sequenceServ, log) inventoryIssueServ := inventoryIssueService.NewInventoryIssueService(db, inventoryIssueRepository, inventoryIssueLineRepository, sequenceServ, log)
inventoryReturnServ := inventoryReturnService.NewInventoryReturnService(db, inventoryReturnRepository, inventoryReturnLineRepository, inventoryIssueLineRepository, productRepository, sequenceServ, log) inventoryReturnServ := inventoryReturnService.NewInventoryReturnService(db, inventoryReturnRepository, inventoryReturnLineRepository, inventoryIssueLineRepository, productRepository, sequenceServ, log)
inventoryMovementServ := inventoryMovementService.NewInventoryMovementService(db, inventoryMovementRepository, inventoryMovementLineRepository, sequenceServ, log) inventoryMovementServ := inventoryMovementService.NewInventoryMovementService(db, inventoryMovementRepository, inventoryMovementLineRepository, sequenceServ, log)
inventoryStorageService := inventoryStorageService.NewInventoryStorageService(db, inventoryStorageRepository, log)
inventoryTransactionServ := inventoryTransactionService.NewInventoryTransactionService(db, inventoryTransactionRepository, log)
quarantineServ := quarantineService.NewQuarantineService(db, quarantineRepository, quarantineLineRepository, productRepository, uomRepository, inventoryStorageRepository) quarantineServ := quarantineService.NewQuarantineService(db, quarantineRepository, quarantineLineRepository, productRepository, uomRepository, inventoryStorageRepository)
// Controller // Controller
@ -305,7 +305,7 @@ func RegisterDependencies(injector *do.Injector) {
) )
do.Provide( do.Provide(
injector, func(i *do.Injector) (inventoryStorageController.InventoryStorageController, error) { injector, func(i *do.Injector) (inventoryStorageController.InventoryStorageController, error) {
return inventoryStorageController.NewInventoryStorageController(i, inventoryStorageService), nil return inventoryStorageController.NewInventoryStorageController(i, inventoryStorageServ), nil
}, },
) )
do.Provide( do.Provide(