add order and payment
This commit is contained in:
@@ -20,6 +20,8 @@ func NewCrypto(config CryptoConfig) *CryptoImpl {
|
||||
|
||||
type CryptoConfig interface {
|
||||
AccessTokenSecret() string
|
||||
AccessTokenOrderSecret() string
|
||||
AccessTokenOrderExpiresDate() time.Time
|
||||
AccessTokenExpiresDate() time.Time
|
||||
}
|
||||
|
||||
@@ -88,3 +90,46 @@ func (c *CryptoImpl) ParseAndValidateJWT(tokenString string) (*entity.JWTAuthCla
|
||||
return nil, errors.ErrorUnauthorized
|
||||
}
|
||||
}
|
||||
|
||||
func (c *CryptoImpl) GenerateJWTOrder(order *entity.Order) (string, error) {
|
||||
claims := &entity.JWTOrderClaims{
|
||||
StandardClaims: jwt.StandardClaims{
|
||||
Subject: strconv.FormatInt(order.ID, 10),
|
||||
ExpiresAt: c.Config.AccessTokenOrderExpiresDate().Unix(),
|
||||
IssuedAt: time.Now().Unix(),
|
||||
NotBefore: time.Now().Unix(),
|
||||
},
|
||||
PartnerID: order.PartnerID,
|
||||
OrderID: order.ID,
|
||||
}
|
||||
|
||||
token, err := jwt.
|
||||
NewWithClaims(jwt.SigningMethodHS256, claims).
|
||||
SignedString([]byte(c.Config.AccessTokenOrderSecret()))
|
||||
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return token, nil
|
||||
}
|
||||
|
||||
func (c *CryptoImpl) ValidateJWTOrder(tokenString string) (int64, int64, error) {
|
||||
token, err := jwt.ParseWithClaims(tokenString, &entity.JWTOrderClaims{}, func(token *jwt.Token) (interface{}, error) {
|
||||
if _, ok := token.Method.(*jwt.SigningMethodHMAC); !ok {
|
||||
return nil, fmt.Errorf("unexpected signing method: %v", token.Header["alg"])
|
||||
}
|
||||
return []byte(c.Config.AccessTokenOrderSecret()), nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return 0, 0, err
|
||||
}
|
||||
|
||||
claims, ok := token.Claims.(*entity.JWTOrderClaims)
|
||||
if !ok || !token.Valid {
|
||||
return 0, 0, fmt.Errorf("invalid token %v", token.Header["alg"])
|
||||
}
|
||||
|
||||
return claims.PartnerID, claims.OrderID, nil
|
||||
}
|
||||
|
||||
@@ -0,0 +1,81 @@
|
||||
package mdtrns
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"furtuna-be/internal/common/logger"
|
||||
"furtuna-be/internal/entity"
|
||||
"log"
|
||||
"strconv"
|
||||
|
||||
"github.com/veritrans/go-midtrans"
|
||||
)
|
||||
|
||||
type MidtransConfig interface {
|
||||
MidtransServerKey() string
|
||||
MidtransClientKey() string
|
||||
MidtranEnvType() int
|
||||
}
|
||||
|
||||
type ClientService struct {
|
||||
client midtrans.Client
|
||||
midtransConfig MidtransConfig
|
||||
}
|
||||
|
||||
func New(midtransConfig MidtransConfig) *ClientService {
|
||||
midclient := midtrans.NewClient()
|
||||
midclient.ServerKey = midtransConfig.MidtransServerKey()
|
||||
midclient.ClientKey = midtransConfig.MidtransClientKey()
|
||||
midclient.APIEnvType = midtrans.EnvironmentType(midtransConfig.MidtranEnvType())
|
||||
|
||||
return &ClientService{
|
||||
client: midclient,
|
||||
midtransConfig: midtransConfig,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *ClientService) CreatePayment(order entity.MidtransRequest) (*entity.MidtransResponse, error) {
|
||||
var snapGateway midtrans.SnapGateway
|
||||
snapGateway = midtrans.SnapGateway{
|
||||
Client: c.client,
|
||||
}
|
||||
|
||||
snapReq := &midtrans.SnapReq{
|
||||
EnabledPayments: []midtrans.PaymentType{
|
||||
midtrans.SourceGopay,
|
||||
},
|
||||
TransactionDetails: midtrans.TransactionDetails{
|
||||
OrderID: order.PaymentReferenceID,
|
||||
GrossAmt: order.TotalAmount,
|
||||
},
|
||||
}
|
||||
|
||||
log.Println("GetToken:")
|
||||
snapTokenResp, err := snapGateway.GetToken(snapReq)
|
||||
|
||||
if err != nil {
|
||||
logger.GetLogger().Error(fmt.Sprintf("error when create midtrans payment %v", err))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &entity.MidtransResponse{
|
||||
Token: snapTokenResp.Token,
|
||||
RedirectURL: snapTokenResp.RedirectURL,
|
||||
}, nil
|
||||
|
||||
}
|
||||
|
||||
func (c ClientService) getProductItems(products []entity.OrderItem) []midtrans.ItemDetail {
|
||||
var items []midtrans.ItemDetail
|
||||
|
||||
for _, product := range products {
|
||||
item := midtrans.ItemDetail{
|
||||
ID: strconv.FormatInt(product.ID, 10),
|
||||
Name: product.ItemType,
|
||||
Qty: int32(product.Quantity),
|
||||
Price: int64(product.Price),
|
||||
}
|
||||
items = append(items, item)
|
||||
}
|
||||
|
||||
return items
|
||||
}
|
||||
@@ -2,10 +2,8 @@ package orders
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"furtuna-be/internal/common/logger"
|
||||
"furtuna-be/internal/entity"
|
||||
|
||||
"go.uber.org/zap"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
@@ -20,284 +18,42 @@ func NewOrderRepository(db *gorm.DB) *OrderRepository {
|
||||
}
|
||||
}
|
||||
|
||||
func (o *OrderRepository) CreateOrder(ctx context.Context, order *entity.OrderDB) (*entity.OrderDB, error) {
|
||||
tx := o.db.Begin()
|
||||
|
||||
if err := tx.Select("branch_id", "status", "customer_name", "customer_phone", "pax", "amount", "created_by").Create(order).Error; err != nil {
|
||||
tx.Rollback()
|
||||
logError(ctx, "creating order", err)
|
||||
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))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for i, orditem := range order.OrderItem {
|
||||
orderItem := orditem.ToOrderItemDB()
|
||||
orderItem.OrderID = order.ID
|
||||
|
||||
err := tx.Select("order_id", "item_id", "item_type", "price", "qty", "created_by").Create(orderItem).Error
|
||||
if err != nil {
|
||||
logger.ContextLogger(ctx).Error("error when create order item", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
order.OrderItem[i] = *orderItem.ToOrderItem()
|
||||
}
|
||||
|
||||
//insert transaction
|
||||
transaction := order.Transaction.ToTransactionDB()
|
||||
transaction.OrderID = order.ID
|
||||
|
||||
if err := tx.Select("branch_id", "status", "amount", "order_id", "payment_method", "customer_name", "customer_phone", "created_by").Create(transaction).Error; err != nil {
|
||||
tx.Rollback()
|
||||
logError(ctx, "creating transaction", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := tx.Commit().Error; err != nil {
|
||||
tx.Rollback()
|
||||
logError(ctx, "committing transaction", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return order, nil
|
||||
}
|
||||
|
||||
func (b *OrderRepository) UpdateOrder(ctx context.Context, order *entity.OrderDB) (*entity.OrderDB, error) {
|
||||
|
||||
if err := b.db.Select("status", "updated_at", "updated_by").Save(order).Error; err != nil {
|
||||
logError(ctx, "update order", err)
|
||||
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))
|
||||
return nil, err
|
||||
}
|
||||
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))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return order, nil
|
||||
}
|
||||
|
||||
func (b *OrderRepository) GetAllOrders(ctx context.Context, req entity.OrderSearch) (entity.OrderList, int, error) {
|
||||
var orders []*entity.OrderDB
|
||||
var total int64
|
||||
|
||||
query := b.db.Table("orders").
|
||||
Select("orders.id, orders.branch_id, b.name as branch_name, orders.status, orders.amount, orders.created_at, orders.updated_at, oi.order_item_id, oi.order_id, oi.item_id, oi.item_type, COALESCE(p.name, s.name, '') as item_name, oi.price, oi.qty, oi.created_at, oi.updated_at, COALESCE(t.payment_method, ''), COALESCE(orders.customer_name, ''), COALESCE(orders.customer_phone, ''), COALESCE(orders.pax, 0)").
|
||||
Joins("LEFT JOIN order_items oi ON orders.id = oi.order_id").
|
||||
Joins("LEFT JOIN transactions t ON orders.id = t.order_id").
|
||||
Joins("LEFT JOIN products p ON oi.item_id = p.id AND oi.item_type ='PRODUCT' ").
|
||||
Joins("LEFT JOIN studios s ON oi.item_id = s.id AND oi.item_type ='STUDIO' ").
|
||||
Joins("LEFT JOIN branches b ON orders.branch_id = b.id")
|
||||
|
||||
if req.Search != "" {
|
||||
query = query.Where("b.name ILIKE ? or orders.status ILIKE ? or oi.item_type ILIKE ? or p.name ILIKE ? or orders.customer_name ILIKE ? ", "%"+req.Search+"%", "%"+req.Search+"%", "%"+req.Search+"%", "%"+req.Search+"%", "%"+req.Search+"%")
|
||||
}
|
||||
|
||||
if req.Status != "" {
|
||||
query = query.Where("orders.status = ?", req.Status)
|
||||
}
|
||||
|
||||
if req.BranchID > 0 {
|
||||
query = query.Where("orders.branch_id = ?", req.BranchID)
|
||||
}
|
||||
|
||||
if req.StatusActive.IsActive() {
|
||||
query = query.Joins("INNER JOIN (SELECT o.id, oi.qty, o.created_at FROM orders o INNER JOIN order_items oi ON o.id = oi.order_id AND oi.item_type = 'STUDIO' where o.status != 'CANCEL' and CURRENT_TIMESTAMP > o.created_at AND CURRENT_TIMESTAMP < (o.created_at + (oi.qty || ' hours')::interval)) order_active on order_active.id=orders.id")
|
||||
}
|
||||
|
||||
if req.Limit > 0 {
|
||||
query = query.Limit(req.Limit)
|
||||
}
|
||||
|
||||
if req.Offset > 0 {
|
||||
query = query.Offset(req.Offset)
|
||||
}
|
||||
|
||||
query.Order("orders.created_at DESC")
|
||||
|
||||
rows, err := query.Rows()
|
||||
if err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
defer rows.Close()
|
||||
|
||||
ordersMap := make(map[int64]*entity.OrderDB) // Map to store orders by ID
|
||||
for rows.Next() {
|
||||
var ordr entity.OrderDB
|
||||
var oi entity.OrderItem
|
||||
|
||||
err := rows.Scan(&ordr.ID, &ordr.BranchID, &ordr.BranchName, &ordr.Status, &ordr.Amount, &ordr.CreatedAt, &ordr.UpdatedAt,
|
||||
&oi.OrderItemID, &oi.OrderID, &oi.ItemID, &oi.ItemType, &oi.ItemName, &oi.Price, &oi.Qty, &oi.CreatedAt, &oi.UpdatedAt,
|
||||
&ordr.Transaction.PaymentMethod, &ordr.CustomerName, &ordr.CustomerPhone, &ordr.Pax)
|
||||
if err != nil {
|
||||
logger.ContextLogger(ctx).Error("error scanning rows", zap.Error(err))
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
if order, ok := ordersMap[ordr.ID]; ok {
|
||||
// Order already exists in map, append OrderItem to existing order
|
||||
order.OrderItem = append(order.OrderItem, oi)
|
||||
} else {
|
||||
// Order doesn't exist in map, create a new OrderDB
|
||||
newOrder := ordr
|
||||
newOrder.OrderItem = []entity.OrderItem{oi}
|
||||
ordersMap[ordr.ID] = &newOrder
|
||||
|
||||
orders = append(orders, &ordr)
|
||||
}
|
||||
}
|
||||
|
||||
// assign value order item
|
||||
for _, v := range orders {
|
||||
v.OrderItem = ordersMap[v.ID].OrderItem
|
||||
}
|
||||
|
||||
//reset limit for count total data
|
||||
query = query.Offset(-1).Limit(-1)
|
||||
|
||||
if err := query.Count(&total).Error; err != nil {
|
||||
logger.ContextLogger(ctx).Error("error when count orders", zap.Error(err))
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
return orders, int(total), nil
|
||||
}
|
||||
|
||||
func (b *OrderRepository) GetOrderByID(ctx context.Context, id int64) (*entity.OrderDB, error) {
|
||||
var orders *entity.OrderDB
|
||||
|
||||
query := b.db.Table("orders").
|
||||
Select("orders.id, orders.branch_id, b.name as branch_name, orders.status, orders.amount, orders.created_at, orders.updated_at, oi.order_item_id, oi.order_id, oi.item_id, oi.item_type, COALESCE(p.name, s.name, '') as item_name, oi.price, oi.qty, oi.created_at, oi.updated_at, t.payment_method, orders.customer_name, orders.customer_phone, orders.pax").
|
||||
Joins("LEFT JOIN order_items oi ON orders.id = oi.order_id").
|
||||
Joins("LEFT JOIN transactions t ON orders.id = t.order_id").
|
||||
Joins("LEFT JOIN products p ON oi.item_id = p.id AND oi.item_type ='PRODUCT' ").
|
||||
Joins("LEFT JOIN studios s ON oi.item_id = s.id AND oi.item_type ='STUDIO' ").
|
||||
Joins("LEFT JOIN branches b ON orders.branch_id = b.id").
|
||||
Where("orders.id = ?", id)
|
||||
|
||||
rows, err := query.Rows()
|
||||
if err != nil {
|
||||
func (r *OrderRepository) FindByID(ctx context.Context, id int64) (*entity.Order, error) {
|
||||
var order entity.Order
|
||||
if err := r.db.WithContext(ctx).Preload("OrderItems").First(&order, id).Error; err != nil {
|
||||
logger.ContextLogger(ctx).Error("error when finding order by ID", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
defer rows.Close()
|
||||
|
||||
var ordr entity.OrderDB // Map to store orders by ID
|
||||
for rows.Next() {
|
||||
var oi entity.OrderItem
|
||||
|
||||
err := rows.Scan(&ordr.ID, &ordr.BranchID, &ordr.BranchName, &ordr.Status, &ordr.Amount, &ordr.CreatedAt, &ordr.UpdatedAt,
|
||||
&oi.OrderItemID, &oi.OrderID, &oi.ItemID, &oi.ItemType, &oi.ItemName, &oi.Price, &oi.Qty, &oi.CreatedAt, &oi.UpdatedAt,
|
||||
&ordr.Transaction.PaymentMethod, &ordr.CustomerName, &ordr.CustomerPhone, &ordr.Pax)
|
||||
if err != nil {
|
||||
logger.ContextLogger(ctx).Error("error scanning rows", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ordr.OrderItem = append(ordr.OrderItem, oi)
|
||||
}
|
||||
|
||||
orders = &ordr
|
||||
|
||||
if orders == nil {
|
||||
return nil, fmt.Errorf("order not found")
|
||||
}
|
||||
|
||||
return orders, nil
|
||||
return &order, nil
|
||||
}
|
||||
|
||||
func (b *OrderRepository) GetTotalRevenue(ctx context.Context, req entity.OrderTotalRevenueSearch) (float64, int64, error) {
|
||||
var (
|
||||
totalmonthlyRevenue float64
|
||||
totalmonthlyTrans int64
|
||||
)
|
||||
|
||||
query := b.db.Table("orders").
|
||||
Select("COALESCE(sum(amount),0) as total_amount, COALESCE(count(id),0) as total_transaction").
|
||||
Where("status in ('NEW','PAID') ")
|
||||
|
||||
if req.BranchID > 0 {
|
||||
query = query.Where("branch_id = ?", req.BranchID)
|
||||
}
|
||||
|
||||
if req.Month > 0 {
|
||||
query = query.Where("EXTRACT(MONTH FROM created_at) = ? ", req.Month)
|
||||
}
|
||||
|
||||
if req.Year > 0 {
|
||||
query = query.Where("EXTRACT(YEAR FROM created_at) = ? ", req.Year)
|
||||
}
|
||||
|
||||
if req.DateStart != nil {
|
||||
query = query.Where("created_at >= ? ", req.DateStart)
|
||||
}
|
||||
|
||||
if req.DateEnd != nil {
|
||||
query = query.Where("created_at <= ? ", req.DateEnd)
|
||||
}
|
||||
|
||||
rows, err := query.Rows()
|
||||
if err != nil {
|
||||
return totalmonthlyRevenue, totalmonthlyTrans, err
|
||||
}
|
||||
defer rows.Close()
|
||||
|
||||
for rows.Next() {
|
||||
err := rows.Scan(&totalmonthlyRevenue, &totalmonthlyTrans)
|
||||
if err != nil {
|
||||
logger.ContextLogger(ctx).Error("error scanning rows", zap.Error(err))
|
||||
return totalmonthlyRevenue, totalmonthlyTrans, err
|
||||
}
|
||||
}
|
||||
|
||||
return totalmonthlyRevenue, totalmonthlyTrans, nil
|
||||
}
|
||||
|
||||
func (b *OrderRepository) GetYearlyRevenue(ctx context.Context, year int) (entity.OrderYearlyRevenueList, error) {
|
||||
var result entity.OrderYearlyRevenueList
|
||||
|
||||
err := b.db.Raw(` SELECT
|
||||
oi.item_type,
|
||||
EXTRACT(MONTH FROM o.created_at) AS month_number,
|
||||
SUM(oi.price ) AS total_amount
|
||||
FROM
|
||||
orders o
|
||||
JOIN
|
||||
order_items oi ON o.id = oi.order_id
|
||||
WHERE
|
||||
EXTRACT(YEAR FROM o.created_at) = ?
|
||||
AND o.status IN ('NEW', 'PAID')
|
||||
GROUP BY
|
||||
EXTRACT(MONTH FROM o.created_at),
|
||||
oi.item_type
|
||||
ORDER BY
|
||||
month_number,
|
||||
oi.item_type`, year).Scan(&result).Error
|
||||
|
||||
return result, err
|
||||
}
|
||||
|
||||
func (b *OrderRepository) GetBranchRevenue(ctx context.Context, req entity.OrderBranchRevenueSearch) (entity.OrderBranchRevenueList, error) {
|
||||
var result entity.OrderBranchRevenueList
|
||||
|
||||
query := b.db.Table("orders o").
|
||||
Joins("JOIN branches ON branches.id = o.branch_id").
|
||||
Select("o.branch_id, branches.name, branches.location, SUM(o.amount) as total_amount, COUNT(o.id) as total_trans").
|
||||
Where("o.status IN ('NEW', 'PAID')").
|
||||
Group("o.branch_id, branches.name, branches.location").
|
||||
Order("total_amount DESC, total_trans DESC")
|
||||
|
||||
if req.DateStart != nil {
|
||||
query = query.Where("o.created_at >= ? ", req.DateStart)
|
||||
}
|
||||
|
||||
if req.DateEnd != nil {
|
||||
query = query.Where("o.created_at <= ? ", req.DateEnd)
|
||||
}
|
||||
|
||||
if err := query.Find(&result).Error; err != nil {
|
||||
logger.ContextLogger(ctx).Error("error when GetBranchRevenue", zap.Error(err))
|
||||
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))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func logError(ctx context.Context, s string, err error) {
|
||||
panic("unimplemented")
|
||||
return order, nil
|
||||
}
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
package payment
|
||||
|
||||
import (
|
||||
"context"
|
||||
"furtuna-be/internal/common/logger"
|
||||
"furtuna-be/internal/entity"
|
||||
"github.com/google/uuid"
|
||||
"go.uber.org/zap"
|
||||
"gorm.io/gorm"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type PaymentRepository struct {
|
||||
db *gorm.DB
|
||||
}
|
||||
|
||||
func NewPaymentRepository(db *gorm.DB) *PaymentRepository {
|
||||
return &PaymentRepository{
|
||||
db: db,
|
||||
}
|
||||
}
|
||||
|
||||
func (r *PaymentRepository) Create(ctx context.Context, payment *entity.Payment) (*entity.Payment, error) {
|
||||
payment.ID = uuid.New()
|
||||
if err := r.db.WithContext(ctx).Create(payment).Error; err != nil {
|
||||
logger.ContextLogger(ctx).Error("error when creating payment", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
return payment, nil
|
||||
}
|
||||
|
||||
// Update updates an existing payment record in the database
|
||||
func (r *PaymentRepository) Update(ctx context.Context, payment *entity.Payment) (*entity.Payment, error) {
|
||||
if err := r.db.WithContext(ctx).Save(payment).Error; err != nil {
|
||||
logger.ContextLogger(ctx).Error("error when updating payment", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
return payment, nil
|
||||
}
|
||||
|
||||
// FindByID retrieves a payment record by its ID
|
||||
func (r *PaymentRepository) FindByID(ctx context.Context, id uuid.UUID) (*entity.Payment, error) {
|
||||
payment := new(entity.Payment)
|
||||
if err := r.db.WithContext(ctx).First(payment, id).Error; err != nil {
|
||||
logger.ContextLogger(ctx).Error("error when finding payment by ID", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
return payment, nil
|
||||
}
|
||||
|
||||
func (r *PaymentRepository) FindByOrderAndPartnerID(ctx context.Context, orderID, partnerID int64) (*entity.Payment, error) {
|
||||
payment := new(entity.Payment)
|
||||
orderIDStr := strconv.FormatInt(orderID, 10)
|
||||
partnerIDStr := strconv.FormatInt(partnerID, 10)
|
||||
if err := r.db.WithContext(ctx).
|
||||
Where("order_id = ? AND partner_id = ?", orderIDStr, partnerIDStr).
|
||||
First(payment).Error; err != nil {
|
||||
logger.ContextLogger(ctx).Error("error when finding payment by order ID and partner ID", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
return payment, nil
|
||||
}
|
||||
|
||||
// FindByReferenceID retrieves a payment record by its reference ID
|
||||
func (r *PaymentRepository) FindByReferenceID(ctx context.Context, referenceID string) (*entity.Payment, error) {
|
||||
payment := new(entity.Payment)
|
||||
if err := r.db.WithContext(ctx).Where("reference_id = ?", referenceID).First(payment).Error; err != nil {
|
||||
logger.ContextLogger(ctx).Error("error when finding payment by reference ID", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
return payment, nil
|
||||
}
|
||||
@@ -105,3 +105,12 @@ func (b *ProductRepository) DeleteProduct(ctx context.Context, id int64) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (b *ProductRepository) GetProductsByIDs(ctx context.Context, ids []int64, partnerID int64) ([]*entity.ProductDB, error) {
|
||||
var products []*entity.ProductDB
|
||||
if err := b.db.Where("partner_id = ? AND id IN ?", partnerID, ids).Find(&products).Error; err != nil {
|
||||
logger.ContextLogger(ctx).Error("error when getting products by IDs and partner ID", zap.Error(err))
|
||||
return nil, err
|
||||
}
|
||||
return products, nil
|
||||
}
|
||||
|
||||
@@ -4,9 +4,11 @@ import (
|
||||
"context"
|
||||
"database/sql"
|
||||
"furtuna-be/internal/repository/branches"
|
||||
mdtrns "furtuna-be/internal/repository/midtrans"
|
||||
"furtuna-be/internal/repository/orders"
|
||||
"furtuna-be/internal/repository/oss"
|
||||
"furtuna-be/internal/repository/partners"
|
||||
"furtuna-be/internal/repository/payment"
|
||||
"furtuna-be/internal/repository/products"
|
||||
"furtuna-be/internal/repository/sites"
|
||||
"furtuna-be/internal/repository/studios"
|
||||
@@ -24,36 +26,40 @@ import (
|
||||
)
|
||||
|
||||
type RepoManagerImpl struct {
|
||||
Crypto Crypto
|
||||
Auth Auth
|
||||
Event Event
|
||||
User User
|
||||
Branch Branch
|
||||
Studio Studio
|
||||
Product Product
|
||||
Order Order
|
||||
OSS OSSRepository
|
||||
Partner PartnerRepository
|
||||
Site SiteRepository
|
||||
Trx TransactionManager
|
||||
Wallet WalletRepository
|
||||
Crypto Crypto
|
||||
Auth Auth
|
||||
Event Event
|
||||
User User
|
||||
Branch Branch
|
||||
Studio Studio
|
||||
Product Product
|
||||
Order Order
|
||||
OSS OSSRepository
|
||||
Partner PartnerRepository
|
||||
Site SiteRepository
|
||||
Trx TransactionManager
|
||||
Wallet WalletRepository
|
||||
Midtrans Midtrans
|
||||
Payment Payment
|
||||
}
|
||||
|
||||
func NewRepoManagerImpl(db *gorm.DB, cfg *config.Config) *RepoManagerImpl {
|
||||
return &RepoManagerImpl{
|
||||
Crypto: crypto.NewCrypto(cfg.Auth()),
|
||||
Auth: auth.NewAuthRepository(db),
|
||||
Event: event.NewEventRepo(db),
|
||||
User: users.NewUserRepository(db),
|
||||
Branch: branches.NewBranchRepository(db),
|
||||
Studio: studios.NewStudioRepository(db),
|
||||
Product: products.NewProductRepository(db),
|
||||
Order: orders.NewOrderRepository(db),
|
||||
OSS: oss.NewOssRepositoryImpl(cfg.OSSConfig),
|
||||
Partner: partners.NewPartnerRepository(db),
|
||||
Site: sites.NewSiteRepository(db),
|
||||
Trx: trx.NewGormTransactionManager(db),
|
||||
Wallet: repository.NewWalletRepository(db),
|
||||
Crypto: crypto.NewCrypto(cfg.Auth()),
|
||||
Auth: auth.NewAuthRepository(db),
|
||||
Event: event.NewEventRepo(db),
|
||||
User: users.NewUserRepository(db),
|
||||
Branch: branches.NewBranchRepository(db),
|
||||
Studio: studios.NewStudioRepository(db),
|
||||
Product: products.NewProductRepository(db),
|
||||
Order: orders.NewOrderRepository(db),
|
||||
OSS: oss.NewOssRepositoryImpl(cfg.OSSConfig),
|
||||
Partner: partners.NewPartnerRepository(db),
|
||||
Site: sites.NewSiteRepository(db),
|
||||
Trx: trx.NewGormTransactionManager(db),
|
||||
Wallet: repository.NewWalletRepository(db),
|
||||
Midtrans: mdtrns.New(&cfg.Midtrans),
|
||||
Payment: payment.NewPaymentRepository(db),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -73,6 +79,8 @@ type Crypto interface {
|
||||
CompareHashAndPassword(hash string, password string) bool
|
||||
ValidateWT(tokenString string) (*jwt.Token, error)
|
||||
GenerateJWT(user *entity.User) (string, error)
|
||||
GenerateJWTOrder(order *entity.Order) (string, error)
|
||||
ValidateJWTOrder(tokenString string) (int64, int64, error)
|
||||
ParseAndValidateJWT(token string) (*entity.JWTAuthClaims, error)
|
||||
}
|
||||
|
||||
@@ -106,16 +114,13 @@ type Product interface {
|
||||
GetProductByID(ctx context.Context, id int64) (*entity.ProductDB, error)
|
||||
GetAllProducts(ctx context.Context, req entity.ProductSearch) (entity.ProductList, int, error)
|
||||
DeleteProduct(ctx context.Context, id int64) error
|
||||
GetProductsByIDs(ctx context.Context, ids []int64, partnerID int64) ([]*entity.ProductDB, error)
|
||||
}
|
||||
|
||||
type Order interface {
|
||||
CreateOrder(ctx context.Context, order *entity.OrderDB) (*entity.OrderDB, error)
|
||||
UpdateOrder(ctx context.Context, order *entity.OrderDB) (*entity.OrderDB, error)
|
||||
GetOrderByID(ctx context.Context, id int64) (*entity.OrderDB, error)
|
||||
GetAllOrders(ctx context.Context, req entity.OrderSearch) (entity.OrderList, int, error)
|
||||
GetTotalRevenue(ctx context.Context, req entity.OrderTotalRevenueSearch) (float64, int64, error)
|
||||
GetYearlyRevenue(ctx context.Context, year int) (entity.OrderYearlyRevenueList, error)
|
||||
GetBranchRevenue(ctx context.Context, req entity.OrderBranchRevenueSearch) (entity.OrderBranchRevenueList, error)
|
||||
Create(ctx context.Context, order *entity.Order) (*entity.Order, error)
|
||||
FindByID(ctx context.Context, id int64) (*entity.Order, error)
|
||||
Update(ctx context.Context, order *entity.Order) (*entity.Order, error)
|
||||
}
|
||||
|
||||
type OSSRepository interface {
|
||||
@@ -150,3 +155,13 @@ type TransactionManager interface {
|
||||
type WalletRepository interface {
|
||||
Create(ctx context.Context, tx *gorm.DB, wallet *entity.Wallet) (*entity.Wallet, error)
|
||||
}
|
||||
|
||||
type Midtrans interface {
|
||||
CreatePayment(order entity.MidtransRequest) (*entity.MidtransResponse, error)
|
||||
}
|
||||
|
||||
type Payment interface {
|
||||
Create(ctx context.Context, payment *entity.Payment) (*entity.Payment, error)
|
||||
Update(ctx context.Context, payment *entity.Payment) (*entity.Payment, error)
|
||||
FindByOrderAndPartnerID(ctx context.Context, orderID, partnerID int64) (*entity.Payment, error)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user