forked from ebhomengo/niki
Merge pull request 'feat(order): add create order' (#266) from feature/order into develop
Reviewed-on: ebhomengo/niki#266 Reviewed-by: hossein <h.nazari1990@gmail.com>
This commit is contained in:
commit
a652a4402a
|
|
@ -0,0 +1 @@
|
||||||
|
package command
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
package command
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
package command
|
||||||
|
|
@ -0,0 +1,63 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"flag"
|
||||||
|
"fmt"
|
||||||
|
"git.gocasts.ir/ebhomengo/niki/purchaseapp/delivery/http"
|
||||||
|
purchaseMysql "git.gocasts.ir/ebhomengo/niki/purchaseapp/repository/mysql"
|
||||||
|
"git.gocasts.ir/ebhomengo/niki/purchaseapp/service/order"
|
||||||
|
"git.gocasts.ir/ebhomengo/niki/repository/migrator"
|
||||||
|
"git.gocasts.ir/ebhomengo/niki/repository/mysql"
|
||||||
|
)
|
||||||
|
|
||||||
|
func MariaDB() *mysql.DB {
|
||||||
|
cfg := mysql.Config{
|
||||||
|
Username: "niki",
|
||||||
|
Password: "nikiappt0lk2o20",
|
||||||
|
Port: 3306,
|
||||||
|
Host: "localhost",
|
||||||
|
DBName: "niki_db",
|
||||||
|
}
|
||||||
|
migrate := flag.Bool("migrate", false, "perform database migration")
|
||||||
|
flag.Parse()
|
||||||
|
if *migrate {
|
||||||
|
migrator.New(migrator.Config{
|
||||||
|
MysqlConfig: cfg,
|
||||||
|
MigrationPath: "./purchaseapp/repository/mysql/migration",
|
||||||
|
MigrationDBName: "gorp_migrations",
|
||||||
|
}).Up()
|
||||||
|
}
|
||||||
|
|
||||||
|
return mysql.New(cfg)
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
cfg := mysql.Config{
|
||||||
|
Username: "niki",
|
||||||
|
Password: "nikiappt0lk2o20",
|
||||||
|
Port: 3306,
|
||||||
|
Host: "localhost",
|
||||||
|
DBName: "niki_db",
|
||||||
|
}
|
||||||
|
db := mysql.New(cfg)
|
||||||
|
defer func() {
|
||||||
|
if err := db.CloseStatements(); err != nil {
|
||||||
|
fmt.Printf("Error closing statements: %v\n", err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
orderRepo := purchaseMysql.New(db)
|
||||||
|
|
||||||
|
orderSvc := Service(orderRepo)
|
||||||
|
server := HTTPServer(orderSvc)
|
||||||
|
server.Serve()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func HTTPServer(orderSvc order.Service) *http.Server {
|
||||||
|
return http.New(orderSvc)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Service(orderRepo *purchaseMysql.DB) order.Service {
|
||||||
|
return order.New(orderRepo)
|
||||||
|
}
|
||||||
|
|
@ -12,12 +12,13 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
defaultPrefix = "EB_"
|
defaultPrefix = "EB_"
|
||||||
defaultDelimiter = "."
|
defaultDelimiter = "."
|
||||||
defaultSeparator = "__"
|
defaultSeparator = "__"
|
||||||
defaultYamlFilePath = "config.yml"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var defaultYamlFilePath = "config.yml"
|
||||||
|
|
||||||
var c Config
|
var c Config
|
||||||
|
|
||||||
type Option struct {
|
type Option struct {
|
||||||
|
|
|
||||||
|
|
@ -1 +1,61 @@
|
||||||
package purchaseapp
|
package purchaseapp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
purchaseHTTP "git.gocasts.ir/ebhomengo/niki/purchaseapp/delivery/http"
|
||||||
|
purchaseHandler "git.gocasts.ir/ebhomengo/niki/purchaseapp/delivery/http/order"
|
||||||
|
purchaseMysql "git.gocasts.ir/ebhomengo/niki/purchaseapp/repository/mysql"
|
||||||
|
purchaseService "git.gocasts.ir/ebhomengo/niki/purchaseapp/service/order"
|
||||||
|
"git.gocasts.ir/ebhomengo/niki/repository/mysql"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Application struct {
|
||||||
|
Config Config
|
||||||
|
HTTPServer *purchaseHTTP.Server
|
||||||
|
purchaseService purchaseService.Service
|
||||||
|
PurchaseHandler *purchaseHandler.Handler
|
||||||
|
PurchaseRepo purchaseService.Repo
|
||||||
|
DB *mysql.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
func SetUp(ctx context.Context, config Config, DB mysql.DB) *Application {
|
||||||
|
|
||||||
|
//cfg := mysql.Config{
|
||||||
|
// Username: "niki",
|
||||||
|
// Password: "nikiappt0lk2o20",
|
||||||
|
// Port: 3306,
|
||||||
|
// Host: "localhost",
|
||||||
|
// DBName: "niki_db",
|
||||||
|
//}
|
||||||
|
db := mysql.New(config.Mysql)
|
||||||
|
defer func() {
|
||||||
|
if err := db.CloseStatements(); err != nil {
|
||||||
|
fmt.Printf("Error closing statements: %v\n", err)
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
orderRepo := purchaseMysql.New(db)
|
||||||
|
|
||||||
|
orderSvc := Service(orderRepo)
|
||||||
|
server := HTTPServer(orderSvc)
|
||||||
|
handler := purchaseHandler.New(orderSvc)
|
||||||
|
|
||||||
|
return &Application{
|
||||||
|
Config: Config{},
|
||||||
|
HTTPServer: server,
|
||||||
|
purchaseService: orderSvc,
|
||||||
|
PurchaseHandler: handler,
|
||||||
|
PurchaseRepo: orderRepo,
|
||||||
|
DB: &DB,
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func HTTPServer(orderSvc purchaseService.Service) *purchaseHTTP.Server {
|
||||||
|
return purchaseHTTP.New(orderSvc)
|
||||||
|
}
|
||||||
|
|
||||||
|
func Service(orderRepo *purchaseMysql.DB) purchaseService.Service {
|
||||||
|
return purchaseService.New(orderRepo)
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,9 @@
|
||||||
package purchaseapp
|
package purchaseapp
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.gocasts.ir/ebhomengo/niki/repository/mysql"
|
||||||
|
)
|
||||||
|
|
||||||
type Config struct {
|
type Config struct {
|
||||||
|
Mysql mysql.Config `koanf:"mariadb"`
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
package invoice
|
|
||||||
|
|
||||||
type Handler struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
func New() *Handler {
|
|
||||||
return &Handler{}
|
|
||||||
}
|
|
||||||
|
|
@ -1,7 +0,0 @@
|
||||||
package invoice
|
|
||||||
|
|
||||||
import "github.com/labstack/echo/v4"
|
|
||||||
|
|
||||||
func (h Handler) SetRoutes(e *echo.Echo) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
@ -1,7 +1,68 @@
|
||||||
package order
|
package order
|
||||||
|
|
||||||
type Handler struct{}
|
import (
|
||||||
|
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
|
||||||
|
"git.gocasts.ir/ebhomengo/niki/purchaseapp/entity"
|
||||||
|
"git.gocasts.ir/ebhomengo/niki/purchaseapp/service/order"
|
||||||
|
"github.com/labstack/echo/v4"
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
func New() *Handler {
|
type Handler struct {
|
||||||
return &Handler{}
|
orderSvc *order.Service
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(orderSvc order.Service) *Handler {
|
||||||
|
return &Handler{orderSvc: &orderSvc}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (h *Handler) CreateOrderHandler(c echo.Context) error {
|
||||||
|
var req order.CreateOrderRequest
|
||||||
|
if err := c.Bind(&req); err != nil {
|
||||||
|
msg, code := getErrorDataFromRichError(err)
|
||||||
|
return echo.NewHTTPError(code, msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
orderItems := req.OrderItems
|
||||||
|
order := entity.Order{
|
||||||
|
ID: 0,
|
||||||
|
UserID: req.UserID,
|
||||||
|
TotalAmount: req.TotalAmount,
|
||||||
|
TotalDiscount: req.TotalDiscount,
|
||||||
|
ShippingID: req.ShippingID,
|
||||||
|
PaymentMethod: req.PaymentMethod,
|
||||||
|
ProcessStatus: entity.WaitingToPay,
|
||||||
|
PaymentStatus: entity.UnPaid,
|
||||||
|
Address: req.Address,
|
||||||
|
CreatedAt: time.Now(),
|
||||||
|
UpdatedAt: time.Now(),
|
||||||
|
}
|
||||||
|
resp, lErr := h.orderSvc.CreateOrder(order, orderItems)
|
||||||
|
|
||||||
|
if lErr != nil {
|
||||||
|
msg, code := getErrorDataFromRichError(lErr)
|
||||||
|
return echo.NewHTTPError(code, msg)
|
||||||
|
}
|
||||||
|
return c.JSON(http.StatusOK, resp)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getErrorDataFromRichError(err error) (message string, code int) {
|
||||||
|
switch err.(type) {
|
||||||
|
case richerror.RichError:
|
||||||
|
re := err.(richerror.RichError)
|
||||||
|
|
||||||
|
return re.Message(), mapKindToCode(re.Kind())
|
||||||
|
default:
|
||||||
|
return err.Error(), http.StatusBadRequest
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func mapKindToCode(kind richerror.Kind) int {
|
||||||
|
switch kind {
|
||||||
|
case richerror.KindInvalid:
|
||||||
|
return http.StatusUnprocessableEntity
|
||||||
|
default:
|
||||||
|
return http.StatusBadRequest
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,4 +4,5 @@ import "github.com/labstack/echo/v4"
|
||||||
|
|
||||||
func (h Handler) SetRoutes(e *echo.Echo) {
|
func (h Handler) SetRoutes(e *echo.Echo) {
|
||||||
|
|
||||||
|
e.POST("/order/create", h.CreateOrderHandler)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,33 +1,32 @@
|
||||||
package http
|
package http
|
||||||
|
|
||||||
import (
|
import (
|
||||||
httpserver "git.gocasts.ir/ebhomengo/niki/delivery/http_server"
|
|
||||||
"git.gocasts.ir/ebhomengo/niki/purchaseapp/delivery/http/invoice"
|
|
||||||
"git.gocasts.ir/ebhomengo/niki/purchaseapp/delivery/http/order"
|
"git.gocasts.ir/ebhomengo/niki/purchaseapp/delivery/http/order"
|
||||||
|
orderService "git.gocasts.ir/ebhomengo/niki/purchaseapp/service/order"
|
||||||
|
"github.com/labstack/echo/v4"
|
||||||
|
"github.com/labstack/echo/v4/middleware"
|
||||||
)
|
)
|
||||||
|
|
||||||
type Server struct {
|
type Server struct {
|
||||||
HTTPServer *httpserver.Server
|
OrderHandler *order.Handler
|
||||||
OrderHandler *order.Handler
|
|
||||||
InvoiceHandler *invoice.Handler
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(httpserver *httpserver.Server) *Server {
|
func New(orderSvc orderService.Service) *Server {
|
||||||
return &Server{
|
return &Server{
|
||||||
HTTPServer: httpserver,
|
OrderHandler: order.New(orderSvc),
|
||||||
OrderHandler: order.New(),
|
|
||||||
InvoiceHandler: invoice.New(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) Serve() {
|
func (s *Server) Serve() {
|
||||||
s.RegisterRoutes()
|
e := echo.New()
|
||||||
|
e.Use(middleware.RequestLogger())
|
||||||
|
e.GET("/purchase/health-check", s.healthCheck)
|
||||||
|
|
||||||
|
s.OrderHandler.SetRoutes(e)
|
||||||
|
|
||||||
|
if err := e.Start(":8088"); err != nil {
|
||||||
|
e.Logger.Error("failed to start server", "error", err)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) Stop() {}
|
func (s *Server) Stop() {}
|
||||||
|
|
||||||
func (s *Server) RegisterRoutes() {
|
|
||||||
s.HTTPServer.Router.GET("/purchase/health-check", s.healthCheck)
|
|
||||||
s.OrderHandler.SetRoutes(s.HTTPServer.Router)
|
|
||||||
s.InvoiceHandler.SetRoutes(s.HTTPServer.Router)
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
package entity
|
|
||||||
|
|
||||||
type Invoice struct {
|
|
||||||
}
|
|
||||||
|
|
@ -1,4 +1,59 @@
|
||||||
package entity
|
package entity
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.gocasts.ir/ebhomengo/niki/types"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
type Order struct {
|
type Order struct {
|
||||||
|
ID types.ID
|
||||||
|
UserID types.ID
|
||||||
|
TotalAmount types.Price
|
||||||
|
TotalDiscount types.Price
|
||||||
|
ShippingID types.ID
|
||||||
|
PaymentMethod PaymentMethod
|
||||||
|
ProcessStatus ProcessStatus
|
||||||
|
PaymentStatus PaymentStatus
|
||||||
|
Address string
|
||||||
|
CreatedAt time.Time
|
||||||
|
UpdatedAt time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type OrderItem struct {
|
||||||
|
ID types.ID
|
||||||
|
ProductID types.ID
|
||||||
|
Price types.Price
|
||||||
|
Quantity types.Count
|
||||||
|
PriceWithDiscount types.Price
|
||||||
|
OrderID types.ID
|
||||||
|
CreatedAt time.Time
|
||||||
|
}
|
||||||
|
|
||||||
|
type PaymentMethod string
|
||||||
|
|
||||||
|
const (
|
||||||
|
Online PaymentMethod = "online"
|
||||||
|
Wallet = "wallet"
|
||||||
|
Cart = "cart"
|
||||||
|
)
|
||||||
|
|
||||||
|
type ProcessStatus string
|
||||||
|
|
||||||
|
const (
|
||||||
|
WaitingToPay ProcessStatus = "waiting-to-pay"
|
||||||
|
processing = "processing"
|
||||||
|
accepted = "accepted"
|
||||||
|
preparing = "preparing"
|
||||||
|
prepared = "prepared"
|
||||||
|
givenToPost = "given-to-post"
|
||||||
|
delivered = "delivered"
|
||||||
|
cancelled = "cancelled"
|
||||||
|
)
|
||||||
|
|
||||||
|
type PaymentStatus string
|
||||||
|
|
||||||
|
const (
|
||||||
|
Paid PaymentStatus = "paid"
|
||||||
|
UnPaid = "unpaid"
|
||||||
|
Cancelled = "cancelled"
|
||||||
|
)
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
-- +migrate Up
|
||||||
|
-- please read this article to understand why we use VARCHAR(191)
|
||||||
|
-- https://www.grouparoo.com/blog/varchar-191#why-varchar-and-not-text
|
||||||
|
CREATE TABLE `orders` (
|
||||||
|
`id` INT PRIMARY KEY AUTO_INCREMENT,
|
||||||
|
`user_id` INT NOT NULL,
|
||||||
|
`address` TEXT,
|
||||||
|
`shipping_id` INT NOT NULL,
|
||||||
|
`payment_method` ENUM('online', 'wallet', 'cart') DEFAULT 'online',
|
||||||
|
`payment_status` ENUM('unpaid', 'paid', 'cancelled') DEFAULT 'unpaid',
|
||||||
|
`process_status` ENUM('waiting-to-pay', 'processing', 'accepted', 'preparing', 'prepared', 'given-to-post', 'delivered', 'cancelled') DEFAULT 'waiting-to-pay',
|
||||||
|
`total_amount` INT NOT NULL,
|
||||||
|
`total_discount` INT NULL,
|
||||||
|
|
||||||
|
`created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
`updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
|
||||||
|
-- FOREIGN KEY (`user_id`) REFERENCES `users`(`id`)
|
||||||
|
-- FOREIGN KEY (`shipping_id`) REFERENCES `shippings`(`id`)
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
-- +migrate Down
|
||||||
|
DROP TABLE `orders`;
|
||||||
|
|
@ -0,0 +1,19 @@
|
||||||
|
-- +migrate Up
|
||||||
|
-- please read this article to understand why we use VARCHAR(191)
|
||||||
|
-- https://www.grouparoo.com/blog/varchar-191#why-varchar-and-not-text
|
||||||
|
CREATE TABLE `order_items` (
|
||||||
|
`id` INT PRIMARY KEY AUTO_INCREMENT,
|
||||||
|
`order_id` INT NOT NULL,
|
||||||
|
`product_id` INT NOT NULL,
|
||||||
|
`quantity` INT DEFAULT 1,
|
||||||
|
`price` INT NOT NULL,
|
||||||
|
`price_with_discount` INT NULL,
|
||||||
|
`created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
`updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||||
|
|
||||||
|
FOREIGN KEY (`order_id`) REFERENCES `orders`(`id`)
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
-- +migrate Down
|
||||||
|
DROP TABLE `order_items`;
|
||||||
|
|
@ -0,0 +1,69 @@
|
||||||
|
package mysql
|
||||||
|
|
||||||
|
import (
|
||||||
|
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
|
||||||
|
"git.gocasts.ir/ebhomengo/niki/purchaseapp/entity"
|
||||||
|
"git.gocasts.ir/ebhomengo/niki/repository/mysql"
|
||||||
|
"git.gocasts.ir/ebhomengo/niki/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
type DB struct {
|
||||||
|
conn *mysql.DB
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(db *mysql.DB) *DB {
|
||||||
|
return &DB{conn: db}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DB) CreateOrder(order entity.Order, orderItems []entity.OrderItem) (types.ID, error) {
|
||||||
|
|
||||||
|
const Op = "repository.mysql.order.createorder"
|
||||||
|
tx, err := d.conn.Conn().Begin()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return 0, richerror.New(Op).WithErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
defer tx.Rollback()
|
||||||
|
|
||||||
|
query := "insert into orders(user_id, address, shipping_id," +
|
||||||
|
" payment_method, payment_status, process_status," +
|
||||||
|
" total_amount, total_discount) values (?, ?, ?, ?, ?, ?, ?, ?);"
|
||||||
|
res, oErr := tx.Exec(query, order.UserID, order.Address, order.ShippingID,
|
||||||
|
order.PaymentMethod, order.PaymentStatus, order.ProcessStatus,
|
||||||
|
order.TotalAmount, order.TotalDiscount)
|
||||||
|
|
||||||
|
if oErr != nil {
|
||||||
|
return 0, richerror.New(Op).WithErr(oErr)
|
||||||
|
}
|
||||||
|
orderID, insertIDErr := res.LastInsertId()
|
||||||
|
if insertIDErr != nil {
|
||||||
|
return 0, richerror.New(Op).WithErr(insertIDErr)
|
||||||
|
}
|
||||||
|
|
||||||
|
orderItemQuery := "insert into order_items(order_id, product_id, quantity, price, price_with_discount) values(?, ?, ?, ?, ?);"
|
||||||
|
for _, item := range orderItems {
|
||||||
|
_, iErr := tx.Exec(orderItemQuery, orderID, item.ProductID, item.Quantity, item.Price, item.PriceWithDiscount)
|
||||||
|
if iErr != nil {
|
||||||
|
return 0, richerror.New(Op).WithErr(iErr)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := tx.Commit(); err != nil {
|
||||||
|
return 0, richerror.New(Op).WithErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return types.ID(orderID), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (d *DB) UpdateOrderProcessStatus(orderID types.ID, status string) (bool, error) {
|
||||||
|
const Op = "repository.mysql.order.update-order-process-status"
|
||||||
|
_, err := d.conn.Conn().Exec("update orders set process_status=? where id=?;", status, orderID)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return false, richerror.New(Op).WithErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return true, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
package invoice
|
|
||||||
|
|
@ -1,4 +0,0 @@
|
||||||
package invoice
|
|
||||||
|
|
||||||
type Service struct {
|
|
||||||
}
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
package invoice
|
|
||||||
|
|
@ -1 +1,20 @@
|
||||||
package order
|
package order
|
||||||
|
|
||||||
|
import (
|
||||||
|
"git.gocasts.ir/ebhomengo/niki/purchaseapp/entity"
|
||||||
|
"git.gocasts.ir/ebhomengo/niki/types"
|
||||||
|
)
|
||||||
|
|
||||||
|
type CreateOrderRequest struct {
|
||||||
|
UserID types.ID `json:"user_id"`
|
||||||
|
Address string `json:"address"`
|
||||||
|
ShippingID types.ID `json:"shipping_id"`
|
||||||
|
PaymentMethod entity.PaymentMethod `json:"payment_method"`
|
||||||
|
TotalAmount types.Price `json:"total_amount"`
|
||||||
|
TotalDiscount types.Price `json:"total_discount"`
|
||||||
|
OrderItems []entity.OrderItem `json:"order_items"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type CreateOrderResponse struct {
|
||||||
|
OrderID types.ID
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,42 @@
|
||||||
package order
|
package order
|
||||||
|
|
||||||
|
import (
|
||||||
|
richerror "git.gocasts.ir/ebhomengo/niki/pkg/rich_error"
|
||||||
|
"git.gocasts.ir/ebhomengo/niki/purchaseapp/entity"
|
||||||
|
"git.gocasts.ir/ebhomengo/niki/types"
|
||||||
|
)
|
||||||
|
|
||||||
type Service struct {
|
type Service struct {
|
||||||
|
repo Repo
|
||||||
|
}
|
||||||
|
|
||||||
|
type Repo interface {
|
||||||
|
CreateOrder(order entity.Order, orderItems []entity.OrderItem) (types.ID, error)
|
||||||
|
UpdateOrderProcessStatus(orderID types.ID, status string) (bool, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
func New(orderRepo Repo) Service {
|
||||||
|
return Service{repo: orderRepo}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s Service) CreateOrder(order entity.Order, orderItems []entity.OrderItem) (CreateOrderResponse, error) {
|
||||||
|
const Op = "purchaseapp.service.CreateOrder"
|
||||||
|
orderID, err := s.repo.CreateOrder(order, orderItems)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return CreateOrderResponse{}, richerror.New(Op).WithErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return CreateOrderResponse{OrderID: orderID}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s Service) UpdateOrderProcessStatus(orderID types.ID, status string) (bool, error) {
|
||||||
|
|
||||||
|
const Op = "purchaseapp.service.UpdateOrderProcessStatus"
|
||||||
|
_, err := s.repo.UpdateOrderProcessStatus(orderID, status)
|
||||||
|
if err != nil {
|
||||||
|
return false, richerror.New(Op).WithErr(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
_ "github.com/go-sql-driver/mysql"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
package types
|
||||||
|
|
||||||
|
type Count uint32
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
package types
|
||||||
|
|
||||||
|
type ID uint64
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
package types
|
||||||
|
|
||||||
|
type Price uint64
|
||||||
Loading…
Reference in New Issue