Update template email
This commit is contained in:
@@ -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{
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
@@ -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"
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user