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{
@ -186,11 +186,11 @@ 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(),
} }
} }
@ -210,10 +210,11 @@ func ToInventoryRequestLineResponses(linesEntity []entities.TInventoryRequestLin
} }
} }
lines = append(lines, InventoryRequestLineResponse{ lines = append(lines, InventoryRequestLineResponse{
ID: line.ID.String(), ID: line.ID.String(),
Quantity: line.Quantity, Quantity: line.Quantity,
Product: product, Product: product,
ClientID: line.ClientID.String(), CurrentStock: 0,
ClientID: line.ClientID.String(),
}) })
} }
return lines return lines

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"
@ -30,11 +31,12 @@ type InventoryRequestService interface {
} }
type inventoryRequestService struct { type inventoryRequestService struct {
db *gorm.DB db *gorm.DB
requestRepo repository.InventoryRequestRepository requestRepo repository.InventoryRequestRepository
requestLineRepo repository.InventoryRequestLineRepository requestLineRepo repository.InventoryRequestLineRepository
sequenceService sequenceservice.SequenceService invStorageService invstorageservice.InventoryStorageService
log *logrus.Logger sequenceService sequenceservice.SequenceService
log *logrus.Logger
} }
// GetLineById implements InventoryRequestService. // GetLineById implements InventoryRequestService.
@ -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,12 +399,13 @@ 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,
sequenceService: sequenceService, invStorageService: invStorageService,
log: log, sequenceService: sequenceService,
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(