feat: add nullable outlet_id to product

Co-authored-by: aider (openai/glm-5.1) <aider@aider.chat>
This commit is contained in:
ryan 2026-05-13 15:42:51 +07:00
parent dc5a823508
commit 3d124bafb0
6 changed files with 23 additions and 1 deletions

View File

@ -7,6 +7,7 @@ import (
)
type CreateProductRequest struct {
OutletID *uuid.UUID `json:"outlet_id,omitempty"`
CategoryID uuid.UUID `json:"category_id" validate:"required"`
SKU *string `json:"sku,omitempty"`
Name string `json:"name" validate:"required,min=1,max=255"`
@ -25,6 +26,7 @@ type CreateProductRequest struct {
}
type UpdateProductRequest struct {
OutletID *uuid.UUID `json:"outlet_id,omitempty"`
CategoryID *uuid.UUID `json:"category_id,omitempty"`
SKU *string `json:"sku,omitempty"`
Name *string `json:"name,omitempty" validate:"omitempty,min=1,max=255"`
@ -58,6 +60,7 @@ type UpdateProductVariantRequest struct {
type ProductResponse struct {
ID uuid.UUID `json:"id"`
OrganizationID uuid.UUID `json:"organization_id"`
OutletID *uuid.UUID `json:"outlet_id"`
CategoryID uuid.UUID `json:"category_id"`
CategoryName string `json:"category_name"`
SKU *string `json:"sku"`
@ -89,6 +92,7 @@ type ProductVariantResponse struct {
type ListProductsRequest struct {
OrganizationID *uuid.UUID `json:"organization_id,omitempty"`
OutletID *uuid.UUID `json:"outlet_id,omitempty"`
CategoryID *uuid.UUID `json:"category_id,omitempty"`
BusinessType string `json:"business_type,omitempty"`
IsActive *bool `json:"is_active,omitempty"`

View File

@ -10,6 +10,7 @@ import (
type Product 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"`
OutletID *uuid.UUID `gorm:"type:uuid;index" json:"outlet_id"`
CategoryID uuid.UUID `gorm:"type:uuid;not null;index" json:"category_id" validate:"required"`
SKU *string `gorm:"size:100;index" json:"sku"`
Name string `gorm:"not null;size:255" json:"name" validate:"required,min=1,max=255"`
@ -27,6 +28,7 @@ type Product struct {
UpdatedAt time.Time `gorm:"autoUpdateTime" json:"updated_at"`
Organization Organization `gorm:"foreignKey:OrganizationID" json:"organization,omitempty"`
Outlet *Outlet `gorm:"foreignKey:OutletID" json:"outlet,omitempty"`
Category Category `gorm:"foreignKey:CategoryID" json:"category,omitempty"`
Unit *Unit `gorm:"foreignKey:UnitID" json:"unit,omitempty"`
ProductVariants []ProductVariant `gorm:"foreignKey:ProductID" json:"variants,omitempty"`

View File

@ -172,6 +172,12 @@ func (h *ProductHandler) ListProducts(c *gin.Context) {
}
}
if outletIDStr := c.Query("outlet_id"); outletIDStr != "" {
if outletID, err := uuid.Parse(outletIDStr); err == nil {
req.OutletID = &outletID
}
}
if categoryIDStr := c.Query("category_id"); categoryIDStr != "" {
if categoryID, err := uuid.Parse(categoryIDStr); err == nil {
req.CategoryID = &categoryID

View File

@ -10,6 +10,7 @@ import (
type Product struct {
ID uuid.UUID
OrganizationID uuid.UUID
OutletID *uuid.UUID
CategoryID uuid.UUID
SKU *string
Name string
@ -40,6 +41,7 @@ type ProductVariant struct {
type CreateProductRequest struct {
OrganizationID uuid.UUID `validate:"required"`
OutletID *uuid.UUID `validate:"omitempty"`
CategoryID uuid.UUID `validate:"required"`
SKU *string `validate:"omitempty,max=100"`
Name string `validate:"required,min=1,max=255"`
@ -60,6 +62,7 @@ type CreateProductRequest struct {
}
type UpdateProductRequest struct {
OutletID *uuid.UUID `validate:"omitempty"`
CategoryID *uuid.UUID `validate:"omitempty"`
SKU *string `validate:"omitempty,max=100"`
Name *string `validate:"omitempty,min=1,max=255"`
@ -94,6 +97,7 @@ type UpdateProductVariantRequest struct {
type ProductResponse struct {
ID uuid.UUID
OrganizationID uuid.UUID
OutletID *uuid.UUID
CategoryID uuid.UUID
CategoryName string
SKU *string

View File

@ -85,6 +85,9 @@ func (s *ProductServiceImpl) ListProducts(ctx context.Context, req *contract.Lis
if req.OrganizationID != nil {
filters["organization_id"] = *req.OrganizationID
}
if req.OutletID != nil {
filters["outlet_id"] = *req.OutletID
}
if req.CategoryID != nil {
filters["category_id"] = *req.CategoryID
}

View File

@ -39,6 +39,7 @@ func CreateProductRequestToModel(apctx *appcontext.ContextInfo, req *contract.Cr
return &models.CreateProductRequest{
OrganizationID: apctx.OrganizationID,
OutletID: req.OutletID,
CategoryID: req.CategoryID,
SKU: req.SKU,
Name: req.Name,
@ -60,7 +61,8 @@ func UpdateProductRequestToModel(req *contract.UpdateProductRequest) *models.Upd
}
return &models.UpdateProductRequest{
CategoryID: req.CategoryID,
OutletID: req.OutletID,
CategoryID: req.CategoryID,
SKU: req.SKU,
Name: req.Name,
Description: req.Description,
@ -100,6 +102,7 @@ func ProductModelResponseToResponse(prod *models.ProductResponse) *contract.Prod
return &contract.ProductResponse{
ID: prod.ID,
OrganizationID: prod.OrganizationID,
OutletID: prod.OutletID,
CategoryID: prod.CategoryID,
CategoryName: prod.CategoryName,
SKU: prod.SKU,