Update template email

This commit is contained in:
aditya.siregar
2025-03-08 00:35:23 +07:00
parent 3c80b710af
commit 18003313dd
54 changed files with 2309 additions and 199 deletions
+26 -1
View File
@@ -26,7 +26,31 @@ func (s ServiceImpl) SendEmailTransactional(ctx context.Context, param entity.Se
return err
}
renderedTemplate, err := template.New(param.TemplateName).Parse(string(templateFile))
tmpl := template.New(param.TemplateName).Funcs(template.FuncMap{
"range": func(args ...interface{}) []interface{} {
if len(args) == 0 {
return nil
}
switch items := args[0].(type) {
case []map[string]string:
result := make([]interface{}, len(items))
for i, item := range items {
result[i] = item
}
return result
case []interface{}:
return items
default:
if slice, ok := args[0].([]interface{}); ok {
return slice
}
return nil
}
},
})
renderedTemplate, err := tmpl.Parse(string(templateFile))
if err != nil {
log.Println(err)
return err
@@ -45,6 +69,7 @@ func (s ServiceImpl) sendEmail(ctx context.Context, tmpl *template.Template, par
payload := brevo.SendSmtpEmail{
Sender: &brevo.SendSmtpEmailSender{
Name: "Enaklo",
Email: param.Sender,
},
To: []brevo.SendSmtpEmailTo{
+43
View File
@@ -149,6 +149,49 @@ func (c *CryptoImpl) GenerateJWTOrder(order *entity.Order) (string, error) {
return token, nil
}
func (c *CryptoImpl) GenerateJWTOrderInquiry(inquiry *entity.OrderInquiry) (string, error) {
claims := &entity.JWTOrderClaims{
StandardClaims: jwt.StandardClaims{
Subject: inquiry.ID,
ExpiresAt: c.Config.AccessTokenOrderExpiresDate().Unix(),
IssuedAt: time.Now().Unix(),
NotBefore: time.Now().Unix(),
},
PartnerID: inquiry.PartnerID,
InquiryID: inquiry.ID,
}
token, err := jwt.
NewWithClaims(jwt.SigningMethodHS256, claims).
SignedString([]byte(c.Config.AccessTokenOrderSecret()))
if err != nil {
return "", err
}
return token, nil
}
func (c *CryptoImpl) ValidateJWTOrderInquiry(tokenString string) (int64, string, 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, "", err
}
claims, ok := token.Claims.(*entity.JWTOrderClaims)
if !ok || !token.Valid {
return 0, "", fmt.Errorf("invalid token %v", token.Header["alg"])
}
return claims.PartnerID, claims.InquiryID, 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 {
+128
View File
@@ -0,0 +1,128 @@
package repository
import (
"enaklo-pos-be/internal/common/mycontext"
"enaklo-pos-be/internal/entity"
"enaklo-pos-be/internal/repository/models"
"github.com/pkg/errors"
"gorm.io/gorm"
"time"
)
type CustomerRepo interface {
Create(ctx mycontext.Context, customer *entity.Customer) (*entity.Customer, error)
FindByID(ctx mycontext.Context, id int64) (*entity.Customer, error)
FindByPhone(ctx mycontext.Context, phone string) (*entity.Customer, error)
FindByEmail(ctx mycontext.Context, email string) (*entity.Customer, error)
AddPoints(ctx mycontext.Context, id int64, points int) error
}
type customerRepository struct {
db *gorm.DB
}
func NewCustomerRepository(db *gorm.DB) *customerRepository {
return &customerRepository{db: db}
}
func (r *customerRepository) Create(ctx mycontext.Context, customer *entity.Customer) (*entity.Customer, error) {
customerDB := r.toCustomerDBModel(customer)
if err := r.db.Create(&customerDB).Error; err != nil {
return nil, errors.Wrap(err, "failed to insert customer")
}
customer.ID = customerDB.ID
return customer, nil
}
func (r *customerRepository) FindByID(ctx mycontext.Context, id int64) (*entity.Customer, error) {
var customerDB models.CustomerDB
if err := r.db.First(&customerDB, id).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, errors.New("customer not found")
}
return nil, errors.Wrap(err, "failed to find customer")
}
customer := r.toDomainCustomerModel(&customerDB)
return customer, nil
}
func (r *customerRepository) FindByPhone(ctx mycontext.Context, phone string) (*entity.Customer, error) {
var customerDB models.CustomerDB
if err := r.db.Where("phone = ?", phone).First(&customerDB).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, errors.New("customer not found")
}
return nil, errors.Wrap(err, "failed to find customer by phone")
}
customer := r.toDomainCustomerModel(&customerDB)
return customer, nil
}
func (r *customerRepository) FindByEmail(ctx mycontext.Context, email string) (*entity.Customer, error) {
var customerDB models.CustomerDB
if err := r.db.Where("email = ?", email).First(&customerDB).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, errors.New("customer not found")
}
return nil, errors.Wrap(err, "failed to find customer by email")
}
customer := r.toDomainCustomerModel(&customerDB)
return customer, nil
}
func (r *customerRepository) AddPoints(ctx mycontext.Context, id int64, points int) error {
now := time.Now()
result := r.db.Model(&models.CustomerDB{}).
Where("id = ?", id).
Updates(map[string]interface{}{
"points": gorm.Expr("points + ?", points),
"updated_at": now,
})
if result.Error != nil {
return errors.Wrap(result.Error, "failed to add points to customer")
}
if result.RowsAffected == 0 {
return errors.New("customer not found")
}
return nil
}
func (r *customerRepository) toCustomerDBModel(customer *entity.Customer) models.CustomerDB {
return models.CustomerDB{
ID: customer.ID,
Name: customer.Name,
Email: customer.Email,
Phone: customer.Phone,
Points: customer.Points,
CreatedAt: customer.CreatedAt,
UpdatedAt: customer.UpdatedAt,
}
}
func (r *customerRepository) toDomainCustomerModel(dbModel *models.CustomerDB) *entity.Customer {
return &entity.Customer{
ID: dbModel.ID,
Name: dbModel.Name,
Email: dbModel.Email,
Phone: dbModel.Phone,
Points: dbModel.Points,
CreatedAt: dbModel.CreatedAt,
UpdatedAt: dbModel.UpdatedAt,
}
}
+19
View File
@@ -0,0 +1,19 @@
package models
import (
"time"
)
type CustomerDB struct {
ID int64 `gorm:"primaryKey;column:id"`
Name string `gorm:"column:name"`
Email string `gorm:"column:email"`
Phone string `gorm:"column:phone"`
Points int `gorm:"column:points"`
CreatedAt time.Time `gorm:"column:created_at"`
UpdatedAt time.Time `gorm:"column:updated_at"`
}
func (CustomerDB) TableName() string {
return "customers"
}
+80
View File
@@ -0,0 +1,80 @@
package models
import (
"time"
)
type OrderDB struct {
ID int64 `gorm:"primaryKey;column:id"`
PartnerID int64 `gorm:"column:partner_id"`
CustomerID *int64 `gorm:"column:customer_id"`
InquiryID *string `gorm:"column:inquiry_id"`
Status string `gorm:"column:status"`
Amount float64 `gorm:"column:amount"`
Fee float64 `gorm:"column:fee"`
Total float64 `gorm:"column:total"`
PaymentType string `gorm:"column:payment_type"`
Source string `gorm:"column:source"`
CreatedBy int64 `gorm:"column:created_by"`
CreatedAt time.Time `gorm:"column:created_at"`
UpdatedAt time.Time `gorm:"column:updated_at"`
OrderItems []OrderItemDB `gorm:"foreignKey:OrderID"`
}
func (OrderDB) TableName() string {
return "orders"
}
type OrderItemDB struct {
ID int64 `gorm:"primaryKey;column:order_item_id"`
OrderID int64 `gorm:"column:order_id"`
ItemID int64 `gorm:"column:item_id"`
ItemType string `gorm:"column:item_type"`
Price float64 `gorm:"column:price"`
Quantity int `gorm:"column:quantity"`
CreatedBy int64 `gorm:"column:created_by"`
CreatedAt time.Time `gorm:"column:created_at"`
}
func (OrderItemDB) TableName() string {
return "order_items"
}
type OrderInquiryDB struct {
ID string `gorm:"primaryKey;column:id"`
PartnerID int64 `gorm:"column:partner_id"`
CustomerID *int64 `gorm:"column:customer_id"`
CustomerName string `gorm:"column:customer_name"`
CustomerEmail string `gorm:"column:customer_email"`
CustomerPhoneNumber string `gorm:"column:customer_phone_number"`
Status string `gorm:"column:status"`
Amount float64 `gorm:"column:amount"`
Fee float64 `gorm:"column:fee"`
Total float64 `gorm:"column:total"`
PaymentType string `gorm:"column:payment_type"`
Source string `gorm:"column:source"`
CreatedBy int64 `gorm:"column:created_by"`
CreatedAt time.Time `gorm:"column:created_at"`
UpdatedAt time.Time `gorm:"column:updated_at"`
ExpiresAt time.Time `gorm:"column:expires_at"`
InquiryItems []InquiryItemDB `gorm:"foreignKey:InquiryID"`
}
func (OrderInquiryDB) TableName() string {
return "order_inquiries"
}
type InquiryItemDB struct {
ID int64 `gorm:"primaryKey;column:id"`
InquiryID string `gorm:"column:inquiry_id"`
ItemID int64 `gorm:"column:item_id"`
ItemType string `gorm:"column:item_type"`
Price float64 `gorm:"column:price"`
Quantity int `gorm:"column:quantity"`
CreatedBy int64 `gorm:"column:created_by"`
CreatedAt time.Time `gorm:"column:created_at"`
}
func (InquiryItemDB) TableName() string {
return "inquiry_items"
}
+22
View File
@@ -0,0 +1,22 @@
package models
import (
"time"
)
type ProductDB struct {
ID int64 `gorm:"primaryKey;column:id"`
SiteID int64 `gorm:"column:site_id"`
PartnerID int64 `gorm:"column:partner_id"`
Name string `gorm:"column:name"`
Description string `gorm:"column:description"`
Price float64 `gorm:"column:price"`
Type string `gorm:"column:type"`
Status string `gorm:"column:status"`
CreatedAt time.Time `gorm:"column:created_at"`
UpdatedAt time.Time `gorm:"column:updated_at"`
}
func (ProductDB) TableName() string {
return "products"
}
+21
View File
@@ -0,0 +1,21 @@
package models
import (
"time"
)
type TransactionDB struct {
ID string `gorm:"primaryKey;column:id"`
OrderID int64 `gorm:"column:order_id"`
Amount float64 `gorm:"column:amount"`
PaymentMethod string `gorm:"column:payment_method"`
Status string `gorm:"column:status"`
CreatedAt time.Time `gorm:"column:created_at"`
UpdatedAt time.Time `gorm:"column:updated_at"`
PartnerID int64 `gorm:"column:partner_id"`
TransactionType string `gorm:"column:transaction_type"`
}
func (TransactionDB) TableName() string {
return "transactions"
}
+292
View File
@@ -0,0 +1,292 @@
package repository
import (
"enaklo-pos-be/internal/common/logger"
"enaklo-pos-be/internal/common/mycontext"
"enaklo-pos-be/internal/entity"
"enaklo-pos-be/internal/repository/models"
"github.com/pkg/errors"
"go.uber.org/zap"
"gorm.io/gorm"
"time"
)
type OrderRepository interface {
Create(ctx mycontext.Context, order *entity.Order) (*entity.Order, error)
FindByID(ctx mycontext.Context, id int64) (*entity.Order, error)
CreateInquiry(ctx mycontext.Context, inquiry *entity.OrderInquiry) (*entity.OrderInquiry, error)
FindInquiryByID(ctx mycontext.Context, id string) (*entity.OrderInquiry, error)
UpdateInquiryStatus(ctx mycontext.Context, id string, status string) error
}
type orderRepository struct {
db *gorm.DB
}
func NeworderRepository(db *gorm.DB) *orderRepository {
return &orderRepository{db: db}
}
func (r *orderRepository) Create(ctx mycontext.Context, order *entity.Order) (*entity.Order, error) {
orderDB := r.toOrderDBModel(order)
tx := r.db.Begin()
if tx.Error != nil {
return nil, errors.Wrap(tx.Error, "failed to begin transaction")
}
defer func() {
if r := recover(); r != nil {
tx.Rollback()
}
}()
if err := tx.Create(&orderDB).Error; err != nil {
tx.Rollback()
return nil, errors.Wrap(err, "failed to insert order")
}
order.ID = orderDB.ID
for i := range order.OrderItems {
item := &order.OrderItems[i]
item.OrderID = orderDB.ID
itemDB := r.toOrderItemDBModel(item)
if err := tx.Create(&itemDB).Error; err != nil {
tx.Rollback()
return nil, errors.Wrap(err, "failed to insert order item")
}
item.ID = itemDB.ID
}
if err := tx.Commit().Error; err != nil {
return nil, errors.Wrap(err, "failed to commit transaction")
}
return order, nil
}
func (r *orderRepository) FindByID(ctx mycontext.Context, id int64) (*entity.Order, error) {
var orderDB models.OrderDB
if err := r.db.Preload("OrderItems").First(&orderDB, id).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, errors.New("order not found")
}
return nil, errors.Wrap(err, "failed to find order")
}
order := r.toDomainOrderModel(&orderDB)
for _, itemDB := range orderDB.OrderItems {
item := r.toDomainOrderItemModel(&itemDB)
order.OrderItems = append(order.OrderItems, *item)
}
return order, nil
}
func (r *orderRepository) CreateInquiry(ctx mycontext.Context, inquiry *entity.OrderInquiry) (*entity.OrderInquiry, error) {
inquiryDB := r.toOrderInquiryDBModel(inquiry)
inquiryItems := make([]models.InquiryItemDB, 0, len(inquiry.OrderItems))
for _, item := range inquiry.OrderItems {
inquiryItems = append(inquiryItems, models.InquiryItemDB{
InquiryID: inquiryDB.ID,
ItemID: item.ItemID,
ItemType: item.ItemType,
Price: item.Price,
Quantity: item.Quantity,
CreatedBy: item.CreatedBy,
CreatedAt: time.Now(),
})
}
tx := r.db.Begin()
if tx.Error != nil {
return nil, errors.Wrap(tx.Error, "failed to begin transaction")
}
defer func() {
if r := recover(); r != nil {
tx.Rollback()
}
}()
if err := tx.Create(&inquiryDB).Error; err != nil {
tx.Rollback()
return nil, errors.Wrap(err, "failed to insert order inquiry")
}
if len(inquiryItems) > 0 {
if err := tx.CreateInBatches(inquiryItems, 100).Error; err != nil {
tx.Rollback()
return nil, errors.Wrap(err, "failed to insert inquiry items")
}
}
if err := tx.Commit().Error; err != nil {
return nil, errors.Wrap(err, "failed to commit transaction")
}
return inquiry, nil
}
func (r *orderRepository) FindInquiryByID(ctx mycontext.Context, id string) (*entity.OrderInquiry, error) {
var inquiryDB models.OrderInquiryDB
if err := r.db.Preload("InquiryItems").First(&inquiryDB, "id = ?", id).Error; err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, errors.New("inquiry not found")
}
return nil, errors.Wrap(err, "failed to find inquiry")
}
inquiry := r.toDomainOrderInquiryModel(&inquiryDB)
orderItems := make([]entity.OrderItem, 0, len(inquiryDB.InquiryItems))
for _, itemDB := range inquiryDB.InquiryItems {
orderItems = append(orderItems, entity.OrderItem{
ItemID: itemDB.ItemID,
ItemType: itemDB.ItemType,
Price: itemDB.Price,
Quantity: itemDB.Quantity,
CreatedBy: itemDB.CreatedBy,
CreatedAt: itemDB.CreatedAt,
})
}
inquiry.OrderItems = orderItems
return inquiry, nil
}
func (r *orderRepository) UpdateInquiryStatus(ctx mycontext.Context, id string, status string) error {
now := time.Now()
result := r.db.Model(&models.OrderInquiryDB{}).
Where("id = ?", id).
Updates(map[string]interface{}{
"status": status,
"updated_at": now,
})
if result.Error != nil {
return errors.Wrap(result.Error, "failed to update inquiry status")
}
if result.RowsAffected == 0 {
logger.ContextLogger(ctx).Warn("no inquiry updated", zap.String("id", id))
}
return nil
}
func (r *orderRepository) toOrderDBModel(order *entity.Order) models.OrderDB {
return models.OrderDB{
ID: order.ID,
PartnerID: order.PartnerID,
CustomerID: order.CustomerID,
InquiryID: order.InquiryID,
Status: order.Status,
Amount: order.Amount,
Fee: order.Fee,
Total: order.Total,
PaymentType: order.PaymentType,
Source: order.Source,
CreatedBy: order.CreatedBy,
CreatedAt: order.CreatedAt,
UpdatedAt: order.UpdatedAt,
}
}
func (r *orderRepository) toDomainOrderModel(dbModel *models.OrderDB) *entity.Order {
return &entity.Order{
ID: dbModel.ID,
PartnerID: dbModel.PartnerID,
CustomerID: dbModel.CustomerID,
InquiryID: dbModel.InquiryID,
Status: dbModel.Status,
Amount: dbModel.Amount,
Fee: dbModel.Fee,
Total: dbModel.Total,
PaymentType: dbModel.PaymentType,
Source: dbModel.Source,
CreatedBy: dbModel.CreatedBy,
CreatedAt: dbModel.CreatedAt,
UpdatedAt: dbModel.UpdatedAt,
OrderItems: []entity.OrderItem{},
}
}
func (r *orderRepository) toOrderItemDBModel(item *entity.OrderItem) models.OrderItemDB {
return models.OrderItemDB{
ID: item.ID,
OrderID: item.OrderID,
ItemID: item.ItemID,
ItemType: item.ItemType,
Price: item.Price,
Quantity: item.Quantity,
CreatedBy: item.CreatedBy,
CreatedAt: item.CreatedAt,
}
}
func (r *orderRepository) toDomainOrderItemModel(dbModel *models.OrderItemDB) *entity.OrderItem {
return &entity.OrderItem{
ID: dbModel.ID,
OrderID: dbModel.OrderID,
ItemID: dbModel.ItemID,
ItemType: dbModel.ItemType,
Price: dbModel.Price,
Quantity: dbModel.Quantity,
CreatedBy: dbModel.CreatedBy,
CreatedAt: dbModel.CreatedAt,
}
}
func (r *orderRepository) toOrderInquiryDBModel(inquiry *entity.OrderInquiry) models.OrderInquiryDB {
return models.OrderInquiryDB{
ID: inquiry.ID,
PartnerID: inquiry.PartnerID,
CustomerID: &inquiry.CustomerID,
Status: inquiry.Status,
Amount: inquiry.Amount,
Fee: inquiry.Fee,
Total: inquiry.Total,
PaymentType: inquiry.PaymentType,
Source: inquiry.Source,
CreatedBy: inquiry.CreatedBy,
CreatedAt: inquiry.CreatedAt,
UpdatedAt: inquiry.UpdatedAt,
ExpiresAt: inquiry.ExpiresAt,
CustomerName: inquiry.CustomerName,
CustomerPhoneNumber: inquiry.CustomerPhoneNumber,
CustomerEmail: inquiry.CustomerEmail,
}
}
func (r *orderRepository) toDomainOrderInquiryModel(dbModel *models.OrderInquiryDB) *entity.OrderInquiry {
inquiry := &entity.OrderInquiry{
ID: dbModel.ID,
PartnerID: dbModel.PartnerID,
Status: dbModel.Status,
Amount: dbModel.Amount,
Fee: dbModel.Fee,
Total: dbModel.Total,
PaymentType: dbModel.PaymentType,
Source: dbModel.Source,
CreatedBy: dbModel.CreatedBy,
CreatedAt: dbModel.CreatedAt,
ExpiresAt: dbModel.ExpiresAt,
OrderItems: []entity.OrderItem{},
}
if dbModel.CustomerID != nil {
inquiry.CustomerID = *dbModel.CustomerID
}
inquiry.UpdatedAt = dbModel.UpdatedAt
return inquiry
}
+1 -1
View File
@@ -63,5 +63,5 @@ func (r *OssRepositoryImpl) GetPublicURL(fileName string) string {
if fileName == "" {
return ""
}
return fmt.Sprintf("%s/%s%s", r.cfg.GetHostURL(), r.cfg.GetBucketName(), fileName)
return fmt.Sprintf("%s%s%s", r.cfg.GetHostURL(), r.cfg.GetBucketName(), fileName)
}
+82
View File
@@ -0,0 +1,82 @@
package repository
import (
"enaklo-pos-be/internal/common/mycontext"
"enaklo-pos-be/internal/entity"
"enaklo-pos-be/internal/repository/models"
"github.com/pkg/errors"
"gorm.io/gorm"
)
type ProductRepository interface {
GetProductsByIDs(ctx mycontext.Context, ids []int64, partnerID int64) ([]*entity.Product, error)
GetProductDetails(ctx mycontext.Context, productIDs []int64, partnerID int64) (*entity.ProductDetails, error)
}
type productRepository struct {
db *gorm.DB
}
func NewproductRepository(db *gorm.DB) *productRepository {
return &productRepository{db: db}
}
func (r *productRepository) GetProductsByIDs(ctx mycontext.Context, ids []int64, partnerID int64) ([]*entity.Product, error) {
if len(ids) == 0 {
return []*entity.Product{}, nil
}
var productsDB []models.ProductDB
if err := r.db.Where("id IN ? AND partner_id = ?", ids, partnerID).Find(&productsDB).Error; err != nil {
return nil, errors.Wrap(err, "failed to find products")
}
products := make([]*entity.Product, 0, len(productsDB))
for i := range productsDB {
product := r.toDomainProductModel(&productsDB[i])
products = append(products, product)
}
return products, nil
}
func (r *productRepository) GetProductDetails(ctx mycontext.Context, productIDs []int64, partnerID int64) (*entity.ProductDetails, error) {
if len(productIDs) == 0 {
return &entity.ProductDetails{
Products: make(map[int64]*entity.Product),
}, nil
}
var productsDB []models.ProductDB
if err := r.db.Where("id IN ? AND partner_id = ?", productIDs, partnerID).Find(&productsDB).Error; err != nil {
return nil, errors.Wrap(err, "failed to find products")
}
productMap := make(map[int64]*entity.Product, len(productsDB))
for i := range productsDB {
product := r.toDomainProductModel(&productsDB[i])
productMap[product.ID] = product
}
return &entity.ProductDetails{
Products: productMap,
PartnerID: partnerID,
}, nil
}
func (r *productRepository) toDomainProductModel(dbModel *models.ProductDB) *entity.Product {
return &entity.Product{
ID: dbModel.ID,
PartnerID: dbModel.PartnerID,
Name: dbModel.Name,
Description: dbModel.Description,
Price: dbModel.Price,
Type: dbModel.Type,
Status: dbModel.Status,
CreatedAt: dbModel.CreatedAt,
UpdatedAt: dbModel.UpdatedAt,
}
}
-8
View File
@@ -88,14 +88,6 @@ func (b *ProductRepository) GetAllProducts(ctx context.Context, req entity.Produ
query = query.Where("branch_id = ? ", req.BranchID)
}
if req.Available != "" {
if req.Available.IsAvailable() {
query = query.Where("stock_qty > 0 ")
} else if req.Available.IsUnavailable() {
query = query.Where("stock_qty < 1 ")
}
}
if req.Limit > 0 {
query = query.Limit(req.Limit)
}
+12
View File
@@ -51,6 +51,11 @@ type RepoManagerImpl struct {
Transaction TransactionRepository
PG PaymentGateway
LinkQu LinkQu
OrderRepo OrderRepository
CustomerRepo CustomerRepo
ProductRepo ProductRepository
TransactionRepo TransactionRepo
}
func NewRepoManagerImpl(db *gorm.DB, cfg *config.Config) *RepoManagerImpl {
@@ -74,6 +79,11 @@ func NewRepoManagerImpl(db *gorm.DB, cfg *config.Config) *RepoManagerImpl {
Transaction: transactions.NewTransactionRepository(db),
PG: pg.NewPaymentGatewayRepo(&cfg.Midtrans, &cfg.LinkQu),
LinkQu: linkqu.NewLinkQuService(&cfg.LinkQu),
OrderRepo: NeworderRepository(db),
CustomerRepo: NewCustomerRepository(db),
ProductRepo: NewproductRepository(db),
TransactionRepo: NewTransactionRepository(db),
}
}
@@ -97,6 +107,8 @@ type Crypto interface {
GenerateJWT(user *entity.User) (string, error)
GenerateJWTReseetPassword(user *entity.User) (string, error)
GenerateJWTOrder(order *entity.Order) (string, error)
GenerateJWTOrderInquiry(inquiry *entity.OrderInquiry) (string, error)
ValidateJWTOrderInquiry(tokenString string) (int64, string, error)
ValidateJWTOrder(tokenString string) (int64, int64, error)
ValidateResetPassword(tokenString string) (int64, error)
ParseAndValidateJWT(token string) (*entity.JWTAuthClaims, error)
-3
View File
@@ -36,14 +36,11 @@ func (r *SiteRepository) Upsert(ctx context.Context, site *entity.Site) (*entity
if len(site.Products) > 0 {
for i := range site.Products {
site.Products[i].SiteID = site.ID
if site.Products[i].ID != 0 {
// Update existing product
if err := tx.Save(&site.Products[i]).Error; err != nil {
return err
}
} else {
// Create new product
if err := tx.Create(&site.Products[i]).Error; err != nil {
return err
}
+76
View File
@@ -0,0 +1,76 @@
package repository
import (
"enaklo-pos-be/internal/common/mycontext"
"enaklo-pos-be/internal/entity"
"enaklo-pos-be/internal/repository/models"
"github.com/pkg/errors"
"gorm.io/gorm"
)
type TransactionRepo interface {
Create(ctx mycontext.Context, transaction *entity.Transaction) (*entity.Transaction, error)
FindByOrderID(ctx mycontext.Context, orderID int64) ([]*entity.Transaction, error)
}
type transactionRepository struct {
db *gorm.DB
}
func NewTransactionRepository(db *gorm.DB) *transactionRepository {
return &transactionRepository{
db: db,
}
}
func (r *transactionRepository) Create(ctx mycontext.Context, transaction *entity.Transaction) (*entity.Transaction, error) {
transactionDB := r.toTransactionDBModel(transaction)
if err := r.db.Create(&transactionDB).Error; err != nil {
return nil, errors.Wrap(err, "failed to insert transaction")
}
return transaction, nil
}
func (r *transactionRepository) FindByOrderID(ctx mycontext.Context, orderID int64) ([]*entity.Transaction, error) {
var transactionsDB []models.TransactionDB
if err := r.db.Where("order_id = ?", orderID).Find(&transactionsDB).Error; err != nil {
return nil, errors.Wrap(err, "failed to find transactions for order")
}
transactions := make([]*entity.Transaction, 0, len(transactionsDB))
for i := range transactionsDB {
transaction := r.toDomainTransactionModel(&transactionsDB[i])
transactions = append(transactions, transaction)
}
return transactions, nil
}
func (r *transactionRepository) toTransactionDBModel(transaction *entity.Transaction) models.TransactionDB {
return models.TransactionDB{
ID: transaction.ID,
OrderID: transaction.OrderID,
Amount: transaction.Amount,
PaymentMethod: transaction.PaymentMethod,
Status: transaction.Status,
CreatedAt: transaction.CreatedAt,
UpdatedAt: transaction.UpdatedAt,
TransactionType: transaction.TransactionType,
PartnerID: transaction.PartnerID,
}
}
func (r *transactionRepository) toDomainTransactionModel(dbModel *models.TransactionDB) *entity.Transaction {
return &entity.Transaction{
ID: dbModel.ID,
OrderID: dbModel.OrderID,
Amount: dbModel.Amount,
PaymentMethod: dbModel.PaymentMethod,
Status: dbModel.Status,
CreatedAt: dbModel.CreatedAt,
UpdatedAt: dbModel.UpdatedAt,
}
}