add total out
This commit is contained in:
parent
07b3eda263
commit
13d8c75be7
@ -210,7 +210,7 @@ func (a *App) initProcessors(cfg *config.Config, repos *repositories) *processor
|
|||||||
categoryProcessor: processor.NewCategoryProcessorImpl(repos.categoryRepo),
|
categoryProcessor: processor.NewCategoryProcessorImpl(repos.categoryRepo),
|
||||||
productProcessor: processor.NewProductProcessorImpl(repos.productRepo, repos.categoryRepo, repos.productVariantRepo, repos.inventoryRepo, repos.outletRepo),
|
productProcessor: processor.NewProductProcessorImpl(repos.productRepo, repos.categoryRepo, repos.productVariantRepo, repos.inventoryRepo, repos.outletRepo),
|
||||||
productVariantProcessor: processor.NewProductVariantProcessorImpl(repos.productVariantRepo, repos.productRepo),
|
productVariantProcessor: processor.NewProductVariantProcessorImpl(repos.productVariantRepo, repos.productRepo),
|
||||||
inventoryProcessor: processor.NewInventoryProcessorImpl(repos.inventoryRepo, repos.productRepo, repos.outletRepo),
|
inventoryProcessor: processor.NewInventoryProcessorImpl(repos.inventoryRepo, repos.productRepo, repos.outletRepo, repos.ingredientRepo, repos.inventoryMovementRepo),
|
||||||
orderProcessor: processor.NewOrderProcessorImpl(repos.orderRepo, repos.orderItemRepo, repos.paymentRepo, repos.paymentOrderItemRepo, repos.productRepo, repos.paymentMethodRepo, repos.inventoryRepo, repos.inventoryMovementRepo, repos.productVariantRepo, repos.outletRepo, repos.customerRepo, repos.txManager, repos.productRecipeRepo, repos.ingredientRepo, inventoryMovementService),
|
orderProcessor: processor.NewOrderProcessorImpl(repos.orderRepo, repos.orderItemRepo, repos.paymentRepo, repos.paymentOrderItemRepo, repos.productRepo, repos.paymentMethodRepo, repos.inventoryRepo, repos.inventoryMovementRepo, repos.productVariantRepo, repos.outletRepo, repos.customerRepo, repos.txManager, repos.productRecipeRepo, repos.ingredientRepo, inventoryMovementService),
|
||||||
paymentMethodProcessor: processor.NewPaymentMethodProcessorImpl(repos.paymentMethodRepo),
|
paymentMethodProcessor: processor.NewPaymentMethodProcessorImpl(repos.paymentMethodRepo),
|
||||||
fileProcessor: processor.NewFileProcessorImpl(repos.fileRepo, fileClient),
|
fileProcessor: processor.NewFileProcessorImpl(repos.fileRepo, fileClient),
|
||||||
|
|||||||
@ -1,8 +1,9 @@
|
|||||||
package contract
|
package contract
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/google/uuid"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
)
|
)
|
||||||
|
|
||||||
type CreateInventoryRequest struct {
|
type CreateInventoryRequest struct {
|
||||||
@ -24,6 +25,18 @@ type AdjustInventoryRequest struct {
|
|||||||
Reason string `json:"reason" validate:"required,min=1,max=255"`
|
Reason string `json:"reason" validate:"required,min=1,max=255"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type RestockInventoryRequest struct {
|
||||||
|
OutletID uuid.UUID `json:"outlet_id" validate:"required"`
|
||||||
|
Items []RestockItem `json:"items" validate:"required,min=1,dive"`
|
||||||
|
Reason string `json:"reason" validate:"required,min=1,max=255"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type RestockItem struct {
|
||||||
|
ItemID uuid.UUID `json:"item_id" validate:"required"`
|
||||||
|
ItemType string `json:"item_type" validate:"required,oneof=PRODUCT INGREDIENT"`
|
||||||
|
Quantity int `json:"quantity" validate:"required,min=1"`
|
||||||
|
}
|
||||||
|
|
||||||
type ListInventoryRequest struct {
|
type ListInventoryRequest struct {
|
||||||
OutletID *uuid.UUID `json:"outlet_id,omitempty"`
|
OutletID *uuid.UUID `json:"outlet_id,omitempty"`
|
||||||
ProductID *uuid.UUID `json:"product_id,omitempty"`
|
ProductID *uuid.UUID `json:"product_id,omitempty"`
|
||||||
@ -68,6 +81,24 @@ type InventoryAdjustmentResponse struct {
|
|||||||
AdjustedAt time.Time `json:"adjusted_at"`
|
AdjustedAt time.Time `json:"adjusted_at"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type RestockInventoryResponse struct {
|
||||||
|
OutletID uuid.UUID `json:"outlet_id"`
|
||||||
|
Items []RestockItemResult `json:"items"`
|
||||||
|
Reason string `json:"reason"`
|
||||||
|
RestockedAt time.Time `json:"restocked_at"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type RestockItemResult struct {
|
||||||
|
ItemID uuid.UUID `json:"item_id"`
|
||||||
|
ItemType string `json:"item_type"`
|
||||||
|
ItemName string `json:"item_name"`
|
||||||
|
PreviousQty int `json:"previous_quantity"`
|
||||||
|
NewQty int `json:"new_quantity"`
|
||||||
|
AddedQty int `json:"added_quantity"`
|
||||||
|
Success bool `json:"success"`
|
||||||
|
Error string `json:"error,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
// Inventory Report Contracts
|
// Inventory Report Contracts
|
||||||
type InventoryReportSummaryResponse struct {
|
type InventoryReportSummaryResponse struct {
|
||||||
TotalProducts int `json:"total_products"`
|
TotalProducts int `json:"total_products"`
|
||||||
|
|||||||
@ -238,6 +238,34 @@ func (h *InventoryHandler) AdjustInventory(c *gin.Context) {
|
|||||||
util.HandleResponse(c.Writer, c.Request, inventoryResponse, "InventoryHandler::AdjustInventory")
|
util.HandleResponse(c.Writer, c.Request, inventoryResponse, "InventoryHandler::AdjustInventory")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *InventoryHandler) RestockInventory(c *gin.Context) {
|
||||||
|
ctx := c.Request.Context()
|
||||||
|
|
||||||
|
var req contract.RestockInventoryRequest
|
||||||
|
if err := c.ShouldBindJSON(&req); err != nil {
|
||||||
|
logger.FromContext(c.Request.Context()).WithError(err).Error("InventoryHandler::RestockInventory -> request binding failed")
|
||||||
|
validationResponseError := contract.NewResponseError(constants.MissingFieldErrorCode, constants.RequestEntity, err.Error())
|
||||||
|
util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{validationResponseError}), "InventoryHandler::RestockInventory")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Add validation for restock request
|
||||||
|
// validationError, validationErrorCode := h.inventoryValidator.ValidateRestockInventoryRequest(&req)
|
||||||
|
// if validationError != nil {
|
||||||
|
// validationResponseError := contract.NewResponseError(validationErrorCode, constants.RequestEntity, validationError.Error())
|
||||||
|
// util.HandleResponse(c.Writer, c.Request, contract.BuildErrorResponse([]*contract.ResponseError{validationResponseError}), "InventoryHandler::RestockInventory")
|
||||||
|
// return
|
||||||
|
// }
|
||||||
|
|
||||||
|
inventoryResponse := h.inventoryService.RestockInventory(ctx, &req)
|
||||||
|
if inventoryResponse.HasErrors() {
|
||||||
|
errorResp := inventoryResponse.GetErrors()[0]
|
||||||
|
logger.FromContext(ctx).WithError(errorResp).Error("InventoryHandler::RestockInventory -> Failed to restock inventory from service")
|
||||||
|
}
|
||||||
|
|
||||||
|
util.HandleResponse(c.Writer, c.Request, inventoryResponse, "InventoryHandler::RestockInventory")
|
||||||
|
}
|
||||||
|
|
||||||
func (h *InventoryHandler) GetLowStockItems(c *gin.Context) {
|
func (h *InventoryHandler) GetLowStockItems(c *gin.Context) {
|
||||||
ctx := c.Request.Context()
|
ctx := c.Request.Context()
|
||||||
|
|
||||||
|
|||||||
@ -1,10 +1,13 @@
|
|||||||
package processor
|
package processor
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"apskel-pos-be/internal/appcontext"
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"apskel-pos-be/internal/contract"
|
||||||
|
"apskel-pos-be/internal/entities"
|
||||||
"apskel-pos-be/internal/mappers"
|
"apskel-pos-be/internal/mappers"
|
||||||
"apskel-pos-be/internal/models"
|
"apskel-pos-be/internal/models"
|
||||||
"apskel-pos-be/internal/repository"
|
"apskel-pos-be/internal/repository"
|
||||||
@ -26,6 +29,7 @@ type InventoryProcessor interface {
|
|||||||
AdjustQuantity(ctx context.Context, productID, outletID, organizationID uuid.UUID, delta int) (*models.InventoryResponse, error)
|
AdjustQuantity(ctx context.Context, productID, outletID, organizationID uuid.UUID, delta int) (*models.InventoryResponse, error)
|
||||||
SetQuantity(ctx context.Context, productID, outletID, organizationID uuid.UUID, quantity int) (*models.InventoryResponse, error)
|
SetQuantity(ctx context.Context, productID, outletID, organizationID uuid.UUID, quantity int) (*models.InventoryResponse, error)
|
||||||
UpdateReorderLevel(ctx context.Context, id uuid.UUID, reorderLevel int, organizationID uuid.UUID) error
|
UpdateReorderLevel(ctx context.Context, id uuid.UUID, reorderLevel int, organizationID uuid.UUID) error
|
||||||
|
RestockInventory(ctx context.Context, outletID uuid.UUID, items []contract.RestockItem, reason string) (*contract.RestockInventoryResponse, error)
|
||||||
GetInventoryReportSummary(ctx context.Context, outletID, organizationID uuid.UUID, dateFrom, dateTo *time.Time) (*models.InventoryReportSummary, error)
|
GetInventoryReportSummary(ctx context.Context, outletID, organizationID uuid.UUID, dateFrom, dateTo *time.Time) (*models.InventoryReportSummary, error)
|
||||||
GetInventoryReportDetails(ctx context.Context, filter *models.InventoryReportFilter, organizationID uuid.UUID) (*models.InventoryReportDetail, error)
|
GetInventoryReportDetails(ctx context.Context, filter *models.InventoryReportFilter, organizationID uuid.UUID) (*models.InventoryReportDetail, error)
|
||||||
}
|
}
|
||||||
@ -34,17 +38,23 @@ type InventoryProcessorImpl struct {
|
|||||||
inventoryRepo repository.InventoryRepository
|
inventoryRepo repository.InventoryRepository
|
||||||
productRepo ProductRepository
|
productRepo ProductRepository
|
||||||
outletRepo OutletRepository
|
outletRepo OutletRepository
|
||||||
|
ingredientRepo IngredientRepository
|
||||||
|
inventoryMovementRepo repository.InventoryMovementRepository
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewInventoryProcessorImpl(
|
func NewInventoryProcessorImpl(
|
||||||
inventoryRepo repository.InventoryRepository,
|
inventoryRepo repository.InventoryRepository,
|
||||||
productRepo ProductRepository,
|
productRepo ProductRepository,
|
||||||
outletRepo OutletRepository,
|
outletRepo OutletRepository,
|
||||||
|
ingredientRepo IngredientRepository,
|
||||||
|
inventoryMovementRepo repository.InventoryMovementRepository,
|
||||||
) *InventoryProcessorImpl {
|
) *InventoryProcessorImpl {
|
||||||
return &InventoryProcessorImpl{
|
return &InventoryProcessorImpl{
|
||||||
inventoryRepo: inventoryRepo,
|
inventoryRepo: inventoryRepo,
|
||||||
productRepo: productRepo,
|
productRepo: productRepo,
|
||||||
outletRepo: outletRepo,
|
outletRepo: outletRepo,
|
||||||
|
ingredientRepo: ingredientRepo,
|
||||||
|
inventoryMovementRepo: inventoryMovementRepo,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -401,3 +411,165 @@ func (p *InventoryProcessorImpl) GetZeroStockItems(ctx context.Context, outletID
|
|||||||
|
|
||||||
return responses, nil
|
return responses, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (p *InventoryProcessorImpl) RestockInventory(ctx context.Context, outletID uuid.UUID, items []contract.RestockItem, reason string) (*contract.RestockInventoryResponse, error) {
|
||||||
|
outlet, err := p.outletRepo.GetByID(ctx, outletID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("invalid outlet: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(items) == 0 {
|
||||||
|
return nil, fmt.Errorf("no items provided for restocking")
|
||||||
|
}
|
||||||
|
|
||||||
|
restockResults := make([]contract.RestockItemResult, 0, len(items))
|
||||||
|
restockedAt := time.Now()
|
||||||
|
|
||||||
|
for _, item := range items {
|
||||||
|
result := contract.RestockItemResult{
|
||||||
|
ItemID: item.ItemID,
|
||||||
|
ItemType: item.ItemType,
|
||||||
|
AddedQty: item.Quantity,
|
||||||
|
Success: false,
|
||||||
|
}
|
||||||
|
|
||||||
|
switch item.ItemType {
|
||||||
|
case "PRODUCT":
|
||||||
|
if err := p.restockProduct(ctx, outletID, item.ItemID, item.Quantity, reason, outlet.OrganizationID); err != nil {
|
||||||
|
result.Error = err.Error()
|
||||||
|
}
|
||||||
|
case "INGREDIENT":
|
||||||
|
if err := p.restockIngredient(ctx, outletID, item.ItemID, item.Quantity, reason, outlet.OrganizationID); err != nil {
|
||||||
|
result.Error = err.Error()
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
result.Error = fmt.Sprintf("unsupported item type: %s", item.ItemType)
|
||||||
|
}
|
||||||
|
|
||||||
|
restockResults = append(restockResults, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &contract.RestockInventoryResponse{
|
||||||
|
OutletID: outletID,
|
||||||
|
Items: restockResults,
|
||||||
|
Reason: reason,
|
||||||
|
RestockedAt: restockedAt,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *InventoryProcessorImpl) restockProduct(ctx context.Context, outletID, productID uuid.UUID, quantity int, reason string, organizationID uuid.UUID) error {
|
||||||
|
contextInfo := appcontext.FromGinContext(ctx)
|
||||||
|
|
||||||
|
var previousQuantity int
|
||||||
|
var newQuantity int
|
||||||
|
|
||||||
|
inventory, err := p.inventoryRepo.GetByProductAndOutlet(ctx, productID, outletID)
|
||||||
|
if err != nil {
|
||||||
|
createReq := &models.CreateInventoryRequest{
|
||||||
|
OutletID: outletID,
|
||||||
|
ProductID: productID,
|
||||||
|
Quantity: quantity,
|
||||||
|
ReorderLevel: 0,
|
||||||
|
}
|
||||||
|
inventoryEntity := mappers.CreateInventoryRequestToEntity(createReq)
|
||||||
|
if err := p.inventoryRepo.Create(ctx, inventoryEntity); err != nil {
|
||||||
|
return fmt.Errorf("failed to create inventory for product %s: %w", productID, err)
|
||||||
|
}
|
||||||
|
previousQuantity = 0
|
||||||
|
newQuantity = quantity
|
||||||
|
} else {
|
||||||
|
previousQuantity = inventory.Quantity
|
||||||
|
newQuantity = inventory.Quantity + quantity
|
||||||
|
updateReq := &models.UpdateInventoryRequest{
|
||||||
|
Quantity: &newQuantity,
|
||||||
|
}
|
||||||
|
mappers.UpdateInventoryEntityFromRequest(inventory, updateReq)
|
||||||
|
|
||||||
|
if err := p.inventoryRepo.Update(ctx, inventory); err != nil {
|
||||||
|
return fmt.Errorf("failed to update inventory for product %s: %w", productID, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
referenceType := entities.InventoryMovementReferenceTypeManual
|
||||||
|
movement := &entities.InventoryMovement{
|
||||||
|
OrganizationID: organizationID,
|
||||||
|
OutletID: outletID,
|
||||||
|
ItemID: productID,
|
||||||
|
ItemType: "PRODUCT",
|
||||||
|
MovementType: entities.InventoryMovementTypePurchase,
|
||||||
|
Quantity: float64(quantity),
|
||||||
|
PreviousQuantity: float64(previousQuantity),
|
||||||
|
NewQuantity: float64(newQuantity),
|
||||||
|
ReferenceType: &referenceType,
|
||||||
|
Reason: &reason,
|
||||||
|
UserID: contextInfo.UserID,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := p.inventoryMovementRepo.Create(ctx, movement); err != nil {
|
||||||
|
return fmt.Errorf("failed to create inventory movement record: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *InventoryProcessorImpl) restockIngredient(ctx context.Context, outletID, ingredientID uuid.UUID, quantity int, reason string, organizationID uuid.UUID) error {
|
||||||
|
contextInfo := appcontext.FromGinContext(ctx)
|
||||||
|
ingredient, err := p.getIngredientByID(ctx, ingredientID, organizationID)
|
||||||
|
if err != nil {
|
||||||
|
return fmt.Errorf("failed to get ingredient %s: %w", ingredientID, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
previousStock := ingredient.Stock
|
||||||
|
newStock := ingredient.Stock + float64(quantity)
|
||||||
|
|
||||||
|
if err := p.updateIngredientStock(ctx, ingredientID, float64(quantity), organizationID); err != nil {
|
||||||
|
return fmt.Errorf("failed to update ingredient stock: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
referenceType := entities.InventoryMovementReferenceTypeManual
|
||||||
|
movement := &entities.InventoryMovement{
|
||||||
|
OrganizationID: organizationID,
|
||||||
|
OutletID: outletID,
|
||||||
|
ItemID: ingredientID,
|
||||||
|
ItemType: "INGREDIENT",
|
||||||
|
MovementType: entities.InventoryMovementTypePurchase,
|
||||||
|
Quantity: float64(quantity),
|
||||||
|
PreviousQuantity: previousStock,
|
||||||
|
NewQuantity: newStock,
|
||||||
|
ReferenceType: &referenceType,
|
||||||
|
Reason: &reason,
|
||||||
|
UserID: contextInfo.UserID,
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := p.inventoryMovementRepo.Create(ctx, movement); err != nil {
|
||||||
|
return fmt.Errorf("failed to create inventory movement record: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *InventoryProcessorImpl) getIngredientByID(ctx context.Context, ingredientID, organizationID uuid.UUID) (*models.Ingredient, error) {
|
||||||
|
ingredient, err := p.ingredientRepo.GetByID(ctx, ingredientID, organizationID)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to get ingredient %s: %w", ingredientID, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &models.Ingredient{
|
||||||
|
ID: ingredient.ID,
|
||||||
|
Name: ingredient.Name,
|
||||||
|
Stock: ingredient.Stock,
|
||||||
|
UnitID: ingredient.UnitID,
|
||||||
|
OrganizationID: ingredient.OrganizationID,
|
||||||
|
OutletID: ingredient.OutletID,
|
||||||
|
IsActive: ingredient.IsActive,
|
||||||
|
CreatedAt: ingredient.CreatedAt,
|
||||||
|
UpdatedAt: ingredient.UpdatedAt,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (p *InventoryProcessorImpl) updateIngredientStock(ctx context.Context, ingredientID uuid.UUID, quantityToAdd float64, organizationID uuid.UUID) error {
|
||||||
|
if err := p.ingredientRepo.UpdateStock(ctx, ingredientID, quantityToAdd, organizationID); err != nil {
|
||||||
|
return fmt.Errorf("failed to update ingredient stock: %w", err)
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|||||||
@ -203,6 +203,7 @@ func (r *Router) addAppRoutes(rg *gin.Engine) {
|
|||||||
inventory.PUT("/:id", r.inventoryHandler.UpdateInventory)
|
inventory.PUT("/:id", r.inventoryHandler.UpdateInventory)
|
||||||
inventory.DELETE("/:id", r.inventoryHandler.DeleteInventory)
|
inventory.DELETE("/:id", r.inventoryHandler.DeleteInventory)
|
||||||
inventory.POST("/adjust", r.inventoryHandler.AdjustInventory)
|
inventory.POST("/adjust", r.inventoryHandler.AdjustInventory)
|
||||||
|
inventory.POST("/restock", r.inventoryHandler.RestockInventory)
|
||||||
inventory.GET("/low-stock/:outlet_id", r.inventoryHandler.GetLowStockItems)
|
inventory.GET("/low-stock/:outlet_id", r.inventoryHandler.GetLowStockItems)
|
||||||
inventory.GET("/zero-stock/:outlet_id", r.inventoryHandler.GetZeroStockItems)
|
inventory.GET("/zero-stock/:outlet_id", r.inventoryHandler.GetZeroStockItems)
|
||||||
inventory.GET("/report/summary/:outlet_id", r.inventoryHandler.GetInventoryReportSummary)
|
inventory.GET("/report/summary/:outlet_id", r.inventoryHandler.GetInventoryReportSummary)
|
||||||
|
|||||||
@ -21,6 +21,7 @@ type InventoryService interface {
|
|||||||
GetInventoryByID(ctx context.Context, id uuid.UUID) *contract.Response
|
GetInventoryByID(ctx context.Context, id uuid.UUID) *contract.Response
|
||||||
ListInventory(ctx context.Context, req *contract.ListInventoryRequest) *contract.Response
|
ListInventory(ctx context.Context, req *contract.ListInventoryRequest) *contract.Response
|
||||||
AdjustInventory(ctx context.Context, req *contract.AdjustInventoryRequest) *contract.Response
|
AdjustInventory(ctx context.Context, req *contract.AdjustInventoryRequest) *contract.Response
|
||||||
|
RestockInventory(ctx context.Context, req *contract.RestockInventoryRequest) *contract.Response
|
||||||
GetLowStockItems(ctx context.Context, outletID uuid.UUID) *contract.Response
|
GetLowStockItems(ctx context.Context, outletID uuid.UUID) *contract.Response
|
||||||
GetZeroStockItems(ctx context.Context, outletID uuid.UUID) *contract.Response
|
GetZeroStockItems(ctx context.Context, outletID uuid.UUID) *contract.Response
|
||||||
GetInventoryReportSummary(ctx context.Context, outletID, organizationID uuid.UUID, dateFrom, dateTo *time.Time) (*contract.InventoryReportSummaryResponse, error)
|
GetInventoryReportSummary(ctx context.Context, outletID, organizationID uuid.UUID, dateFrom, dateTo *time.Time) (*contract.InventoryReportSummaryResponse, error)
|
||||||
@ -153,6 +154,16 @@ func (s *InventoryServiceImpl) AdjustInventory(ctx context.Context, req *contrac
|
|||||||
return contract.BuildSuccessResponse(contractResponse)
|
return contract.BuildSuccessResponse(contractResponse)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *InventoryServiceImpl) RestockInventory(ctx context.Context, req *contract.RestockInventoryRequest) *contract.Response {
|
||||||
|
restockResponse, err := s.inventoryProcessor.RestockInventory(ctx, req.OutletID, req.Items, req.Reason)
|
||||||
|
if err != nil {
|
||||||
|
errorResp := contract.NewResponseError(constants.InternalServerErrorCode, constants.InventoryServiceEntity, err.Error())
|
||||||
|
return contract.BuildErrorResponse([]*contract.ResponseError{errorResp})
|
||||||
|
}
|
||||||
|
|
||||||
|
return contract.BuildSuccessResponse(restockResponse)
|
||||||
|
}
|
||||||
|
|
||||||
func (s *InventoryServiceImpl) GetLowStockItems(ctx context.Context, outletID uuid.UUID) *contract.Response {
|
func (s *InventoryServiceImpl) GetLowStockItems(ctx context.Context, outletID uuid.UUID) *contract.Response {
|
||||||
inventory, err := s.inventoryProcessor.GetLowStock(ctx, outletID, uuid.Nil) // TODO: Get organizationID from context
|
inventory, err := s.inventoryProcessor.GetLowStock(ctx, outletID, uuid.Nil) // TODO: Get organizationID from context
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user