diff --git a/internal/app/application/services/box.go b/internal/app/application/services/box.go index c92d58a..7500031 100644 --- a/internal/app/application/services/box.go +++ b/internal/app/application/services/box.go @@ -301,3 +301,36 @@ func (s *BoxService) makeGetAllQueryFilter( return queryFilter } + +func (s *BoxService) TransferItem( + fromBoxID string, + toBoxID string, + itemID string, +) error { + fromBoxItem, err := s.boxRepository.GetBoxItem(fromBoxID, itemID) + if err != nil { + return err + } + + quantity := fromBoxItem.Quantity + + err = s.RemoveItemFromBox( + quantity, + fromBoxID, + itemID, + ) + if err != nil { + return err + } + + _, err = s.AddItemIntoBox( + quantity, + toBoxID, + itemID, + ) + if err != nil { + return err + } + + return nil +} diff --git a/internal/app/application/services/box_test.go b/internal/app/application/services/box_test.go index d24631a..b687fb9 100644 --- a/internal/app/application/services/box_test.go +++ b/internal/app/application/services/box_test.go @@ -598,3 +598,47 @@ func TestBoxServiceCountAllErrorInBoxRepository(t *testing.T) { itemRepository.AssertExpectations(t) roomRepository.AssertExpectations(t) } + +func TestBoxServiceTransferItem(t *testing.T) { + boxRepository := new(stub.BoxRepositoryMock) + roomRepository := new(stub.RoomRepositoryMock) + itemRepository := new(stub.ItemRepositoryMock) + + boxService := NewBoxService(boxRepository, itemRepository, roomRepository) + + originBoxID := uuid.NewString() + destinationBoxID := uuid.NewString() + itemID := uuid.NewString() + + itemRepository.On("GetByID", itemID). + Return(&entities.Item{ + ID: itemID, + }, nil) + boxRepository.On("GetBoxItem", originBoxID, itemID). + Return(&entities.BoxItem{ + BoxID: originBoxID, + ItemID: itemID, + Quantity: 10.0, + }, nil) + boxRepository.On("GetBoxItem", destinationBoxID, itemID). + Return(&entities.BoxItem{ + BoxID: originBoxID, + ItemID: itemID, + Quantity: 10.0, + }, nil) + boxRepository.On("DeleteBoxItem", originBoxID, itemID). + Return(nil) + boxRepository.On("CreateBoxTransaction", mock.AnythingOfType("*entities.BoxTransaction")). + Return(nil) + boxRepository.On("UpdateBoxItem", mock.AnythingOfType("*entities.BoxItem")). + Return(nil) + + err := boxService.TransferItem(originBoxID, destinationBoxID, itemID) + + time.Sleep(2 * time.Second) + + assert.NoError(t, err) + boxRepository.AssertExpectations(t) + itemRepository.AssertExpectations(t) + roomRepository.AssertExpectations(t) +} diff --git a/internal/app/infrastructure/controllers/transfer_item.go b/internal/app/infrastructure/controllers/transfer_item.go new file mode 100644 index 0000000..d28f407 --- /dev/null +++ b/internal/app/infrastructure/controllers/transfer_item.go @@ -0,0 +1,47 @@ +package controllers + +import ( + "github.com/jibaru/home-inventory-api/m/internal/app/application/services" + "github.com/jibaru/home-inventory-api/m/internal/app/infrastructure/responses" + "github.com/labstack/echo/v4" + "net/http" +) + +type TransferItemController struct { + boxService *services.BoxService +} + +type TransferItemRequest struct { + BoxID string `param:"boxID"` + ItemID string `param:"itemID"` + BoxDestinationID string `json:"box_destination_id"` +} + +func NewTransferItemController(boxService *services.BoxService) *TransferItemController { + return &TransferItemController{boxService} +} + +func (c *TransferItemController) Handle(ctx echo.Context) error { + request := TransferItemRequest{} + + err := (&echo.DefaultBinder{}).BindBody(ctx, &request) + if err != nil { + return ctx.JSON(http.StatusBadRequest, responses.NewMessageResponse(err.Error())) + } + + err = (&echo.DefaultBinder{}).BindPathParams(ctx, &request) + if err != nil { + return ctx.JSON(http.StatusBadRequest, responses.NewMessageResponse(err.Error())) + } + + err = c.boxService.TransferItem( + request.BoxID, + request.BoxDestinationID, + request.ItemID, + ) + if err != nil { + return ctx.JSON(http.StatusBadRequest, responses.NewMessageResponse(err.Error())) + } + + return ctx.JSON(http.StatusNoContent, nil) +} diff --git a/internal/app/infrastructure/http/server.go b/internal/app/infrastructure/http/server.go index 72c45a2..01ff5f5 100644 --- a/internal/app/infrastructure/http/server.go +++ b/internal/app/infrastructure/http/server.go @@ -55,6 +55,7 @@ func RunServer( getRoomsController := controllers.NewGetRoomsController(roomService) getBoxesController := controllers.NewGetBoxesController(boxService) getItemsController := controllers.NewGetItemsController(assetService, itemService) + transferItemController := controllers.NewTransferItemController(boxService) loggerMiddleware := middlewares.NewLoggerMiddleware() needsAuthMiddleware := middlewares.NewNeedsAuthMiddleware(authService) @@ -77,6 +78,7 @@ func RunServer( authApi.GET("/rooms", getRoomsController.Handle) authApi.GET("/boxes", getBoxesController.Handle) authApi.GET("/items", getItemsController.Handle) + authApi.POST("/boxes/:boxID/items/:itemID/transfer", transferItemController.Handle) logger.LogError(e.Start(host + ":" + port)) }