Compare commits
3 Commits
fa037b4d2a
...
dc5a823508
| Author | SHA1 | Date | |
|---|---|---|---|
| dc5a823508 | |||
| 691e2ea614 | |||
| c5f94229a7 |
@ -8,22 +8,25 @@ import (
|
||||
|
||||
type CreateCategoryRequest struct {
|
||||
Name string `json:"name" validate:"required,min=1,max=255"`
|
||||
OutletID *uuid.UUID `json:"outlet_id,omitempty"`
|
||||
Description *string `json:"description,omitempty"`
|
||||
BusinessType *string `json:"business_type,omitempty"`
|
||||
Order *int `json:"order,omitempty"`
|
||||
Order *int `json:"order,omitempty"`
|
||||
Metadata map[string]interface{} `json:"metadata,omitempty"`
|
||||
}
|
||||
|
||||
type UpdateCategoryRequest struct {
|
||||
Name *string `json:"name,omitempty" validate:"omitempty,min=1,max=255"`
|
||||
OutletID *uuid.UUID `json:"outlet_id,omitempty"`
|
||||
Description *string `json:"description,omitempty"`
|
||||
BusinessType *string `json:"business_type,omitempty"`
|
||||
Order *int `json:"order,omitempty"`
|
||||
Order *int `json:"order,omitempty"`
|
||||
Metadata map[string]interface{} `json:"metadata,omitempty"`
|
||||
}
|
||||
|
||||
type ListCategoriesRequest struct {
|
||||
OrganizationID *uuid.UUID `json:"organization_id,omitempty"`
|
||||
OutletID *uuid.UUID `json:"outlet_id,omitempty"`
|
||||
BusinessType string `json:"business_type,omitempty"`
|
||||
Search string `json:"search,omitempty"`
|
||||
Page int `json:"page" validate:"required,min=1"`
|
||||
@ -34,10 +37,11 @@ type ListCategoriesRequest struct {
|
||||
type CategoryResponse struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
OrganizationID uuid.UUID `json:"organization_id"`
|
||||
OutletID *uuid.UUID `json:"outlet_id,omitempty"`
|
||||
Name string `json:"name"`
|
||||
Description *string `json:"description"`
|
||||
BusinessType string `json:"business_type"`
|
||||
Order int `json:"order"`
|
||||
Order int `json:"order"`
|
||||
Metadata map[string]interface{} `json:"metadata"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
|
||||
@ -31,17 +31,19 @@ func (m *Metadata) Scan(value interface{}) error {
|
||||
}
|
||||
|
||||
type Category struct {
|
||||
ID uuid.UUID `gorm:"type:uuid;primary_key;default:gen_random_uuid()" json:"id"`
|
||||
OrganizationID uuid.UUID `gorm:"type:uuid;not null;index" json:"organization_id" validate:"required"`
|
||||
Name string `gorm:"not null;size:255" json:"name" validate:"required,min=1,max=255"`
|
||||
Description *string `gorm:"type:text" json:"description"`
|
||||
Order int `gorm:"default:0" json:"order"`
|
||||
BusinessType string `gorm:"size:50;default:'restaurant'" json:"business_type"`
|
||||
Metadata Metadata `gorm:"type:jsonb;default:'{}'" json:"metadata"`
|
||||
CreatedAt time.Time `gorm:"autoCreateTime" json:"created_at"`
|
||||
UpdatedAt time.Time `gorm:"autoUpdateTime" json:"updated_at"`
|
||||
ID uuid.UUID `gorm:"type:uuid;primary_key;default:gen_random_uuid()" json:"id"`
|
||||
OrganizationID uuid.UUID `gorm:"type:uuid;not null;index" json:"organization_id" validate:"required"`
|
||||
OutletID *uuid.UUID `gorm:"type:uuid;index" json:"outlet_id,omitempty"`
|
||||
Name string `gorm:"not null;size:255" json:"name" validate:"required,min=1,max=255"`
|
||||
Description *string `gorm:"type:text" json:"description"`
|
||||
Order int `gorm:"default:0" json:"order"`
|
||||
BusinessType string `gorm:"size:50;default:'restaurant'" json:"business_type"`
|
||||
Metadata Metadata `gorm:"type:jsonb;default:'{}'" json:"metadata"`
|
||||
CreatedAt time.Time `gorm:"autoCreateTime" json:"created_at"`
|
||||
UpdatedAt time.Time `gorm:"autoUpdateTime" json:"updated_at"`
|
||||
|
||||
Organization Organization `gorm:"foreignKey:OrganizationID" json:"organization,omitempty"`
|
||||
Outlet Outlet `gorm:"foreignKey:OutletID" json:"outlet,omitempty"`
|
||||
Products []Product `gorm:"foreignKey:CategoryID" json:"products,omitempty"`
|
||||
}
|
||||
|
||||
|
||||
@ -170,6 +170,12 @@ func (h *CategoryHandler) ListCategories(c *gin.Context) {
|
||||
req.BusinessType = businessType
|
||||
}
|
||||
|
||||
if outletIDStr := c.Query("outlet_id"); outletIDStr != "" {
|
||||
if outletID, err := uuid.Parse(outletIDStr); err == nil {
|
||||
req.OutletID = &outletID
|
||||
}
|
||||
}
|
||||
|
||||
if organizationIDStr := c.Query("organization_id"); organizationIDStr != "" {
|
||||
if organizationID, err := uuid.Parse(organizationIDStr); err == nil {
|
||||
req.OrganizationID = &organizationID
|
||||
|
||||
@ -9,10 +9,11 @@ import (
|
||||
type Category struct {
|
||||
ID uuid.UUID
|
||||
OrganizationID uuid.UUID
|
||||
OutletID *uuid.UUID
|
||||
Name string
|
||||
Description *string
|
||||
ImageURL *string
|
||||
Order int
|
||||
Order int
|
||||
IsActive bool
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
@ -20,27 +21,30 @@ type Category struct {
|
||||
|
||||
type CreateCategoryRequest struct {
|
||||
OrganizationID uuid.UUID `validate:"required"`
|
||||
Name string `validate:"required,min=1,max=255"`
|
||||
Description *string `validate:"omitempty,max=1000"`
|
||||
ImageURL *string `validate:"omitempty,url"`
|
||||
Order int `validate:"min=0"`
|
||||
OutletID *uuid.UUID
|
||||
Name string `validate:"required,min=1,max=255"`
|
||||
Description *string `validate:"omitempty,max=1000"`
|
||||
ImageURL *string `validate:"omitempty,url"`
|
||||
Order int `validate:"min=0"`
|
||||
}
|
||||
|
||||
type UpdateCategoryRequest struct {
|
||||
Name *string `validate:"omitempty,min=1,max=255"`
|
||||
Description *string `validate:"omitempty,max=1000"`
|
||||
ImageURL *string `validate:"omitempty,url"`
|
||||
Order *int `validate:"omitempty,min=0"`
|
||||
OutletID *uuid.UUID `validate:"omitempty,required"`
|
||||
Name *string `validate:"omitempty,min=1,max=255"`
|
||||
Description *string `validate:"omitempty,max=1000"`
|
||||
ImageURL *string `validate:"omitempty,url"`
|
||||
Order *int `validate:"omitempty,min=0"`
|
||||
IsActive *bool
|
||||
}
|
||||
|
||||
type CategoryResponse struct {
|
||||
ID uuid.UUID
|
||||
OrganizationID uuid.UUID
|
||||
OutletID *uuid.UUID
|
||||
Name string
|
||||
Description *string
|
||||
ImageURL *string
|
||||
Order int
|
||||
Order int
|
||||
IsActive bool
|
||||
CreatedAt time.Time
|
||||
UpdatedAt time.Time
|
||||
|
||||
@ -55,6 +55,7 @@ func (p *CategoryProcessorImpl) CreateCategory(ctx context.Context, req *models.
|
||||
|
||||
// Map request to entity
|
||||
categoryEntity := mappers.CreateCategoryRequestToEntity(req)
|
||||
categoryEntity.OutletID = req.OutletID
|
||||
|
||||
// Create category
|
||||
if err := p.categoryRepo.Create(ctx, categoryEntity); err != nil {
|
||||
@ -86,6 +87,9 @@ func (p *CategoryProcessorImpl) UpdateCategory(ctx context.Context, id uuid.UUID
|
||||
|
||||
// Apply updates to entity
|
||||
mappers.UpdateCategoryEntityFromRequest(existingCategory, req)
|
||||
if req.OutletID != nil {
|
||||
existingCategory.OutletID = req.OutletID
|
||||
}
|
||||
|
||||
// Update category
|
||||
if err := p.categoryRepo.Update(ctx, existingCategory); err != nil {
|
||||
|
||||
@ -25,7 +25,7 @@ func (r *CategoryRepositoryImpl) Create(ctx context.Context, category *entities.
|
||||
|
||||
func (r *CategoryRepositoryImpl) GetByID(ctx context.Context, id uuid.UUID) (*entities.Category, error) {
|
||||
var category entities.Category
|
||||
err := r.db.WithContext(ctx).First(&category, "id = ?", id).Error
|
||||
err := r.db.WithContext(ctx).Preload("Outlet").First(&category, "id = ?", id).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -34,7 +34,7 @@ func (r *CategoryRepositoryImpl) GetByID(ctx context.Context, id uuid.UUID) (*en
|
||||
|
||||
func (r *CategoryRepositoryImpl) GetWithProducts(ctx context.Context, id uuid.UUID) (*entities.Category, error) {
|
||||
var category entities.Category
|
||||
err := r.db.WithContext(ctx).Preload("Products").First(&category, "id = ?", id).Error
|
||||
err := r.db.WithContext(ctx).Preload("Products").Preload("Outlet").First(&category, "id = ?", id).Error
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@ -81,7 +81,7 @@ func (r *CategoryRepositoryImpl) List(ctx context.Context, filters map[string]in
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
err := query.Order("\"order\" ASC").Limit(limit).Offset(offset).Find(&categories).Error
|
||||
err := query.Preload("Outlet").Order("\"order\" ASC").Limit(limit).Offset(offset).Find(&categories).Error
|
||||
return categories, total, err
|
||||
}
|
||||
|
||||
|
||||
@ -88,6 +88,9 @@ func (s *CategoryServiceImpl) ListCategories(ctx context.Context, req *contract.
|
||||
if req.BusinessType != "" {
|
||||
filters["business_type"] = req.BusinessType
|
||||
}
|
||||
if req.OutletID != nil {
|
||||
filters["outlet_id"] = *req.OutletID
|
||||
}
|
||||
if req.Search != "" {
|
||||
filters["search"] = req.Search
|
||||
}
|
||||
|
||||
@ -9,6 +9,7 @@ import (
|
||||
func CreateCategoryRequestToModel(apctx *appcontext.ContextInfo, req *contract.CreateCategoryRequest) *models.CreateCategoryRequest {
|
||||
return &models.CreateCategoryRequest{
|
||||
OrganizationID: apctx.OrganizationID,
|
||||
OutletID: req.OutletID,
|
||||
Name: req.Name,
|
||||
Description: req.Description,
|
||||
ImageURL: nil,
|
||||
@ -18,6 +19,7 @@ func CreateCategoryRequestToModel(apctx *appcontext.ContextInfo, req *contract.C
|
||||
|
||||
func UpdateCategoryRequestToModel(req *contract.UpdateCategoryRequest) *models.UpdateCategoryRequest {
|
||||
return &models.UpdateCategoryRequest{
|
||||
OutletID: req.OutletID,
|
||||
Name: req.Name,
|
||||
Description: req.Description,
|
||||
ImageURL: nil,
|
||||
@ -34,6 +36,7 @@ func CategoryModelResponseToResponse(cat *models.CategoryResponse) *contract.Cat
|
||||
return &contract.CategoryResponse{
|
||||
ID: cat.ID,
|
||||
OrganizationID: cat.OrganizationID,
|
||||
OutletID: cat.OutletID,
|
||||
Name: cat.Name,
|
||||
Description: cat.Description,
|
||||
BusinessType: "restaurant", // Default business type
|
||||
|
||||
@ -59,7 +59,7 @@ func (v *CategoryValidatorImpl) ValidateUpdateCategoryRequest(req *contract.Upda
|
||||
}
|
||||
|
||||
// At least one field should be provided for update
|
||||
if req.Name == nil && req.Description == nil && req.BusinessType == nil && req.Metadata == nil {
|
||||
if req.Name == nil && req.Description == nil && req.BusinessType == nil && req.Metadata == nil && req.OutletID == nil {
|
||||
return errors.New("at least one field must be provided for update"), constants.MissingFieldErrorCode
|
||||
}
|
||||
|
||||
|
||||
3
migrations/000068_add_outlet_id_to_categories.down.sql
Normal file
3
migrations/000068_add_outlet_id_to_categories.down.sql
Normal file
@ -0,0 +1,3 @@
|
||||
DROP INDEX IF EXISTS idx_categories_outlet_id;
|
||||
ALTER TABLE categories DROP CONSTRAINT IF EXISTS fk_categories_outlet;
|
||||
ALTER TABLE categories DROP COLUMN IF EXISTS outlet_id;
|
||||
3
migrations/000068_add_outlet_id_to_categories.up.sql
Normal file
3
migrations/000068_add_outlet_id_to_categories.up.sql
Normal file
@ -0,0 +1,3 @@
|
||||
ALTER TABLE categories ADD COLUMN outlet_id UUID;
|
||||
ALTER TABLE categories ADD CONSTRAINT fk_categories_outlet FOREIGN KEY (outlet_id) REFERENCES outlets(id) ON DELETE SET NULL;
|
||||
CREATE INDEX idx_categories_outlet_id ON categories(outlet_id);
|
||||
Loading…
x
Reference in New Issue
Block a user