Merge branch 'main' of https://gits.altru.id/apksel-dev/apskel-pos-backend into feature/expense
This commit is contained in:
commit
f7399fd0e7
@ -98,6 +98,8 @@ type OrderItemResponse struct {
|
|||||||
ProductName string `json:"product_name"`
|
ProductName string `json:"product_name"`
|
||||||
ProductVariantID *uuid.UUID `json:"product_variant_id"`
|
ProductVariantID *uuid.UUID `json:"product_variant_id"`
|
||||||
ProductVariantName *string `json:"product_variant_name,omitempty"`
|
ProductVariantName *string `json:"product_variant_name,omitempty"`
|
||||||
|
CategoryID *uuid.UUID `json:"category_id,omitempty"`
|
||||||
|
CategoryName *string `json:"category_name,omitempty"`
|
||||||
Quantity int `json:"quantity"`
|
Quantity int `json:"quantity"`
|
||||||
UnitPrice float64 `json:"unit_price"`
|
UnitPrice float64 `json:"unit_price"`
|
||||||
TotalPrice float64 `json:"total_price"`
|
TotalPrice float64 `json:"total_price"`
|
||||||
@ -108,6 +110,7 @@ type OrderItemResponse struct {
|
|||||||
CreatedAt time.Time `json:"created_at"`
|
CreatedAt time.Time `json:"created_at"`
|
||||||
UpdatedAt time.Time `json:"updated_at"`
|
UpdatedAt time.Time `json:"updated_at"`
|
||||||
PrinterType string `json:"printer_type"`
|
PrinterType string `json:"printer_type"`
|
||||||
|
PrintToChecker bool `json:"print_to_checker"`
|
||||||
PaidQuantity int `json:"paid_quantity"`
|
PaidQuantity int `json:"paid_quantity"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -17,6 +17,7 @@ type CreateProductRequest struct {
|
|||||||
BusinessType *string `json:"business_type,omitempty"`
|
BusinessType *string `json:"business_type,omitempty"`
|
||||||
ImageURL *string `json:"image_url,omitempty" validate:"omitempty,max=500"`
|
ImageURL *string `json:"image_url,omitempty" validate:"omitempty,max=500"`
|
||||||
PrinterType *string `json:"printer_type,omitempty" validate:"omitempty,max=50"`
|
PrinterType *string `json:"printer_type,omitempty" validate:"omitempty,max=50"`
|
||||||
|
PrintToChecker *bool `json:"print_to_checker,omitempty"`
|
||||||
Metadata map[string]interface{} `json:"metadata,omitempty"`
|
Metadata map[string]interface{} `json:"metadata,omitempty"`
|
||||||
IsActive *bool `json:"is_active,omitempty"`
|
IsActive *bool `json:"is_active,omitempty"`
|
||||||
Variants []CreateProductVariantRequest `json:"variants,omitempty"`
|
Variants []CreateProductVariantRequest `json:"variants,omitempty"`
|
||||||
@ -26,19 +27,20 @@ type CreateProductRequest struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type UpdateProductRequest struct {
|
type UpdateProductRequest struct {
|
||||||
OutletID *uuid.UUID `json:"outlet_id,omitempty"`
|
OutletID *uuid.UUID `json:"outlet_id,omitempty"`
|
||||||
CategoryID *uuid.UUID `json:"category_id,omitempty"`
|
CategoryID *uuid.UUID `json:"category_id,omitempty"`
|
||||||
SKU *string `json:"sku,omitempty"`
|
SKU *string `json:"sku,omitempty"`
|
||||||
Name *string `json:"name,omitempty" validate:"omitempty,min=1,max=255"`
|
Name *string `json:"name,omitempty" validate:"omitempty,min=1,max=255"`
|
||||||
Description *string `json:"description,omitempty"`
|
Description *string `json:"description,omitempty"`
|
||||||
Price *float64 `json:"price,omitempty" validate:"omitempty,min=0"`
|
Price *float64 `json:"price,omitempty" validate:"omitempty,min=0"`
|
||||||
Cost *float64 `json:"cost,omitempty" validate:"omitempty,min=0"`
|
Cost *float64 `json:"cost,omitempty" validate:"omitempty,min=0"`
|
||||||
BusinessType *string `json:"business_type,omitempty"`
|
BusinessType *string `json:"business_type,omitempty"`
|
||||||
ImageURL *string `json:"image_url,omitempty" validate:"omitempty,max=500"`
|
ImageURL *string `json:"image_url,omitempty" validate:"omitempty,max=500"`
|
||||||
PrinterType *string `json:"printer_type,omitempty" validate:"omitempty,max=50"`
|
PrinterType *string `json:"printer_type,omitempty" validate:"omitempty,max=50"`
|
||||||
Metadata map[string]interface{} `json:"metadata,omitempty"`
|
PrintToChecker *bool `json:"print_to_checker,omitempty"`
|
||||||
IsActive *bool `json:"is_active,omitempty"`
|
Metadata map[string]interface{} `json:"metadata,omitempty"`
|
||||||
ReorderLevel *int `json:"reorder_level,omitempty" validate:"omitempty,min=0"`
|
IsActive *bool `json:"is_active,omitempty"`
|
||||||
|
ReorderLevel *int `json:"reorder_level,omitempty" validate:"omitempty,min=0"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type CreateProductVariantRequest struct {
|
type CreateProductVariantRequest struct {
|
||||||
@ -71,6 +73,7 @@ type ProductResponse struct {
|
|||||||
BusinessType string `json:"business_type"`
|
BusinessType string `json:"business_type"`
|
||||||
ImageURL *string `json:"image_url"`
|
ImageURL *string `json:"image_url"`
|
||||||
PrinterType string `json:"printer_type"`
|
PrinterType string `json:"printer_type"`
|
||||||
|
PrintToChecker bool `json:"print_to_checker"`
|
||||||
Metadata map[string]interface{} `json:"metadata"`
|
Metadata map[string]interface{} `json:"metadata"`
|
||||||
IsActive bool `json:"is_active"`
|
IsActive bool `json:"is_active"`
|
||||||
CreatedAt time.Time `json:"created_at"`
|
CreatedAt time.Time `json:"created_at"`
|
||||||
|
|||||||
@ -7,23 +7,26 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type CreateProductOutletPriceRequest struct {
|
type CreateProductOutletPriceRequest struct {
|
||||||
ProductID uuid.UUID `json:"product_id" validate:"required"`
|
ProductID uuid.UUID `json:"product_id" validate:"required"`
|
||||||
OutletID uuid.UUID `json:"outlet_id" validate:"required"`
|
OutletID uuid.UUID `json:"outlet_id" validate:"required"`
|
||||||
Price float64 `json:"price" validate:"required,min=0"`
|
Price float64 `json:"price" validate:"required,min=0"`
|
||||||
|
PrintToChecker bool `json:"print_to_checker"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type UpdateProductOutletPriceRequest struct {
|
type UpdateProductOutletPriceRequest struct {
|
||||||
Price float64 `json:"price" validate:"required,min=0"`
|
Price float64 `json:"price" validate:"required,min=0"`
|
||||||
|
PrintToChecker *bool `json:"print_to_checker"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ProductOutletPriceResponse struct {
|
type ProductOutletPriceResponse struct {
|
||||||
ID uuid.UUID `json:"id,omitempty"`
|
ID uuid.UUID `json:"id,omitempty"`
|
||||||
ProductID uuid.UUID `json:"product_id,omitempty"`
|
ProductID uuid.UUID `json:"product_id,omitempty"`
|
||||||
OutletID uuid.UUID `json:"outlet_id"`
|
OutletID uuid.UUID `json:"outlet_id"`
|
||||||
OutletName string `json:"outlet_name,omitempty"`
|
OutletName string `json:"outlet_name,omitempty"`
|
||||||
Price float64 `json:"price"`
|
Price float64 `json:"price"`
|
||||||
CreatedAt time.Time `json:"created_at,omitempty"`
|
PrintToChecker bool `json:"print_to_checker"`
|
||||||
UpdatedAt time.Time `json:"updated_at,omitempty"`
|
CreatedAt time.Time `json:"created_at,omitempty"`
|
||||||
|
UpdatedAt time.Time `json:"updated_at,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ListProductOutletPricesResponse struct {
|
type ListProductOutletPricesResponse struct {
|
||||||
@ -37,6 +40,7 @@ type BulkCreateProductOutletPriceRequest struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type CreateProductOutletPricePerOutletRequest struct {
|
type CreateProductOutletPricePerOutletRequest struct {
|
||||||
OutletID uuid.UUID `json:"outlet_id" validate:"required"`
|
OutletID uuid.UUID `json:"outlet_id" validate:"required"`
|
||||||
Price float64 `json:"price" validate:"required,min=0"`
|
Price float64 `json:"price" validate:"required,min=0"`
|
||||||
|
PrintToChecker bool `json:"print_to_checker"`
|
||||||
}
|
}
|
||||||
|
|||||||
@ -26,13 +26,14 @@ type Product struct {
|
|||||||
CreatedAt time.Time `gorm:"autoCreateTime" json:"created_at"`
|
CreatedAt time.Time `gorm:"autoCreateTime" json:"created_at"`
|
||||||
UpdatedAt time.Time `gorm:"autoUpdateTime" json:"updated_at"`
|
UpdatedAt time.Time `gorm:"autoUpdateTime" json:"updated_at"`
|
||||||
|
|
||||||
Organization Organization `gorm:"foreignKey:OrganizationID" json:"organization,omitempty"`
|
Organization Organization `gorm:"foreignKey:OrganizationID" json:"organization,omitempty"`
|
||||||
Category Category `gorm:"foreignKey:CategoryID" json:"category,omitempty"`
|
Category Category `gorm:"foreignKey:CategoryID" json:"category,omitempty"`
|
||||||
Unit *Unit `gorm:"foreignKey:UnitID" json:"unit,omitempty"`
|
Unit *Unit `gorm:"foreignKey:UnitID" json:"unit,omitempty"`
|
||||||
ProductVariants []ProductVariant `gorm:"foreignKey:ProductID" json:"variants,omitempty"`
|
ProductVariants []ProductVariant `gorm:"foreignKey:ProductID" json:"variants,omitempty"`
|
||||||
ProductRecipes []ProductRecipe `gorm:"foreignKey:ProductID" json:"product_recipes,omitempty"`
|
ProductRecipes []ProductRecipe `gorm:"foreignKey:ProductID" json:"product_recipes,omitempty"`
|
||||||
Inventory []Inventory `gorm:"foreignKey:ProductID" json:"inventory,omitempty"`
|
Inventory []Inventory `gorm:"foreignKey:ProductID" json:"inventory,omitempty"`
|
||||||
OrderItems []OrderItem `gorm:"foreignKey:ProductID" json:"order_items,omitempty"`
|
OrderItems []OrderItem `gorm:"foreignKey:ProductID" json:"order_items,omitempty"`
|
||||||
|
ProductOutletPrices []ProductOutletPrice `gorm:"foreignKey:ProductID" json:"product_outlet_prices,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Product) BeforeCreate(tx *gorm.DB) error {
|
func (p *Product) BeforeCreate(tx *gorm.DB) error {
|
||||||
|
|||||||
@ -8,12 +8,13 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type ProductOutletPrice struct {
|
type ProductOutletPrice struct {
|
||||||
ID uuid.UUID `gorm:"type:uuid;primary_key;default:gen_random_uuid()" json:"id"`
|
ID uuid.UUID `gorm:"type:uuid;primary_key;default:gen_random_uuid()" json:"id"`
|
||||||
ProductID uuid.UUID `gorm:"type:uuid;not null;index" json:"product_id"`
|
ProductID uuid.UUID `gorm:"type:uuid;not null;index" json:"product_id"`
|
||||||
OutletID uuid.UUID `gorm:"type:uuid;not null;index" json:"outlet_id"`
|
OutletID uuid.UUID `gorm:"type:uuid;not null;index" json:"outlet_id"`
|
||||||
Price float64 `gorm:"type:decimal(10,2);not null" json:"price"`
|
Price float64 `gorm:"type:decimal(10,2);not null" json:"price"`
|
||||||
CreatedAt time.Time `gorm:"autoCreateTime" json:"created_at"`
|
PrintToChecker bool `gorm:"not null;default:true" json:"print_to_checker"`
|
||||||
UpdatedAt time.Time `gorm:"autoUpdateTime" json:"updated_at"`
|
CreatedAt time.Time `gorm:"autoCreateTime" json:"created_at"`
|
||||||
|
UpdatedAt time.Time `gorm:"autoUpdateTime" json:"updated_at"`
|
||||||
|
|
||||||
Product Product `gorm:"foreignKey:ProductID" json:"product,omitempty"`
|
Product Product `gorm:"foreignKey:ProductID" json:"product,omitempty"`
|
||||||
Outlet Outlet `gorm:"foreignKey:OutletID" json:"outlet,omitempty"`
|
Outlet Outlet `gorm:"foreignKey:OutletID" json:"outlet,omitempty"`
|
||||||
|
|||||||
@ -82,7 +82,7 @@ func OrderEntityToResponse(order *entities.Order) *models.OrderResponse {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for i, item := range order.OrderItems {
|
for i, item := range order.OrderItems {
|
||||||
resp := OrderItemEntityToResponse(&item)
|
resp := OrderItemEntityToResponse(&item, order.OutletID)
|
||||||
if resp != nil {
|
if resp != nil {
|
||||||
resp.PaidQuantity = paidQtyByOrderItem[item.ID]
|
resp.PaidQuantity = paidQtyByOrderItem[item.ID]
|
||||||
response.OrderItems[i] = *resp
|
response.OrderItems[i] = *resp
|
||||||
@ -101,11 +101,20 @@ func OrderEntityToResponse(order *entities.Order) *models.OrderResponse {
|
|||||||
return response
|
return response
|
||||||
}
|
}
|
||||||
|
|
||||||
func OrderItemEntityToResponse(item *entities.OrderItem) *models.OrderItemResponse {
|
func OrderItemEntityToResponse(item *entities.OrderItem, outletID uuid.UUID) *models.OrderItemResponse {
|
||||||
if item == nil {
|
if item == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Resolve print_to_checker from preloaded outlet prices
|
||||||
|
printToChecker := true // default
|
||||||
|
for _, op := range item.Product.ProductOutletPrices {
|
||||||
|
if op.OutletID == outletID {
|
||||||
|
printToChecker = op.PrintToChecker
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
response := &models.OrderItemResponse{
|
response := &models.OrderItemResponse{
|
||||||
ID: item.ID,
|
ID: item.ID,
|
||||||
OrderID: item.OrderID,
|
OrderID: item.OrderID,
|
||||||
@ -130,10 +139,19 @@ func OrderItemEntityToResponse(item *entities.OrderItem) *models.OrderItemRespon
|
|||||||
CreatedAt: item.CreatedAt,
|
CreatedAt: item.CreatedAt,
|
||||||
UpdatedAt: item.UpdatedAt,
|
UpdatedAt: item.UpdatedAt,
|
||||||
PrinterType: item.Product.PrinterType,
|
PrinterType: item.Product.PrinterType,
|
||||||
|
PrintToChecker: printToChecker,
|
||||||
}
|
}
|
||||||
|
|
||||||
if item.Product.ID != uuid.Nil {
|
if item.Product.ID != uuid.Nil {
|
||||||
response.ProductName = item.Product.Name
|
response.ProductName = item.Product.Name
|
||||||
|
if item.Product.CategoryID != uuid.Nil {
|
||||||
|
categoryID := item.Product.CategoryID
|
||||||
|
response.CategoryID = &categoryID
|
||||||
|
}
|
||||||
|
if item.Product.Category.ID != uuid.Nil {
|
||||||
|
categoryName := item.Product.Category.Name
|
||||||
|
response.CategoryName = &categoryName
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if item.ProductVariant != nil {
|
if item.ProductVariant != nil {
|
||||||
@ -316,14 +334,14 @@ func OrderEntitiesToResponses(orders []*entities.Order) []models.OrderResponse {
|
|||||||
return responses
|
return responses
|
||||||
}
|
}
|
||||||
|
|
||||||
func OrderItemEntitiesToResponses(items []*entities.OrderItem) []models.OrderItemResponse {
|
func OrderItemEntitiesToResponses(items []*entities.OrderItem, outletID uuid.UUID) []models.OrderItemResponse {
|
||||||
if items == nil {
|
if items == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
responses := make([]models.OrderItemResponse, len(items))
|
responses := make([]models.OrderItemResponse, len(items))
|
||||||
for i, item := range items {
|
for i, item := range items {
|
||||||
response := OrderItemEntityToResponse(item)
|
response := OrderItemEntityToResponse(item, outletID)
|
||||||
if response != nil {
|
if response != nil {
|
||||||
responses[i] = *response
|
responses[i] = *response
|
||||||
}
|
}
|
||||||
|
|||||||
@ -45,7 +45,7 @@ func TestOrderItemEntityToResponse_WithProductNames(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
result := OrderItemEntityToResponse(orderItem)
|
result := OrderItemEntityToResponse(orderItem, uuid.Nil)
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
assert.NotNil(t, result)
|
assert.NotNil(t, result)
|
||||||
@ -89,7 +89,7 @@ func TestOrderItemEntityToResponse_WithoutProductVariant(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
result := OrderItemEntityToResponse(orderItem)
|
result := OrderItemEntityToResponse(orderItem, uuid.Nil)
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
assert.NotNil(t, result)
|
assert.NotNil(t, result)
|
||||||
@ -129,7 +129,7 @@ func TestOrderItemEntityToResponse_WithoutProductPreload(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Act
|
// Act
|
||||||
result := OrderItemEntityToResponse(orderItem)
|
result := OrderItemEntityToResponse(orderItem, uuid.Nil)
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
assert.NotNil(t, result)
|
assert.NotNil(t, result)
|
||||||
|
|||||||
@ -11,12 +11,13 @@ func ProductOutletPriceEntityToModel(entity *entities.ProductOutletPrice) *model
|
|||||||
}
|
}
|
||||||
|
|
||||||
return &models.ProductOutletPrice{
|
return &models.ProductOutletPrice{
|
||||||
ID: entity.ID,
|
ID: entity.ID,
|
||||||
ProductID: entity.ProductID,
|
ProductID: entity.ProductID,
|
||||||
OutletID: entity.OutletID,
|
OutletID: entity.OutletID,
|
||||||
Price: entity.Price,
|
Price: entity.Price,
|
||||||
CreatedAt: entity.CreatedAt,
|
PrintToChecker: entity.PrintToChecker,
|
||||||
UpdatedAt: entity.UpdatedAt,
|
CreatedAt: entity.CreatedAt,
|
||||||
|
UpdatedAt: entity.UpdatedAt,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -26,12 +27,13 @@ func ProductOutletPriceModelToEntity(model *models.ProductOutletPrice) *entities
|
|||||||
}
|
}
|
||||||
|
|
||||||
return &entities.ProductOutletPrice{
|
return &entities.ProductOutletPrice{
|
||||||
ID: model.ID,
|
ID: model.ID,
|
||||||
ProductID: model.ProductID,
|
ProductID: model.ProductID,
|
||||||
OutletID: model.OutletID,
|
OutletID: model.OutletID,
|
||||||
Price: model.Price,
|
Price: model.Price,
|
||||||
CreatedAt: model.CreatedAt,
|
PrintToChecker: model.PrintToChecker,
|
||||||
UpdatedAt: model.UpdatedAt,
|
CreatedAt: model.CreatedAt,
|
||||||
|
UpdatedAt: model.UpdatedAt,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -188,6 +188,8 @@ type OrderItemResponse struct {
|
|||||||
ProductName string
|
ProductName string
|
||||||
ProductVariantID *uuid.UUID
|
ProductVariantID *uuid.UUID
|
||||||
ProductVariantName *string
|
ProductVariantName *string
|
||||||
|
CategoryID *uuid.UUID
|
||||||
|
CategoryName *string
|
||||||
Quantity int
|
Quantity int
|
||||||
UnitPrice float64
|
UnitPrice float64
|
||||||
TotalPrice float64
|
TotalPrice float64
|
||||||
@ -207,6 +209,7 @@ type OrderItemResponse struct {
|
|||||||
CreatedAt time.Time
|
CreatedAt time.Time
|
||||||
UpdatedAt time.Time
|
UpdatedAt time.Time
|
||||||
PrinterType string
|
PrinterType string
|
||||||
|
PrintToChecker bool
|
||||||
PaidQuantity int
|
PaidQuantity int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -50,6 +50,7 @@ type CreateProductRequest struct {
|
|||||||
BusinessType constants.BusinessType `validate:"required"`
|
BusinessType constants.BusinessType `validate:"required"`
|
||||||
ImageURL *string `validate:"omitempty,max=500"`
|
ImageURL *string `validate:"omitempty,max=500"`
|
||||||
PrinterType *string `validate:"omitempty,max=50"`
|
PrinterType *string `validate:"omitempty,max=50"`
|
||||||
|
PrintToChecker *bool `validate:"omitempty"`
|
||||||
UnitID *uuid.UUID `validate:"omitempty"`
|
UnitID *uuid.UUID `validate:"omitempty"`
|
||||||
HasIngredients bool `validate:"omitempty"`
|
HasIngredients bool `validate:"omitempty"`
|
||||||
Metadata map[string]interface{}
|
Metadata map[string]interface{}
|
||||||
@ -70,6 +71,7 @@ type UpdateProductRequest struct {
|
|||||||
Cost *float64 `validate:"omitempty,min=0"`
|
Cost *float64 `validate:"omitempty,min=0"`
|
||||||
ImageURL *string `validate:"omitempty,max=500"`
|
ImageURL *string `validate:"omitempty,max=500"`
|
||||||
PrinterType *string `validate:"omitempty,max=50"`
|
PrinterType *string `validate:"omitempty,max=50"`
|
||||||
|
PrintToChecker *bool `validate:"omitempty"`
|
||||||
UnitID *uuid.UUID `validate:"omitempty"`
|
UnitID *uuid.UUID `validate:"omitempty"`
|
||||||
HasIngredients *bool `validate:"omitempty"`
|
HasIngredients *bool `validate:"omitempty"`
|
||||||
Metadata map[string]interface{}
|
Metadata map[string]interface{}
|
||||||
@ -108,6 +110,7 @@ type ProductResponse struct {
|
|||||||
BusinessType constants.BusinessType
|
BusinessType constants.BusinessType
|
||||||
ImageURL *string
|
ImageURL *string
|
||||||
PrinterType string
|
PrinterType string
|
||||||
|
PrintToChecker bool
|
||||||
UnitID *uuid.UUID
|
UnitID *uuid.UUID
|
||||||
HasIngredients bool
|
HasIngredients bool
|
||||||
Metadata map[string]interface{}
|
Metadata map[string]interface{}
|
||||||
@ -118,9 +121,10 @@ type ProductResponse struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type OutletPrice struct {
|
type OutletPrice struct {
|
||||||
OutletID uuid.UUID
|
OutletID uuid.UUID
|
||||||
OutletName string
|
OutletName string
|
||||||
Price float64
|
Price float64
|
||||||
|
PrintToChecker bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type ProductVariantResponse struct {
|
type ProductVariantResponse struct {
|
||||||
|
|||||||
@ -7,22 +7,25 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type ProductOutletPrice struct {
|
type ProductOutletPrice struct {
|
||||||
ID uuid.UUID
|
ID uuid.UUID
|
||||||
ProductID uuid.UUID
|
ProductID uuid.UUID
|
||||||
OutletID uuid.UUID
|
OutletID uuid.UUID
|
||||||
Price float64
|
Price float64
|
||||||
CreatedAt time.Time
|
PrintToChecker bool
|
||||||
UpdatedAt time.Time
|
CreatedAt time.Time
|
||||||
|
UpdatedAt time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
type CreateProductOutletPriceRequest struct {
|
type CreateProductOutletPriceRequest struct {
|
||||||
ProductID uuid.UUID `validate:"required"`
|
ProductID uuid.UUID `validate:"required"`
|
||||||
OutletID uuid.UUID `validate:"required"`
|
OutletID uuid.UUID `validate:"required"`
|
||||||
Price float64 `validate:"required,min=0"`
|
Price float64 `validate:"required,min=0"`
|
||||||
|
PrintToChecker bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type UpdateProductOutletPriceRequest struct {
|
type UpdateProductOutletPriceRequest struct {
|
||||||
Price *float64 `validate:"required,min=0"`
|
Price *float64 `validate:"required,min=0"`
|
||||||
|
PrintToChecker *bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type ProductOutletPriceResponse struct {
|
type ProductOutletPriceResponse struct {
|
||||||
|
|||||||
@ -1,7 +1,6 @@
|
|||||||
package processor
|
package processor
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"apskel-pos-be/internal/constants"
|
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -388,31 +387,10 @@ func (p *OrderProcessorImpl) AddToOrder(ctx context.Context, orderID uuid.UUID,
|
|||||||
return nil, fmt.Errorf("failed to create order item: %w", err)
|
return nil, fmt.Errorf("failed to create order item: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
itemResponse := models.OrderItemResponse{
|
itemResponse := mappers.OrderItemEntityToResponse(orderItem, order.OutletID)
|
||||||
ID: orderItem.ID,
|
if itemResponse != nil {
|
||||||
OrderID: orderItem.OrderID,
|
addedItemResponses = append(addedItemResponses, *itemResponse)
|
||||||
ProductID: orderItem.ProductID,
|
|
||||||
ProductVariantID: orderItem.ProductVariantID,
|
|
||||||
Quantity: orderItem.Quantity,
|
|
||||||
UnitPrice: orderItem.UnitPrice,
|
|
||||||
TotalPrice: orderItem.TotalPrice,
|
|
||||||
UnitCost: orderItem.UnitCost,
|
|
||||||
TotalCost: orderItem.TotalCost,
|
|
||||||
RefundAmount: orderItem.RefundAmount,
|
|
||||||
RefundQuantity: orderItem.RefundQuantity,
|
|
||||||
IsPartiallyRefunded: orderItem.IsPartiallyRefunded,
|
|
||||||
IsFullyRefunded: orderItem.IsFullyRefunded,
|
|
||||||
RefundReason: orderItem.RefundReason,
|
|
||||||
RefundedAt: orderItem.RefundedAt,
|
|
||||||
RefundedBy: orderItem.RefundedBy,
|
|
||||||
Modifiers: []map[string]interface{}(orderItem.Modifiers),
|
|
||||||
Notes: orderItem.Notes,
|
|
||||||
Metadata: map[string]interface{}(orderItem.Metadata),
|
|
||||||
Status: constants.OrderItemStatus(orderItem.Status),
|
|
||||||
CreatedAt: orderItem.CreatedAt,
|
|
||||||
UpdatedAt: orderItem.UpdatedAt,
|
|
||||||
}
|
}
|
||||||
addedItemResponses = append(addedItemResponses, itemResponse)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
orderWithRelations, err := p.orderRepo.GetWithRelations(ctx, orderID)
|
orderWithRelations, err := p.orderRepo.GetWithRelations(ctx, orderID)
|
||||||
|
|||||||
@ -46,9 +46,10 @@ func (p *ProductOutletPriceProcessorImpl) Upsert(ctx context.Context, req *model
|
|||||||
}
|
}
|
||||||
|
|
||||||
entity := &entities.ProductOutletPrice{
|
entity := &entities.ProductOutletPrice{
|
||||||
ProductID: req.ProductID,
|
ProductID: req.ProductID,
|
||||||
OutletID: req.OutletID,
|
OutletID: req.OutletID,
|
||||||
Price: req.Price,
|
Price: req.Price,
|
||||||
|
PrintToChecker: req.PrintToChecker,
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := p.repo.Upsert(ctx, entity); err != nil {
|
if err := p.repo.Upsert(ctx, entity); err != nil {
|
||||||
|
|||||||
@ -5,6 +5,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"apskel-pos-be/internal/entities"
|
"apskel-pos-be/internal/entities"
|
||||||
|
"apskel-pos-be/internal/logger"
|
||||||
"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"
|
||||||
@ -125,10 +126,15 @@ func (p *ProductProcessorImpl) CreateProduct(ctx context.Context, req *models.Cr
|
|||||||
|
|
||||||
// Upsert outlet-specific price if outlet context is present
|
// Upsert outlet-specific price if outlet context is present
|
||||||
if req.OutletID != uuid.Nil {
|
if req.OutletID != uuid.Nil {
|
||||||
|
printToChecker := true // default
|
||||||
|
if req.PrintToChecker != nil {
|
||||||
|
printToChecker = *req.PrintToChecker
|
||||||
|
}
|
||||||
outletPriceEntity := &entities.ProductOutletPrice{
|
outletPriceEntity := &entities.ProductOutletPrice{
|
||||||
ProductID: productEntity.ID,
|
ProductID: productEntity.ID,
|
||||||
OutletID: req.OutletID,
|
OutletID: req.OutletID,
|
||||||
Price: req.Price,
|
Price: req.Price,
|
||||||
|
PrintToChecker: printToChecker,
|
||||||
}
|
}
|
||||||
if err := p.outletPriceRepo.Upsert(ctx, outletPriceEntity); err != nil {
|
if err := p.outletPriceRepo.Upsert(ctx, outletPriceEntity); err != nil {
|
||||||
return nil, fmt.Errorf("failed to assign outlet price: %w", err)
|
return nil, fmt.Errorf("failed to assign outlet price: %w", err)
|
||||||
@ -196,16 +202,39 @@ func (p *ProductProcessorImpl) UpdateProduct(ctx context.Context, id uuid.UUID,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Upsert outlet-specific price if outlet context is present
|
// Upsert outlet-specific price if outlet context is present and price or print_to_checker is provided
|
||||||
if req.OutletID != uuid.Nil && req.Price != nil {
|
if req.OutletID != uuid.Nil && (req.Price != nil || req.PrintToChecker != nil) {
|
||||||
outletPriceEntity := &entities.ProductOutletPrice{
|
// Fetch existing outlet price to use as fallback for fields not provided
|
||||||
ProductID: id,
|
existing, _ := p.outletPriceRepo.GetByProductAndOutlet(ctx, id, req.OutletID)
|
||||||
OutletID: req.OutletID,
|
|
||||||
Price: *req.Price,
|
price := float64(0)
|
||||||
|
if existing != nil {
|
||||||
|
price = existing.Price
|
||||||
}
|
}
|
||||||
|
if req.Price != nil {
|
||||||
|
price = *req.Price
|
||||||
|
}
|
||||||
|
|
||||||
|
printToChecker := true // default
|
||||||
|
if existing != nil {
|
||||||
|
printToChecker = existing.PrintToChecker
|
||||||
|
}
|
||||||
|
if req.PrintToChecker != nil {
|
||||||
|
printToChecker = *req.PrintToChecker
|
||||||
|
}
|
||||||
|
|
||||||
|
outletPriceEntity := &entities.ProductOutletPrice{
|
||||||
|
ProductID: id,
|
||||||
|
OutletID: req.OutletID,
|
||||||
|
Price: price,
|
||||||
|
PrintToChecker: printToChecker,
|
||||||
|
}
|
||||||
|
logger.FromContext(ctx).Infof("ProductProcessor::UpdateProduct -> upserting outlet price: productID=%s outletID=%s price=%f printToChecker=%v", id, req.OutletID, price, printToChecker)
|
||||||
if err := p.outletPriceRepo.Upsert(ctx, outletPriceEntity); err != nil {
|
if err := p.outletPriceRepo.Upsert(ctx, outletPriceEntity); err != nil {
|
||||||
return nil, fmt.Errorf("failed to assign outlet price: %w", err)
|
return nil, fmt.Errorf("failed to assign outlet price: %w", err)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
logger.FromContext(ctx).Infof("ProductProcessor::UpdateProduct -> skipping outlet price upsert: outletID=%s price=%v printToChecker=%v", req.OutletID, req.Price, req.PrintToChecker)
|
||||||
}
|
}
|
||||||
|
|
||||||
productWithCategory, err := p.productRepo.GetWithCategory(ctx, id)
|
productWithCategory, err := p.productRepo.GetWithCategory(ctx, id)
|
||||||
@ -256,6 +285,7 @@ func (p *ProductProcessorImpl) GetProductByID(ctx context.Context, id uuid.UUID,
|
|||||||
outletPrice, err := p.outletPriceRepo.GetByProductAndOutlet(ctx, id, outletID)
|
outletPrice, err := p.outletPriceRepo.GetByProductAndOutlet(ctx, id, outletID)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
response.OutletPrice = &outletPrice.Price
|
response.OutletPrice = &outletPrice.Price
|
||||||
|
response.PrintToChecker = outletPrice.PrintToChecker
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// No outlet context — return all outlet prices for this product
|
// No outlet context — return all outlet prices for this product
|
||||||
@ -264,9 +294,10 @@ func (p *ProductProcessorImpl) GetProductByID(ctx context.Context, id uuid.UUID,
|
|||||||
prices := make([]models.OutletPrice, len(outletPrices))
|
prices := make([]models.OutletPrice, len(outletPrices))
|
||||||
for i, op := range outletPrices {
|
for i, op := range outletPrices {
|
||||||
prices[i] = models.OutletPrice{
|
prices[i] = models.OutletPrice{
|
||||||
OutletID: op.OutletID,
|
OutletID: op.OutletID,
|
||||||
OutletName: op.Outlet.Name,
|
OutletName: op.Outlet.Name,
|
||||||
Price: op.Price,
|
Price: op.Price,
|
||||||
|
PrintToChecker: op.PrintToChecker,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
response.OutletPrices = prices
|
response.OutletPrices = prices
|
||||||
@ -303,10 +334,35 @@ func (p *ProductProcessorImpl) ListProducts(ctx context.Context, filters map[str
|
|||||||
}
|
}
|
||||||
|
|
||||||
responses := make([]models.ProductResponse, len(productEntities))
|
responses := make([]models.ProductResponse, len(productEntities))
|
||||||
for i, entity := range productEntities {
|
if outletID != uuid.Nil && len(productEntities) > 0 {
|
||||||
response := mappers.ProductEntityToResponse(entity)
|
// Bulk-fetch outlet prices to populate OutletPrice and PrintToChecker per product
|
||||||
if response != nil {
|
productIDs := make([]uuid.UUID, len(productEntities))
|
||||||
responses[i] = *response
|
for i, e := range productEntities {
|
||||||
|
productIDs[i] = e.ID
|
||||||
|
}
|
||||||
|
outletPrices, opErr := p.outletPriceRepo.GetByProductsAndOutlet(ctx, productIDs, outletID)
|
||||||
|
priceMap := make(map[uuid.UUID]*entities.ProductOutletPrice)
|
||||||
|
if opErr == nil {
|
||||||
|
for _, op := range outletPrices {
|
||||||
|
priceMap[op.ProductID] = op
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for i, entity := range productEntities {
|
||||||
|
response := mappers.ProductEntityToResponse(entity)
|
||||||
|
if response != nil {
|
||||||
|
if op, ok := priceMap[entity.ID]; ok {
|
||||||
|
response.OutletPrice = &op.Price
|
||||||
|
response.PrintToChecker = op.PrintToChecker
|
||||||
|
}
|
||||||
|
responses[i] = *response
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for i, entity := range productEntities {
|
||||||
|
response := mappers.ProductEntityToResponse(entity)
|
||||||
|
if response != nil {
|
||||||
|
responses[i] = *response
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -60,6 +60,8 @@ func (r *OrderRepositoryImpl) GetWithRelations(ctx context.Context, id uuid.UUID
|
|||||||
Preload("User").
|
Preload("User").
|
||||||
Preload("OrderItems").
|
Preload("OrderItems").
|
||||||
Preload("OrderItems.Product").
|
Preload("OrderItems.Product").
|
||||||
|
Preload("OrderItems.Product.Category").
|
||||||
|
Preload("OrderItems.Product.ProductOutletPrices").
|
||||||
Preload("OrderItems.ProductVariant").
|
Preload("OrderItems.ProductVariant").
|
||||||
Preload("Payments").
|
Preload("Payments").
|
||||||
Preload("Payments.PaymentMethod").
|
Preload("Payments.PaymentMethod").
|
||||||
@ -139,6 +141,8 @@ func (r *OrderRepositoryImpl) List(ctx context.Context, filters map[string]inter
|
|||||||
Preload("User").
|
Preload("User").
|
||||||
Preload("OrderItems").
|
Preload("OrderItems").
|
||||||
Preload("OrderItems.Product").
|
Preload("OrderItems.Product").
|
||||||
|
Preload("OrderItems.Product.Category").
|
||||||
|
Preload("OrderItems.Product.ProductOutletPrices").
|
||||||
Preload("OrderItems.ProductVariant").
|
Preload("OrderItems.ProductVariant").
|
||||||
Preload("Payments").
|
Preload("Payments").
|
||||||
Preload("Payments.PaymentMethod").
|
Preload("Payments.PaymentMethod").
|
||||||
@ -155,6 +159,8 @@ func (r *OrderRepositoryImpl) ListBySessionID(ctx context.Context, sessionID str
|
|||||||
Preload("User").
|
Preload("User").
|
||||||
Preload("OrderItems").
|
Preload("OrderItems").
|
||||||
Preload("OrderItems.Product").
|
Preload("OrderItems.Product").
|
||||||
|
Preload("OrderItems.Product.Category").
|
||||||
|
Preload("OrderItems.Product.ProductOutletPrices").
|
||||||
Preload("OrderItems.ProductVariant").
|
Preload("OrderItems.ProductVariant").
|
||||||
Preload("Payments").
|
Preload("Payments").
|
||||||
Preload("Payments.PaymentMethod").
|
Preload("Payments.PaymentMethod").
|
||||||
|
|||||||
@ -7,7 +7,6 @@ import (
|
|||||||
|
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"gorm.io/gorm"
|
"gorm.io/gorm"
|
||||||
"gorm.io/gorm/clause"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type ProductOutletPriceRepository interface {
|
type ProductOutletPriceRepository interface {
|
||||||
@ -53,10 +52,18 @@ func (r *ProductOutletPriceRepositoryImpl) GetByOutlet(ctx context.Context, outl
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (r *ProductOutletPriceRepositoryImpl) Upsert(ctx context.Context, price *entities.ProductOutletPrice) error {
|
func (r *ProductOutletPriceRepositoryImpl) Upsert(ctx context.Context, price *entities.ProductOutletPrice) error {
|
||||||
return r.db.WithContext(ctx).Clauses(clause.OnConflict{
|
if price.ID == uuid.Nil {
|
||||||
Columns: []clause.Column{{Name: "product_id"}, {Name: "outlet_id"}},
|
price.ID = uuid.New()
|
||||||
DoUpdates: clause.AssignmentColumns([]string{"price", "updated_at"}),
|
}
|
||||||
}).Create(price).Error
|
return r.db.WithContext(ctx).Exec(`
|
||||||
|
INSERT INTO product_outlet_prices (id, product_id, outlet_id, price, print_to_checker, created_at, updated_at)
|
||||||
|
VALUES (?, ?, ?, ?, ?, NOW(), NOW())
|
||||||
|
ON CONFLICT (product_id, outlet_id)
|
||||||
|
DO UPDATE SET
|
||||||
|
price = EXCLUDED.price,
|
||||||
|
print_to_checker = EXCLUDED.print_to_checker,
|
||||||
|
updated_at = NOW()
|
||||||
|
`, price.ID, price.ProductID, price.OutletID, price.Price, price.PrintToChecker).Error
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *ProductOutletPriceRepositoryImpl) Delete(ctx context.Context, id uuid.UUID) error {
|
func (r *ProductOutletPriceRepositoryImpl) Delete(ctx context.Context, id uuid.UUID) error {
|
||||||
|
|||||||
@ -105,9 +105,10 @@ func (s *ProductOutletPriceServiceImpl) BulkUpsert(ctx context.Context, req *con
|
|||||||
prices := make([]models.CreateProductOutletPriceRequest, len(req.Prices))
|
prices := make([]models.CreateProductOutletPriceRequest, len(req.Prices))
|
||||||
for i, p := range req.Prices {
|
for i, p := range req.Prices {
|
||||||
prices[i] = models.CreateProductOutletPriceRequest{
|
prices[i] = models.CreateProductOutletPriceRequest{
|
||||||
ProductID: req.ProductID,
|
ProductID: req.ProductID,
|
||||||
OutletID: p.OutletID,
|
OutletID: p.OutletID,
|
||||||
Price: p.Price,
|
Price: p.Price,
|
||||||
|
PrintToChecker: p.PrintToChecker,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -100,6 +100,8 @@ func OrderModelToContract(resp *models.OrderResponse) *contract.OrderResponse {
|
|||||||
ProductName: item.ProductName,
|
ProductName: item.ProductName,
|
||||||
ProductVariantID: item.ProductVariantID,
|
ProductVariantID: item.ProductVariantID,
|
||||||
ProductVariantName: item.ProductVariantName,
|
ProductVariantName: item.ProductVariantName,
|
||||||
|
CategoryID: item.CategoryID,
|
||||||
|
CategoryName: item.CategoryName,
|
||||||
Quantity: item.Quantity,
|
Quantity: item.Quantity,
|
||||||
UnitPrice: item.UnitPrice,
|
UnitPrice: item.UnitPrice,
|
||||||
TotalPrice: item.TotalPrice,
|
TotalPrice: item.TotalPrice,
|
||||||
@ -110,6 +112,7 @@ func OrderModelToContract(resp *models.OrderResponse) *contract.OrderResponse {
|
|||||||
CreatedAt: item.CreatedAt,
|
CreatedAt: item.CreatedAt,
|
||||||
UpdatedAt: item.UpdatedAt,
|
UpdatedAt: item.UpdatedAt,
|
||||||
PrinterType: item.PrinterType,
|
PrinterType: item.PrinterType,
|
||||||
|
PrintToChecker: item.PrintToChecker,
|
||||||
PaidQuantity: item.PaidQuantity,
|
PaidQuantity: item.PaidQuantity,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -168,6 +171,8 @@ func AddToOrderModelToContract(resp *models.AddToOrderResponse) *contract.AddToO
|
|||||||
ProductName: item.ProductName,
|
ProductName: item.ProductName,
|
||||||
ProductVariantID: item.ProductVariantID,
|
ProductVariantID: item.ProductVariantID,
|
||||||
ProductVariantName: item.ProductVariantName,
|
ProductVariantName: item.ProductVariantName,
|
||||||
|
CategoryID: item.CategoryID,
|
||||||
|
CategoryName: item.CategoryName,
|
||||||
Quantity: item.Quantity,
|
Quantity: item.Quantity,
|
||||||
UnitPrice: item.UnitPrice,
|
UnitPrice: item.UnitPrice,
|
||||||
TotalPrice: item.TotalPrice,
|
TotalPrice: item.TotalPrice,
|
||||||
@ -177,6 +182,7 @@ func AddToOrderModelToContract(resp *models.AddToOrderResponse) *contract.AddToO
|
|||||||
Status: string(item.Status),
|
Status: string(item.Status),
|
||||||
CreatedAt: item.CreatedAt,
|
CreatedAt: item.CreatedAt,
|
||||||
UpdatedAt: item.UpdatedAt,
|
UpdatedAt: item.UpdatedAt,
|
||||||
|
PrintToChecker: item.PrintToChecker,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return &contract.AddToOrderResponse{
|
return &contract.AddToOrderResponse{
|
||||||
|
|||||||
@ -11,9 +11,10 @@ func CreateProductOutletPriceRequestToModel(req *contract.CreateProductOutletPri
|
|||||||
}
|
}
|
||||||
|
|
||||||
return &models.CreateProductOutletPriceRequest{
|
return &models.CreateProductOutletPriceRequest{
|
||||||
ProductID: req.ProductID,
|
ProductID: req.ProductID,
|
||||||
OutletID: req.OutletID,
|
OutletID: req.OutletID,
|
||||||
Price: req.Price,
|
Price: req.Price,
|
||||||
|
PrintToChecker: req.PrintToChecker,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -23,7 +24,8 @@ func UpdateProductOutletPriceRequestToModel(req *contract.UpdateProductOutletPri
|
|||||||
}
|
}
|
||||||
|
|
||||||
return &models.UpdateProductOutletPriceRequest{
|
return &models.UpdateProductOutletPriceRequest{
|
||||||
Price: &req.Price,
|
Price: &req.Price,
|
||||||
|
PrintToChecker: req.PrintToChecker,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,12 +35,13 @@ func ProductOutletPriceModelToResponse(m *models.ProductOutletPrice) *contract.P
|
|||||||
}
|
}
|
||||||
|
|
||||||
return &contract.ProductOutletPriceResponse{
|
return &contract.ProductOutletPriceResponse{
|
||||||
ID: m.ID,
|
ID: m.ID,
|
||||||
ProductID: m.ProductID,
|
ProductID: m.ProductID,
|
||||||
OutletID: m.OutletID,
|
OutletID: m.OutletID,
|
||||||
Price: m.Price,
|
Price: m.Price,
|
||||||
CreatedAt: m.CreatedAt,
|
PrintToChecker: m.PrintToChecker,
|
||||||
UpdatedAt: m.UpdatedAt,
|
CreatedAt: m.CreatedAt,
|
||||||
|
UpdatedAt: m.UpdatedAt,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -57,6 +57,7 @@ func CreateProductRequestToModel(apctx *appcontext.ContextInfo, req *contract.Cr
|
|||||||
BusinessType: businessType,
|
BusinessType: businessType,
|
||||||
ImageURL: req.ImageURL,
|
ImageURL: req.ImageURL,
|
||||||
PrinterType: req.PrinterType,
|
PrinterType: req.PrinterType,
|
||||||
|
PrintToChecker: req.PrintToChecker,
|
||||||
Metadata: metadata,
|
Metadata: metadata,
|
||||||
Variants: variants,
|
Variants: variants,
|
||||||
}
|
}
|
||||||
@ -75,17 +76,18 @@ func UpdateProductRequestToModel(apctx *appcontext.ContextInfo, req *contract.Up
|
|||||||
}
|
}
|
||||||
|
|
||||||
return &models.UpdateProductRequest{
|
return &models.UpdateProductRequest{
|
||||||
OutletID: outletID,
|
OutletID: outletID,
|
||||||
CategoryID: req.CategoryID,
|
CategoryID: req.CategoryID,
|
||||||
SKU: req.SKU,
|
SKU: req.SKU,
|
||||||
Name: req.Name,
|
Name: req.Name,
|
||||||
Description: req.Description,
|
Description: req.Description,
|
||||||
Price: req.Price,
|
Price: req.Price,
|
||||||
Cost: req.Cost,
|
Cost: req.Cost,
|
||||||
ImageURL: req.ImageURL,
|
ImageURL: req.ImageURL,
|
||||||
PrinterType: req.PrinterType,
|
PrinterType: req.PrinterType,
|
||||||
Metadata: metadata,
|
PrintToChecker: req.PrintToChecker,
|
||||||
IsActive: req.IsActive,
|
Metadata: metadata,
|
||||||
|
IsActive: req.IsActive,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,9 +121,10 @@ func ProductModelResponseToResponse(prod *models.ProductResponse) *contract.Prod
|
|||||||
outletPriceResponses = make([]contract.ProductOutletPriceResponse, len(prod.OutletPrices))
|
outletPriceResponses = make([]contract.ProductOutletPriceResponse, len(prod.OutletPrices))
|
||||||
for i, op := range prod.OutletPrices {
|
for i, op := range prod.OutletPrices {
|
||||||
outletPriceResponses[i] = contract.ProductOutletPriceResponse{
|
outletPriceResponses[i] = contract.ProductOutletPriceResponse{
|
||||||
OutletID: op.OutletID,
|
OutletID: op.OutletID,
|
||||||
OutletName: op.OutletName,
|
OutletName: op.OutletName,
|
||||||
Price: op.Price,
|
Price: op.Price,
|
||||||
|
PrintToChecker: op.PrintToChecker,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -141,6 +144,7 @@ func ProductModelResponseToResponse(prod *models.ProductResponse) *contract.Prod
|
|||||||
BusinessType: string(prod.BusinessType),
|
BusinessType: string(prod.BusinessType),
|
||||||
ImageURL: prod.ImageURL,
|
ImageURL: prod.ImageURL,
|
||||||
PrinterType: prod.PrinterType,
|
PrinterType: prod.PrinterType,
|
||||||
|
PrintToChecker: prod.PrintToChecker,
|
||||||
Metadata: prod.Metadata,
|
Metadata: prod.Metadata,
|
||||||
IsActive: prod.IsActive,
|
IsActive: prod.IsActive,
|
||||||
CreatedAt: prod.CreatedAt,
|
CreatedAt: prod.CreatedAt,
|
||||||
|
|||||||
@ -0,0 +1 @@
|
|||||||
|
ALTER TABLE product_outlet_prices DROP COLUMN IF EXISTS print_to_checker;
|
||||||
@ -0,0 +1 @@
|
|||||||
|
ALTER TABLE product_outlet_prices ADD COLUMN print_to_checker BOOLEAN NOT NULL DEFAULT TRUE;
|
||||||
Loading…
x
Reference in New Issue
Block a user