This commit is contained in:
saeid_01 2023-11-01 20:12:26 +03:30
parent 71cd11920b
commit 2885bd9a17
13 changed files with 564 additions and 25 deletions

View File

@ -1,14 +1,12 @@
package handler_products
import (
"log"
"online-order/entity"
"online-order/repository/product"
"online-order/usecase/product"
)
func NewProductRouters(server *entity.Routers) {
log.Printf("server: %v", server.ActiveBusiness)
productRepo := repository_product.NewProductClient(server.Database, &server.ActiveBusiness)
productService := service_product.NewProductService(productRepo)

View File

@ -8,6 +8,7 @@ import (
handler_products "online-order/api/handlers/products"
"online-order/api/middlewares"
middlewares_log "online-order/api/middlewares/log"
"online-order/database/seeds"
docs "online-order/docs"
"online-order/ent"
"online-order/entity"
@ -29,6 +30,9 @@ func Router(app *gin.Engine, db *ent.Client) {
RestrictedApp: api_restricted,
}
seeds.FillProductCategories(router)
seeds.FillProducts(router)
middlewares_log.SetOutputLogFile()
logFile, _ := middlewares_log.OpenFile("storage/logs/request.log")

View File

@ -0,0 +1,67 @@
package seeds
import (
"log"
"online-order/entity"
repository_product "online-order/repository/product"
repository_product_category "online-order/repository/product_category"
service_product "online-order/usecase/product"
service_product_category "online-order/usecase/product_category"
)
func fetchProductsFromJsonFile() *[]entity.ProductCreateUpdate {
file := CreateFile("database/seeds/resources/products.json")
pl := []entity.ProductCreateUpdate{}
if err := file.ReadJson(&pl); err != nil {
log.Println("on FillProducts an error occured: ", err)
return nil
}
return &pl
}
func fetchProductCategoriesFromJsonFile() *[]entity.ProductCategoryCreateUpdate {
file := CreateFile("database/seeds/resources/categories.json")
pl := []entity.ProductCategoryCreateUpdate{}
if err := file.ReadJson(&pl); err != nil {
log.Println("on FillProducts an error occured: ", err)
return nil
}
return &pl
}
func FillProductCategories(server *entity.Routers) {
productCategories := fetchProductCategoriesFromJsonFile()
activeBusiness := entity.ActiveBusiness{
BusinessID: 1,
DomainID: 1,
Domain: "localhost",
}
productCategoryRepo := repository_product_category.NewProductCategoryClient(server.Database, &activeBusiness)
productCategoryService := service_product_category.NewProductCategoryService(productCategoryRepo)
for _, item := range *productCategories {
productCategoryService.SyncWithSlug(item.Slug, &item)
}
}
func FillProducts(server *entity.Routers) {
products := fetchProductsFromJsonFile()
activeBusiness := entity.ActiveBusiness{
BusinessID: 1,
DomainID: 1,
Domain: "localhost",
}
productRepo := repository_product.NewProductClient(server.Database, &activeBusiness)
productService := service_product.NewProductService(productRepo)
for _, item := range *products {
productService.Create(&item)
}
}

View File

@ -0,0 +1,30 @@
package seeds
import (
"encoding/json"
"io/ioutil"
"log"
)
type file struct {
filePath string
}
func CreateFile(filePath string) *file {
return &file{
filePath: filePath,
}
}
func (f file) ReadJson(obj interface{}) error {
if content, err := ioutil.ReadFile(f.filePath); err != nil {
log.Println("on ReadJson an error occured: ", err)
return err
} else {
if err := json.Unmarshal(content, &obj); err != nil {
log.Println("on ReadJson an error occured: ", err)
return err
}
}
return nil
}

View File

@ -0,0 +1,34 @@
[
{
"id": 1,
"name": "Digital",
"slug": "digital",
"status": true,
"description": "digital",
"business_id": 1
},
{
"id": 2,
"name": "Washer",
"slug": "washer",
"status": true,
"description": "washer",
"business_id": 1
},
{
"id": 3,
"name": "Accessory",
"slug": "accessory",
"status": true,
"description": "accessory",
"business_id": 1
},
{
"id": 4,
"name": "Stationery",
"slug": "stationery",
"status": true,
"description": "stationery",
"business_id": 1
}
]

View File

@ -0,0 +1,98 @@
[
{
"name": "laptop",
"price": 200,
"original_price": 300,
"quantity": 5,
"status": true,
"description": "Asus Laptop",
"summary": "Asus Laptop",
"product_category_id": 1,
"business_id": 1,
"user_id": 1
},
{
"name": "Hair shampoo",
"price": 200,
"original_price": 300,
"quantity": 5,
"status": true,
"description": "Hair Shampoo",
"summary": "Hair Shampoo",
"product_category_id": 2,
"business_id": 1,
"user_id": 1
},
{
"name": "Body Shampoo",
"price": 200,
"original_price": 300,
"quantity": 5,
"status": true,
"description": "Body Shampoo",
"summary": "Body Shampoo",
"product_category_id": 2,
"business_id": 1,
"user_id": 1
},
{
"name": "camera",
"price": 200,
"original_price": 300,
"quantity": 5,
"status": true,
"description": "Sony Camera",
"summary": "Sony Camera",
"product_category_id": 1,
"business_id": 1,
"user_id": 1
},
{
"name": "sunglasses",
"price": 200,
"original_price": 300,
"quantity": 5,
"status": true,
"description": "zenit sunglasses",
"summary": "zenit sunglasses",
"product_category_id": 3,
"business_id": 1,
"user_id": 1
},
{
"name": "pen",
"price": 200,
"original_price": 300,
"quantity": 5,
"status": true,
"description": "Blue pen",
"summary": "Blue pen",
"product_category_id": 4,
"business_id": 1,
"user_id": 1
},
{
"name": "Black pen",
"price": 200,
"original_price": 300,
"quantity": 5,
"status": true,
"description": "black pen",
"summary": "black pen",
"product_category_id": 4,
"business_id": 1,
"user_id": 1
},
{
"name": "Red pen",
"price": 200,
"original_price": 300,
"quantity": 5,
"status": true,
"description": "red pen",
"summary": "black pen",
"product_category_id": 4,
"business_id": 1,
"user_id": 1
}
]

View File

@ -0,0 +1,34 @@
package domain
import (
"github.com/gin-gonic/gin"
"online-order/entity"
)
type ProductCategoryRepository interface {
List() ([]*entity.ProductCategoryDisplay, error)
Create(p *entity.ProductCategoryCreateUpdate) error
GetByID(id int) (*entity.ProductCategoryDisplay, error)
GetBySlug(slug string) (*entity.ProductCategoryDisplay, error)
SearchProductCategory(identifier string) (*entity.ProductCategoryDisplay, error)
Update(p *entity.ProductCategoryCreateUpdate) error
Delete(id int) error
}
type ProductCategoryService interface {
List() ([]*entity.ProductCategoryDisplay, error)
Create(u *entity.ProductCategoryCreateUpdate) error
GetByID(id int) (*entity.ProductCategoryDisplay, error)
GetBySlug(slug string) (*entity.ProductCategoryDisplay, error)
SyncWithSlug(slug string, p *entity.ProductCategoryCreateUpdate) error
SearchProductCategory(identifier string) (*entity.ProductCategoryDisplay, error)
Update(u *entity.ProductCategoryCreateUpdate) error
Delete(id int) error
}
type ProductCategoryController interface {
listProductCategory(ctx *gin.Context)
getProductCategory(ctx *gin.Context)
updateProductCategory(ctx *gin.Context)
deleteProductCategory(ctx *gin.Context)
}

View File

@ -9,10 +9,13 @@ type ProductDisplay struct {
ID int `json:"id"`
Name string `json:"name"`
Description *string `json:"description"`
Summary *string `json:"summary"`
Price float64 `json:"price"`
OriginalPrice float64 `json:"original_price"`
Quantity int `json:"quantity"`
Status bool `json:"status"`
UserID int `json:"user_id"`
ProductCategoryID int `json:"product_category_id"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
@ -20,6 +23,7 @@ type ProductDisplay struct {
// use to create or update a product
type ProductCreateUpdate struct {
ProductDisplay
BusinessID int `json:"business_id"`
}
// Func that will check non empty field on ProductDisplay and update product

View File

@ -0,0 +1,50 @@
package entity
import (
"time"
)
// use to display a product
type ProductCategoryDisplay struct {
ID int `json:"id"`
Name string `json:"name"`
Slug string `json:"slug"`
Description *string `json:"description"`
Summary *string `json:"summary"`
Status bool `json:"status"`
CreatedAt time.Time `json:"created_at"`
UpdatedAt time.Time `json:"updated_at"`
}
// use to create or update a product
type ProductCategoryCreateUpdate struct {
ProductCategoryDisplay
BusinessID int `json:"business_id"`
}
// Func that will check non empty field on ProductDisplay and update product
func ValidateProductCategoryUpdate(product *ProductCategoryCreateUpdate, p *ProductCategoryDisplay) *ProductCategoryCreateUpdate {
product.ID = p.ID
product.Name = p.Name
product.Description = p.Description
product.Summary = p.Summary
product.Status = p.Status
product.CreatedAt = p.CreatedAt
product.UpdatedAt = p.UpdatedAt
return product
}
func ProductCategoryDisplayFormatter(product *ProductCategoryCreateUpdate) (p *ProductCategoryDisplay) {
p = &ProductCategoryDisplay{
ID: product.ID,
Name: product.Name,
Description: product.Description,
Summary: product.Summary,
Status: product.Status,
CreatedAt: product.CreatedAt,
UpdatedAt: product.UpdatedAt,
}
return
}

View File

@ -19,16 +19,6 @@ func NewProductClient(client *ent.Client, activeBusiness *entity.ActiveBusiness)
}
}
//type ProductClient struct {
// client *ent.Client
//}
//
//func NewProductClient(client *ent.Client) *ProductClient {
// return &ProductClient{
// client: client,
// }
//}
// List all products
func (c *ProductClient) List() ([]*entity.ProductDisplay, error) {
var u []*entity.ProductDisplay
@ -58,7 +48,10 @@ func (c *ProductClient) Create(p *entity.ProductCreateUpdate) error {
SetNillableDescription(p.Description).
SetPrice(p.Price).
SetOriginalPrice(p.OriginalPrice).
SetNillableSummary(p.Summary).
SetQuantity(p.Quantity).
SetProductCategoryID(p.ProductCategoryID).
SetUserID(p.UserID).
SetStatus(p.Status).
Save(ctx)

View File

@ -0,0 +1,162 @@
package repository_product_category
import (
"context"
"online-order/ent"
"online-order/ent/productcategory"
"online-order/entity"
)
type ProductCategoryClient struct {
client *ent.Client
activeBusiness *entity.ActiveBusiness
}
func NewProductCategoryClient(client *ent.Client, activeBusiness *entity.ActiveBusiness) *ProductCategoryClient {
return &ProductCategoryClient{
client: client,
activeBusiness: activeBusiness,
}
}
// List all productCategories
func (c *ProductCategoryClient) List() ([]*entity.ProductCategoryDisplay, error) {
var u []*entity.ProductCategoryDisplay
ctx := context.Background()
err := c.client.ProductCategory.
Query().
Where(productcategory.BusinessID(c.activeBusiness.BusinessID)).
Select(productcategory.FieldID, productcategory.FieldName, productcategory.FieldDescription, productcategory.FieldStatus, productcategory.FieldCreatedAt, productcategory.FieldUpdatedAt).
Scan(ctx, &u)
if err != nil {
return nil, err
}
return u, nil
}
// Create a productcategory
func (c *ProductCategoryClient) Create(p *entity.ProductCategoryCreateUpdate) error {
ctx := context.Background()
resp, err := c.client.ProductCategory.
Create().
SetName(p.Name).
SetSlug(p.Slug).
SetBusinessID(c.activeBusiness.BusinessID).
SetNillableDescription(p.Description).
SetStatus(p.Status).
Save(ctx)
if err != nil {
return err
}
p.ID = resp.ID
p.CreatedAt = resp.CreatedAt
p.UpdatedAt = resp.UpdatedAt
return nil
}
func (c *ProductCategoryClient) GetByID(id int) (*entity.ProductCategoryDisplay, error) {
var p entity.ProductCategoryDisplay
ctx := context.Background()
resp := c.client.ProductCategory.
Query().
Where(productcategory.BusinessID(c.activeBusiness.BusinessID)).
Where(productcategory.ID(id)).
AllX(ctx)
if len(resp) > 0 {
p.ID = resp[0].ID
p.Name = resp[0].Name
p.Description = resp[0].Description
p.Status = resp[0].Status
p.CreatedAt = resp[0].CreatedAt
p.UpdatedAt = resp[0].UpdatedAt
} else {
return nil, entity.ErrNotFound
}
return &p, nil
}
func (c *ProductCategoryClient) GetBySlug(slug string) (*entity.ProductCategoryDisplay, error) {
var p entity.ProductCategoryDisplay
ctx := context.Background()
resp := c.client.ProductCategory.
Query().
Where(productcategory.BusinessID(c.activeBusiness.BusinessID)).
Where(productcategory.Slug(slug)).
AllX(ctx)
if len(resp) > 0 {
p.ID = resp[0].ID
p.Name = resp[0].Name
p.Description = resp[0].Description
p.Status = resp[0].Status
p.CreatedAt = resp[0].CreatedAt
p.UpdatedAt = resp[0].UpdatedAt
} else {
return nil, entity.ErrNotFound
}
return &p, nil
}
// Update productcategory information, except password
func (c *ProductCategoryClient) Update(p *entity.ProductCategoryCreateUpdate) error {
ctx := context.Background()
_, err := c.client.ProductCategory.UpdateOneID(p.ID).
SetName(p.Name).
SetDescription(p.Name).
SetStatus(p.Status).
Save(ctx)
if err != nil {
return err
}
return nil
}
// Update user information, except password
func (c *ProductCategoryClient) Delete(id int) error {
ctx := context.Background()
err := c.client.ProductCategory.
DeleteOneID(id).
Exec(ctx)
return err
}
// Search a user information by email or username
func (c *ProductCategoryClient) SearchProductCategory(identifier string) (*entity.ProductCategoryDisplay, error) {
var p entity.ProductCategoryDisplay
ctx := context.Background()
resp := c.client.ProductCategory.
Query().
Where(productcategory.BusinessID(c.activeBusiness.BusinessID)).
Where(
productcategory.NameContains(identifier),
).
AllX(ctx)
if len(resp) > 0 {
p.ID = resp[0].ID
p.Name = resp[0].Name
p.Description = resp[0].Description
p.Status = resp[0].Status
p.CreatedAt = resp[0].CreatedAt
p.UpdatedAt = resp[0].UpdatedAt
} else {
return nil, entity.ErrNotFound
}
return &p, nil
}

View File

@ -19,8 +19,8 @@ func (s *productservice) List() ([]*entity.ProductDisplay, error) {
return s.repo.List()
}
func (s *productservice) Create(u *entity.ProductCreateUpdate) error {
return s.repo.Create(u)
func (s *productservice) Create(p *entity.ProductCreateUpdate) error {
return s.repo.Create(p)
}
// Retrieve a product
@ -32,8 +32,8 @@ func (s *productservice) GetByID(id int) (*entity.ProductDisplay, error) {
return u, nil
}
func (s *productservice) Update(u *entity.ProductCreateUpdate) error {
return s.repo.Update(u)
func (s *productservice) Update(p *entity.ProductCreateUpdate) error {
return s.repo.Update(p)
}
func (s *productservice) SearchProduct(identifier string) (*entity.ProductDisplay, error) {

View File

@ -0,0 +1,65 @@
package service_product_category
import (
"online-order/domain"
"online-order/entity"
)
type productCategoryService struct {
repo domain.ProductCategoryRepository
}
func NewProductCategoryService(r domain.ProductCategoryRepository) *productCategoryService {
return &productCategoryService{
repo: r,
}
}
func (s *productCategoryService) List() ([]*entity.ProductCategoryDisplay, error) {
return s.repo.List()
}
func (s *productCategoryService) Create(u *entity.ProductCategoryCreateUpdate) error {
return s.repo.Create(u)
}
// Retrieve a product
func (s *productCategoryService) GetByID(id int) (*entity.ProductCategoryDisplay, error) {
u, err := s.repo.GetByID(id)
if err != nil {
return &entity.ProductCategoryDisplay{}, entity.ErrNotFound
}
return u, nil
}
func (s *productCategoryService) GetBySlug(slug string) (*entity.ProductCategoryDisplay, error) {
u, err := s.repo.GetBySlug(slug)
if err != nil {
return &entity.ProductCategoryDisplay{}, entity.ErrNotFound
}
return u, nil
}
func (s *productCategoryService) Update(p *entity.ProductCategoryCreateUpdate) error {
return s.repo.Update(p)
}
func (s *productCategoryService) SearchProduct(identifier string) (*entity.ProductCategoryDisplay, error) {
return s.repo.SearchProductCategory(identifier)
}
func (s *productCategoryService) SyncWithSlug(slug string, p *entity.ProductCategoryCreateUpdate) error {
pc, _ := s.repo.GetBySlug(slug)
if pc != nil {
p.ID = pc.ID
p.Slug = pc.Slug
return s.repo.Update(p)
} else {
return s.repo.Create(p)
}
}
func (s *productCategoryService) Delete(id int) error {
return s.repo.Delete(id)
}