2023-10-08 15:59:42 +07:00
package orders
import (
"context"
"furtuna-be/internal/common/logger"
"furtuna-be/internal/entity"
2024-07-26 11:37:22 +07:00
"strings"
2023-10-08 15:59:42 +07:00
"go.uber.org/zap"
"gorm.io/gorm"
)
type OrderRepository struct {
db * gorm . DB
}
func NewOrderRepository ( db * gorm . DB ) * OrderRepository {
return & OrderRepository {
db : db ,
}
}
2024-06-04 02:59:31 +07:00
func ( r * OrderRepository ) Create ( ctx context . Context , order * entity . Order ) ( * entity . Order , error ) {
err := r . db . WithContext ( ctx ) . Create ( order ) . Error
if err != nil {
logger . ContextLogger ( ctx ) . Error ( "error when creating order" , zap . Error ( err ) )
2023-10-08 15:59:42 +07:00
return nil , err
}
2024-06-05 00:24:53 +07:00
return r . FindByID ( ctx , order . ID )
2023-10-08 15:59:42 +07:00
}
2024-06-04 02:59:31 +07:00
func ( r * OrderRepository ) UpdateStatus ( ctx context . Context , orderID int64 , status string ) ( * entity . Order , error ) {
order := new ( entity . Order )
if err := r . db . WithContext ( ctx ) . First ( order , orderID ) . Error ; err != nil {
logger . ContextLogger ( ctx ) . Error ( "error when finding order" , zap . Error ( err ) )
2023-10-08 15:59:42 +07:00
return nil , err
}
2024-06-04 02:59:31 +07:00
order . Status = status
if err := r . db . WithContext ( ctx ) . Save ( order ) . Error ; err != nil {
logger . ContextLogger ( ctx ) . Error ( "error when updating order status" , zap . Error ( err ) )
2023-10-08 15:59:42 +07:00
return nil , err
}
2024-06-04 02:59:31 +07:00
return order , nil
2023-10-08 15:59:42 +07:00
}
2024-06-04 02:59:31 +07:00
func ( r * OrderRepository ) FindByID ( ctx context . Context , id int64 ) ( * entity . Order , error ) {
var order entity . Order
2024-06-05 00:24:53 +07:00
err := r . db . WithContext ( ctx ) . Preload ( "OrderItems" , func ( db * gorm . DB ) * gorm . DB {
return db . Preload ( "Product" )
} ) . First ( & order , id ) . Error
if err != nil {
2024-06-04 02:59:31 +07:00
logger . ContextLogger ( ctx ) . Error ( "error when finding order by ID" , zap . Error ( err ) )
return nil , err
2023-10-08 15:59:42 +07:00
}
2024-06-05 00:24:53 +07:00
2024-06-04 02:59:31 +07:00
return & order , nil
2023-10-08 15:59:42 +07:00
}
2024-06-05 00:24:53 +07:00
func ( r * OrderRepository ) SetOrderStatus ( ctx context . Context , db * gorm . DB , orderID int64 , status string ) error {
var order entity . Order
if err := db . WithContext ( ctx ) . Preload ( "OrderItems" ) . First ( & order , orderID ) . Error ; err != nil {
logger . ContextLogger ( ctx ) . Error ( "error when finding order by ID" , zap . Error ( err ) )
return err
}
order . Status = status
if err := db . WithContext ( ctx ) . Save ( & order ) . Error ; err != nil {
logger . ContextLogger ( ctx ) . Error ( "error when updating order status" , zap . Error ( err ) )
return err
}
return nil
}
2024-06-04 02:59:31 +07:00
func ( r * OrderRepository ) Update ( ctx context . Context , order * entity . Order ) ( * entity . Order , error ) {
if err := r . db . WithContext ( ctx ) . Save ( order ) . Error ; err != nil {
logger . ContextLogger ( ctx ) . Error ( "error when updating order" , zap . Error ( err ) )
2023-10-08 15:59:42 +07:00
return nil , err
}
2024-06-04 02:59:31 +07:00
return order , nil
2023-10-08 15:59:42 +07:00
}
2024-07-26 11:37:22 +07:00
2024-07-26 22:32:24 +07:00
func ( b * OrderRepository ) GetAllHystoryOrders ( ctx context . Context , req entity . HistoryOrderSearch ) ( entity . HistoryOrderList , int , error ) {
2024-07-26 11:37:22 +07:00
var orders [ ] * entity . HistoryOrderDB
var total int64
query := b . db . Table ( "orders" ) .
Select ( "orders.id as id, users.name as employee, sites.name as site, orders.created_at as timestamp, orders.created_at as booking_time, STRING_AGG(ticket_summary.name || ' x' || ticket_summary.total_qty, ', ') AS tickets, orders.payment_type as payment_type, orders.status as status, orders.amount as amount" ) .
Joins ( "left join (SELECT items.order_id, products.name, SUM(items.qty) AS total_qty FROM order_items items LEFT JOIN products ON items.item_id = products.id GROUP BY items.order_id, products.name) AS ticket_summary ON orders.id = ticket_summary.order_id" ) .
Joins ( "left join users on orders.created_by = users.id" ) .
Joins ( "left join partners on orders.partner_id = partners.id" ) .
2024-07-26 13:39:08 +07:00
Joins ( "left join sites on partners.id = sites.partner_id" )
2024-07-26 22:32:24 +07:00
if ! req . IsAdmin {
query = query . Where ( "orders.partner_id = ?" , req . PartnerID )
2024-07-26 13:39:08 +07:00
}
query = query . Group ( "orders.id, users.name, sites.name, orders.created_at, orders.payment_type, orders.status" )
2024-07-26 11:37:22 +07:00
if err := query . Count ( & total ) . Error ; err != nil {
logger . ContextLogger ( ctx ) . Error ( "error when count history orders" , zap . Error ( err ) )
return nil , 0 , err
}
2024-07-26 22:47:37 +07:00
page := ( req . Offset - 1 ) * req . Limit
2024-07-26 11:37:22 +07:00
if req . Offset > 0 {
2024-07-26 22:47:37 +07:00
query = query . Offset ( page )
2024-07-26 11:37:22 +07:00
}
if req . Limit > 0 {
query = query . Limit ( req . Limit )
}
if err := query . Scan ( & orders ) . Error ; err != nil {
logger . ContextLogger ( ctx ) . Error ( "error when get all history orders" , zap . Error ( err ) )
return nil , 0 , err
}
for i , order := range orders {
if order . RawTickets != "" {
orders [ i ] . Tickets = strings . Split ( order . RawTickets , ", " )
}
}
return orders , int ( total ) , nil
}