mirror of
https://github.com/ForFarmTeam/ForFarm.git
synced 2025-12-19 22:14:08 +01:00
feat: update inventory API for status, category and harvest relations
This commit is contained in:
parent
b79f3f69f3
commit
022a6e4caa
@ -48,32 +48,66 @@ func (a *api) registerInventoryRoutes(_ chi.Router, api huma.API) {
|
|||||||
Path: prefix + "/{id}",
|
Path: prefix + "/{id}",
|
||||||
Tags: tags,
|
Tags: tags,
|
||||||
}, a.deleteInventoryItemHandler)
|
}, a.deleteInventoryItemHandler)
|
||||||
|
|
||||||
|
huma.Register(api, huma.Operation{
|
||||||
|
OperationID: "getInventoryStatus",
|
||||||
|
Method: http.MethodGet,
|
||||||
|
Path: prefix + "/status",
|
||||||
|
Tags: tags,
|
||||||
|
}, a.getInventoryStatusHandler)
|
||||||
|
|
||||||
|
huma.Register(api, huma.Operation{
|
||||||
|
OperationID: "getInventoryCategory",
|
||||||
|
Method: http.MethodGet,
|
||||||
|
Path: prefix + "/category",
|
||||||
|
Tags: tags,
|
||||||
|
}, a.getInventoryCategoryHandler)
|
||||||
|
|
||||||
|
huma.Register(api, huma.Operation{
|
||||||
|
OperationID: "getHarvestUnits",
|
||||||
|
Method: http.MethodGet,
|
||||||
|
Path: "/harvest/units",
|
||||||
|
Tags: []string{"harvest"},
|
||||||
|
}, a.getHarvestUnitsHandler)
|
||||||
}
|
}
|
||||||
|
|
||||||
type InventoryItemResponse struct {
|
type InventoryItemResponse struct {
|
||||||
ID string `json:"id"`
|
ID string `json:"id"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
Category string `json:"category"`
|
Category InventoryCategory `json:"category"`
|
||||||
Type string `json:"type"`
|
|
||||||
Quantity float64 `json:"quantity"`
|
Quantity float64 `json:"quantity"`
|
||||||
Unit string `json:"unit"`
|
Unit HarvestUnit `json:"unit"`
|
||||||
DateAdded time.Time `json:"date_added"`
|
DateAdded time.Time `json:"date_added"`
|
||||||
Status string `json:"status"`
|
Status InventoryStatus `json:"status"`
|
||||||
CreatedAt time.Time `json:"created_at,omitempty"`
|
CreatedAt time.Time `json:"created_at,omitempty"`
|
||||||
UpdatedAt time.Time `json:"updated_at,omitempty"`
|
UpdatedAt time.Time `json:"updated_at,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type InventoryStatus struct {
|
||||||
|
ID int `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type InventoryCategory struct {
|
||||||
|
ID int `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type HarvestUnit struct {
|
||||||
|
ID int `json:"id"`
|
||||||
|
Name string `json:"name"`
|
||||||
|
}
|
||||||
|
|
||||||
type CreateInventoryItemInput struct {
|
type CreateInventoryItemInput struct {
|
||||||
Header string `header:"Authorization" required:"true" example:"Bearer token"`
|
Header string `header:"Authorization" required:"true" example:"Bearer token"`
|
||||||
UserID string `header:"user_id" required:"true" example:"user-uuid"`
|
UserID string `header:"user_id" required:"true" example:"user-uuid"`
|
||||||
Body struct {
|
Body struct {
|
||||||
Name string `json:"name" required:"true"`
|
Name string `json:"name" required:"true"`
|
||||||
Category string `json:"category" required:"true"`
|
CategoryID int `json:"category_id" required:"true"`
|
||||||
Type string `json:"type" required:"true"`
|
|
||||||
Quantity float64 `json:"quantity" required:"true"`
|
Quantity float64 `json:"quantity" required:"true"`
|
||||||
Unit string `json:"unit" required:"true"`
|
UnitID int `json:"unit_id" required:"true"`
|
||||||
DateAdded time.Time `json:"date_added" required:"true"`
|
DateAdded time.Time `json:"date_added" required:"true"`
|
||||||
Status string `json:"status" required:"true" enum:"In Stock,Low Stock,Out of Stock"`
|
StatusID int `json:"status_id" required:"true"`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,16 +117,83 @@ type CreateInventoryItemOutput struct {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type UpdateInventoryItemInput struct {
|
||||||
|
Header string `header:"Authorization" required:"true" example:"Bearer token"`
|
||||||
|
UserID string `header:"user_id" required:"true" example:"user-uuid"`
|
||||||
|
ID string `path:"id"`
|
||||||
|
Body struct {
|
||||||
|
Name string `json:"name"`
|
||||||
|
CategoryID int `json:"category_id"`
|
||||||
|
Quantity float64 `json:"quantity"`
|
||||||
|
UnitID int `json:"unit_id"`
|
||||||
|
DateAdded time.Time `json:"date_added"`
|
||||||
|
StatusID int `json:"status_id"`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type UpdateInventoryItemOutput struct {
|
||||||
|
Body InventoryItemResponse
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetInventoryItemsInput struct {
|
||||||
|
Header string `header:"Authorization" required:"true" example:"Bearer token"`
|
||||||
|
UserID string `header:"user_id" required:"true" example:"user-uuid"`
|
||||||
|
CategoryID int `query:"category_id"`
|
||||||
|
StatusID int `query:"status_id"`
|
||||||
|
StartDate time.Time `query:"start_date" format:"date-time"`
|
||||||
|
EndDate time.Time `query:"end_date" format:"date-time"`
|
||||||
|
SearchQuery string `query:"search"`
|
||||||
|
SortBy string `query:"sort_by" enum:"name,quantity,date_added,created_at"`
|
||||||
|
SortOrder string `query:"sort_order" enum:"asc,desc" default:"desc"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetInventoryItemsOutput struct {
|
||||||
|
Body []InventoryItemResponse
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetInventoryItemInput struct {
|
||||||
|
Header string `header:"Authorization" required:"true" example:"Bearer token"`
|
||||||
|
UserID string `header:"user_id" required:"true" example:"user-uuid"`
|
||||||
|
ID string `path:"id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetInventoryItemOutput struct {
|
||||||
|
Body InventoryItemResponse
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeleteInventoryItemInput struct {
|
||||||
|
Header string `header:"Authorization" required:"true" example:"Bearer token"`
|
||||||
|
UserID string `header:"user_id" required:"true" example:"user-uuid"`
|
||||||
|
ID string `path:"id"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type DeleteInventoryItemOutput struct {
|
||||||
|
Body struct {
|
||||||
|
Message string `json:"message"`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetInventoryStatusOutput struct {
|
||||||
|
Body []InventoryStatus
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetInventoryCategoryOutput struct {
|
||||||
|
Body []InventoryCategory
|
||||||
|
}
|
||||||
|
|
||||||
|
type GetHarvestUnitsOutput struct {
|
||||||
|
Body []HarvestUnit
|
||||||
|
}
|
||||||
|
|
||||||
func (a *api) createInventoryItemHandler(ctx context.Context, input *CreateInventoryItemInput) (*CreateInventoryItemOutput, error) {
|
func (a *api) createInventoryItemHandler(ctx context.Context, input *CreateInventoryItemInput) (*CreateInventoryItemOutput, error) {
|
||||||
item := &domain.InventoryItem{
|
item := &domain.InventoryItem{
|
||||||
UserID: input.UserID,
|
UserID: input.UserID,
|
||||||
Name: input.Body.Name,
|
Name: input.Body.Name,
|
||||||
Category: input.Body.Category,
|
CategoryID: input.Body.CategoryID,
|
||||||
Type: input.Body.Type,
|
|
||||||
Quantity: input.Body.Quantity,
|
Quantity: input.Body.Quantity,
|
||||||
Unit: input.Body.Unit,
|
UnitID: input.Body.UnitID,
|
||||||
DateAdded: input.Body.DateAdded,
|
DateAdded: input.Body.DateAdded,
|
||||||
Status: domain.InventoryStatus(input.Body.Status),
|
StatusID: input.Body.StatusID,
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := item.Validate(); err != nil {
|
if err := item.Validate(); err != nil {
|
||||||
@ -109,29 +210,11 @@ func (a *api) createInventoryItemHandler(ctx context.Context, input *CreateInven
|
|||||||
}{ID: item.ID}}, nil
|
}{ID: item.ID}}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type GetInventoryItemsInput struct {
|
|
||||||
Header string `header:"Authorization" required:"true" example:"Bearer token"`
|
|
||||||
UserID string `header:"user_id" required:"true" example:"user-uuid"`
|
|
||||||
Category string `query:"category"`
|
|
||||||
Type string `query:"type"`
|
|
||||||
Status string `query:"status" enum:"In Stock,Low Stock,Out of Stock"`
|
|
||||||
StartDate time.Time `query:"start_date" format:"date-time"`
|
|
||||||
EndDate time.Time `query:"end_date" format:"date-time"`
|
|
||||||
SearchQuery string `query:"search"`
|
|
||||||
SortBy string `query:"sort_by" enum:"name,category,type,quantity,date_added,status,created_at"`
|
|
||||||
SortOrder string `query:"sort_order" enum:"asc,desc" default:"desc"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type GetInventoryItemsOutput struct {
|
|
||||||
Body []InventoryItemResponse
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *api) getInventoryItemsByUserHandler(ctx context.Context, input *GetInventoryItemsInput) (*GetInventoryItemsOutput, error) {
|
func (a *api) getInventoryItemsByUserHandler(ctx context.Context, input *GetInventoryItemsInput) (*GetInventoryItemsOutput, error) {
|
||||||
filter := domain.InventoryFilter{
|
filter := domain.InventoryFilter{
|
||||||
UserID: input.UserID,
|
UserID: input.UserID,
|
||||||
Category: input.Category,
|
CategoryID: input.CategoryID,
|
||||||
Type: input.Type,
|
StatusID: input.StatusID,
|
||||||
Status: domain.InventoryStatus(input.Status),
|
|
||||||
StartDate: input.StartDate,
|
StartDate: input.StartDate,
|
||||||
EndDate: input.EndDate,
|
EndDate: input.EndDate,
|
||||||
SearchQuery: input.SearchQuery,
|
SearchQuery: input.SearchQuery,
|
||||||
@ -152,12 +235,20 @@ func (a *api) getInventoryItemsByUserHandler(ctx context.Context, input *GetInve
|
|||||||
response[i] = InventoryItemResponse{
|
response[i] = InventoryItemResponse{
|
||||||
ID: item.ID,
|
ID: item.ID,
|
||||||
Name: item.Name,
|
Name: item.Name,
|
||||||
Category: item.Category,
|
Category: InventoryCategory{
|
||||||
Type: item.Type,
|
ID: item.Category.ID,
|
||||||
|
Name: item.Category.Name,
|
||||||
|
},
|
||||||
Quantity: item.Quantity,
|
Quantity: item.Quantity,
|
||||||
Unit: item.Unit,
|
Unit: HarvestUnit{
|
||||||
|
ID: item.Unit.ID,
|
||||||
|
Name: item.Unit.Name,
|
||||||
|
},
|
||||||
DateAdded: item.DateAdded,
|
DateAdded: item.DateAdded,
|
||||||
Status: string(item.Status),
|
Status: InventoryStatus{
|
||||||
|
ID: item.Status.ID,
|
||||||
|
Name: item.Status.Name,
|
||||||
|
},
|
||||||
CreatedAt: item.CreatedAt,
|
CreatedAt: item.CreatedAt,
|
||||||
UpdatedAt: item.UpdatedAt,
|
UpdatedAt: item.UpdatedAt,
|
||||||
}
|
}
|
||||||
@ -166,16 +257,6 @@ func (a *api) getInventoryItemsByUserHandler(ctx context.Context, input *GetInve
|
|||||||
return &GetInventoryItemsOutput{Body: response}, nil
|
return &GetInventoryItemsOutput{Body: response}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type GetInventoryItemInput struct {
|
|
||||||
Header string `header:"Authorization" required:"true" example:"Bearer token"`
|
|
||||||
UserID string `header:"user_id" required:"true" example:"user-uuid"`
|
|
||||||
ID string `path:"id"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type GetInventoryItemOutput struct {
|
|
||||||
Body InventoryItemResponse
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *api) getInventoryItemHandler(ctx context.Context, input *GetInventoryItemInput) (*GetInventoryItemOutput, error) {
|
func (a *api) getInventoryItemHandler(ctx context.Context, input *GetInventoryItemInput) (*GetInventoryItemOutput, error) {
|
||||||
item, err := a.inventoryRepo.GetByID(ctx, input.ID, input.UserID)
|
item, err := a.inventoryRepo.GetByID(ctx, input.ID, input.UserID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -185,36 +266,25 @@ func (a *api) getInventoryItemHandler(ctx context.Context, input *GetInventoryIt
|
|||||||
return &GetInventoryItemOutput{Body: InventoryItemResponse{
|
return &GetInventoryItemOutput{Body: InventoryItemResponse{
|
||||||
ID: item.ID,
|
ID: item.ID,
|
||||||
Name: item.Name,
|
Name: item.Name,
|
||||||
Category: item.Category,
|
Category: InventoryCategory{
|
||||||
Type: item.Type,
|
ID: item.Category.ID,
|
||||||
|
Name: item.Category.Name,
|
||||||
|
},
|
||||||
Quantity: item.Quantity,
|
Quantity: item.Quantity,
|
||||||
Unit: item.Unit,
|
Unit: HarvestUnit{
|
||||||
|
ID: item.Unit.ID,
|
||||||
|
Name: item.Unit.Name,
|
||||||
|
},
|
||||||
DateAdded: item.DateAdded,
|
DateAdded: item.DateAdded,
|
||||||
Status: string(item.Status),
|
Status: InventoryStatus{
|
||||||
|
ID: item.Status.ID,
|
||||||
|
Name: item.Status.Name,
|
||||||
|
},
|
||||||
CreatedAt: item.CreatedAt,
|
CreatedAt: item.CreatedAt,
|
||||||
UpdatedAt: item.UpdatedAt,
|
UpdatedAt: item.UpdatedAt,
|
||||||
}}, nil
|
}}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type UpdateInventoryItemInput struct {
|
|
||||||
Header string `header:"Authorization" required:"true" example:"Bearer token"`
|
|
||||||
UserID string `header:"user_id" required:"true" example:"user-uuid"`
|
|
||||||
ID string `path:"id"`
|
|
||||||
Body struct {
|
|
||||||
Name string `json:"name"`
|
|
||||||
Category string `json:"category"`
|
|
||||||
Type string `json:"type"`
|
|
||||||
Quantity float64 `json:"quantity"`
|
|
||||||
Unit string `json:"unit"`
|
|
||||||
DateAdded time.Time `json:"date_added"`
|
|
||||||
Status string `json:"status" enum:"In Stock,Low Stock,Out of Stock"`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type UpdateInventoryItemOutput struct {
|
|
||||||
Body InventoryItemResponse
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *api) updateInventoryItemHandler(ctx context.Context, input *UpdateInventoryItemInput) (*UpdateInventoryItemOutput, error) {
|
func (a *api) updateInventoryItemHandler(ctx context.Context, input *UpdateInventoryItemInput) (*UpdateInventoryItemOutput, error) {
|
||||||
item, err := a.inventoryRepo.GetByID(ctx, input.ID, input.UserID)
|
item, err := a.inventoryRepo.GetByID(ctx, input.ID, input.UserID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -224,23 +294,20 @@ func (a *api) updateInventoryItemHandler(ctx context.Context, input *UpdateInven
|
|||||||
if input.Body.Name != "" {
|
if input.Body.Name != "" {
|
||||||
item.Name = input.Body.Name
|
item.Name = input.Body.Name
|
||||||
}
|
}
|
||||||
if input.Body.Category != "" {
|
if input.Body.CategoryID != 0 {
|
||||||
item.Category = input.Body.Category
|
item.CategoryID = input.Body.CategoryID
|
||||||
}
|
|
||||||
if input.Body.Type != "" {
|
|
||||||
item.Type = input.Body.Type
|
|
||||||
}
|
}
|
||||||
if input.Body.Quantity != 0 {
|
if input.Body.Quantity != 0 {
|
||||||
item.Quantity = input.Body.Quantity
|
item.Quantity = input.Body.Quantity
|
||||||
}
|
}
|
||||||
if input.Body.Unit != "" {
|
if input.Body.UnitID != 0 {
|
||||||
item.Unit = input.Body.Unit
|
item.UnitID = input.Body.UnitID
|
||||||
}
|
}
|
||||||
if !input.Body.DateAdded.IsZero() {
|
if !input.Body.DateAdded.IsZero() {
|
||||||
item.DateAdded = input.Body.DateAdded
|
item.DateAdded = input.Body.DateAdded
|
||||||
}
|
}
|
||||||
if input.Body.Status != "" {
|
if input.Body.StatusID != 0 {
|
||||||
item.Status = domain.InventoryStatus(input.Body.Status)
|
item.StatusID = input.Body.StatusID
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := item.Validate(); err != nil {
|
if err := item.Validate(); err != nil {
|
||||||
@ -260,29 +327,25 @@ func (a *api) updateInventoryItemHandler(ctx context.Context, input *UpdateInven
|
|||||||
return &UpdateInventoryItemOutput{Body: InventoryItemResponse{
|
return &UpdateInventoryItemOutput{Body: InventoryItemResponse{
|
||||||
ID: updatedItem.ID,
|
ID: updatedItem.ID,
|
||||||
Name: updatedItem.Name,
|
Name: updatedItem.Name,
|
||||||
Category: updatedItem.Category,
|
Category: InventoryCategory{
|
||||||
Type: updatedItem.Type,
|
ID: updatedItem.Category.ID,
|
||||||
|
Name: updatedItem.Category.Name,
|
||||||
|
},
|
||||||
Quantity: updatedItem.Quantity,
|
Quantity: updatedItem.Quantity,
|
||||||
Unit: updatedItem.Unit,
|
Unit: HarvestUnit{
|
||||||
|
ID: updatedItem.Unit.ID,
|
||||||
|
Name: updatedItem.Unit.Name,
|
||||||
|
},
|
||||||
DateAdded: updatedItem.DateAdded,
|
DateAdded: updatedItem.DateAdded,
|
||||||
Status: string(updatedItem.Status),
|
Status: InventoryStatus{
|
||||||
|
ID: updatedItem.Status.ID,
|
||||||
|
Name: updatedItem.Status.Name,
|
||||||
|
},
|
||||||
CreatedAt: updatedItem.CreatedAt,
|
CreatedAt: updatedItem.CreatedAt,
|
||||||
UpdatedAt: updatedItem.UpdatedAt,
|
UpdatedAt: updatedItem.UpdatedAt,
|
||||||
}}, nil
|
}}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type DeleteInventoryItemInput struct {
|
|
||||||
Header string `header:"Authorization" required:"true" example:"Bearer token"`
|
|
||||||
UserID string `header:"user_id" required:"true" example:"user-uuid"`
|
|
||||||
ID string `path:"id"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type DeleteInventoryItemOutput struct {
|
|
||||||
Body struct {
|
|
||||||
Message string `json:"message"`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (a *api) deleteInventoryItemHandler(ctx context.Context, input *DeleteInventoryItemInput) (*DeleteInventoryItemOutput, error) {
|
func (a *api) deleteInventoryItemHandler(ctx context.Context, input *DeleteInventoryItemInput) (*DeleteInventoryItemOutput, error) {
|
||||||
err := a.inventoryRepo.Delete(ctx, input.ID, input.UserID)
|
err := a.inventoryRepo.Delete(ctx, input.ID, input.UserID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -293,3 +356,54 @@ func (a *api) deleteInventoryItemHandler(ctx context.Context, input *DeleteInven
|
|||||||
Message string `json:"message"`
|
Message string `json:"message"`
|
||||||
}{Message: "Inventory item deleted successfully"}}, nil
|
}{Message: "Inventory item deleted successfully"}}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *api) getInventoryStatusHandler(ctx context.Context, input *struct{}) (*GetInventoryStatusOutput, error) {
|
||||||
|
statuses, err := a.inventoryRepo.GetStatuses(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
response := make([]InventoryStatus, len(statuses))
|
||||||
|
for i, status := range statuses {
|
||||||
|
response[i] = InventoryStatus{
|
||||||
|
ID: status.ID,
|
||||||
|
Name: status.Name,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &GetInventoryStatusOutput{Body: response}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *api) getInventoryCategoryHandler(ctx context.Context, input *struct{}) (*GetInventoryCategoryOutput, error) {
|
||||||
|
categories, err := a.inventoryRepo.GetCategories(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
response := make([]InventoryCategory, len(categories))
|
||||||
|
for i, category := range categories {
|
||||||
|
response[i] = InventoryCategory{
|
||||||
|
ID: category.ID,
|
||||||
|
Name: category.Name,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &GetInventoryCategoryOutput{Body: response}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *api) getHarvestUnitsHandler(ctx context.Context, input *struct{}) (*GetHarvestUnitsOutput, error) {
|
||||||
|
units, err := a.harvestRepo.GetUnits(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
response := make([]HarvestUnit, len(units))
|
||||||
|
for i, unit := range units {
|
||||||
|
response[i] = HarvestUnit{
|
||||||
|
ID: unit.ID,
|
||||||
|
Name: unit.Name,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return &GetHarvestUnitsOutput{Body: response}, nil
|
||||||
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user