226 lines
7.3 KiB
Go
226 lines
7.3 KiB
Go
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 PartnerSettingsRepository interface {
|
|
GetByPartnerID(ctx mycontext.Context, partnerID int64) (*entity.PartnerSettings, error)
|
|
Upsert(ctx mycontext.Context, settings *entity.PartnerSettings) error
|
|
GetPaymentMethods(ctx mycontext.Context, partnerID int64) ([]entity.PartnerPaymentMethod, error)
|
|
UpsertPaymentMethod(ctx mycontext.Context, method *entity.PartnerPaymentMethod) error
|
|
DeletePaymentMethod(ctx mycontext.Context, id int64, partnerID int64) error
|
|
UpdatePaymentMethodOrder(ctx mycontext.Context, partnerID int64, methodIDs []int64) error
|
|
}
|
|
|
|
type partnerSettingsRepository struct {
|
|
db *gorm.DB
|
|
}
|
|
|
|
func NewPartnerSettingsRepository(db *gorm.DB) PartnerSettingsRepository {
|
|
return &partnerSettingsRepository{db: db}
|
|
}
|
|
|
|
func (r *partnerSettingsRepository) GetByPartnerID(ctx mycontext.Context, partnerID int64) (*entity.PartnerSettings, error) {
|
|
var settingsDB models.PartnerSettingsDB
|
|
|
|
err := r.db.Where("partner_id = ?", partnerID).First(&settingsDB).Error
|
|
if err != nil {
|
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
|
return &entity.PartnerSettings{
|
|
PartnerID: partnerID,
|
|
TaxEnabled: true,
|
|
TaxPercentage: 10.0,
|
|
}, nil
|
|
}
|
|
return nil, errors.Wrap(err, "failed to get partner settings")
|
|
}
|
|
|
|
return r.toDomainModel(&settingsDB), nil
|
|
}
|
|
|
|
func (r *partnerSettingsRepository) Upsert(ctx mycontext.Context, settings *entity.PartnerSettings) error {
|
|
settingsDB := r.toDBModel(settings)
|
|
settingsDB.UpdatedAt = time.Now()
|
|
|
|
// Check if record exists
|
|
var count int64
|
|
if err := r.db.Model(&models.PartnerSettingsDB{}).Where("partner_id = ?", settings.PartnerID).Count(&count).Error; err != nil {
|
|
return errors.Wrap(err, "failed to check partner settings existence")
|
|
}
|
|
|
|
if count > 0 {
|
|
// Update existing record
|
|
if err := r.db.Model(&models.PartnerSettingsDB{}).Where("partner_id = ?", settings.PartnerID).Updates(settingsDB).Error; err != nil {
|
|
return errors.Wrap(err, "failed to update partner settings")
|
|
}
|
|
} else {
|
|
// Create new record
|
|
settingsDB.CreatedAt = time.Now()
|
|
if err := r.db.Create(&settingsDB).Error; err != nil {
|
|
return errors.Wrap(err, "failed to create partner settings")
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (r *partnerSettingsRepository) GetPaymentMethods(ctx mycontext.Context, partnerID int64) ([]entity.PartnerPaymentMethod, error) {
|
|
var methodsDB []models.PartnerPaymentMethodDB
|
|
|
|
if err := r.db.Where("partner_id = ?", partnerID).Order("display_order").Find(&methodsDB).Error; err != nil {
|
|
return nil, errors.Wrap(err, "failed to get partner payment methods")
|
|
}
|
|
|
|
methods := make([]entity.PartnerPaymentMethod, len(methodsDB))
|
|
for i, methodDB := range methodsDB {
|
|
methods[i] = *r.toDomainPaymentMethodModel(&methodDB)
|
|
}
|
|
|
|
return methods, nil
|
|
}
|
|
|
|
func (r *partnerSettingsRepository) UpsertPaymentMethod(ctx mycontext.Context, method *entity.PartnerPaymentMethod) error {
|
|
methodDB := r.toDBPaymentMethodModel(method)
|
|
methodDB.UpdatedAt = time.Now()
|
|
|
|
tx := r.db.Begin()
|
|
if tx.Error != nil {
|
|
return errors.Wrap(tx.Error, "failed to begin transaction")
|
|
}
|
|
|
|
defer func() {
|
|
if r := recover(); r != nil {
|
|
tx.Rollback()
|
|
}
|
|
}()
|
|
|
|
if method.ID > 0 {
|
|
// Update existing record
|
|
if err := tx.Model(&models.PartnerPaymentMethodDB{}).Where("id = ? AND partner_id = ?", method.ID, method.PartnerID).Updates(methodDB).Error; err != nil {
|
|
tx.Rollback()
|
|
return errors.Wrap(err, "failed to update payment method")
|
|
}
|
|
} else {
|
|
// Get the next display order if not specified
|
|
if method.DisplayOrder == 0 {
|
|
var maxOrder int
|
|
if err := tx.Model(&models.PartnerPaymentMethodDB{}).Where("partner_id = ?", method.PartnerID).Select("COALESCE(MAX(display_order), 0)").Row().Scan(&maxOrder); err != nil {
|
|
tx.Rollback()
|
|
return errors.Wrap(err, "failed to get max display order")
|
|
}
|
|
methodDB.DisplayOrder = maxOrder + 1
|
|
}
|
|
|
|
// Create new record
|
|
methodDB.CreatedAt = time.Now()
|
|
if err := tx.Create(&methodDB).Error; err != nil {
|
|
tx.Rollback()
|
|
return errors.Wrap(err, "failed to create payment method")
|
|
}
|
|
|
|
method.ID = methodDB.ID
|
|
}
|
|
|
|
return tx.Commit().Error
|
|
}
|
|
|
|
func (r *partnerSettingsRepository) DeletePaymentMethod(ctx mycontext.Context, id int64, partnerID int64) error {
|
|
result := r.db.Where("id = ? AND partner_id = ?", id, partnerID).Delete(&models.PartnerPaymentMethodDB{})
|
|
|
|
if result.Error != nil {
|
|
return errors.Wrap(result.Error, "failed to delete payment method")
|
|
}
|
|
|
|
if result.RowsAffected == 0 {
|
|
return errors.New("payment method not found or not authorized")
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func (r *partnerSettingsRepository) UpdatePaymentMethodOrder(ctx mycontext.Context, partnerID int64, methodIDs []int64) error {
|
|
tx := r.db.Begin()
|
|
if tx.Error != nil {
|
|
return errors.Wrap(tx.Error, "failed to begin transaction")
|
|
}
|
|
|
|
defer func() {
|
|
if r := recover(); r != nil {
|
|
tx.Rollback()
|
|
}
|
|
}()
|
|
|
|
for i, id := range methodIDs {
|
|
if err := tx.Model(&models.PartnerPaymentMethodDB{}).
|
|
Where("id = ? AND partner_id = ?", id, partnerID).
|
|
Update("display_order", i+1).Error; err != nil {
|
|
tx.Rollback()
|
|
return errors.Wrap(err, "failed to update payment method order")
|
|
}
|
|
}
|
|
|
|
return tx.Commit().Error
|
|
}
|
|
|
|
func (r *partnerSettingsRepository) toDomainModel(dbModel *models.PartnerSettingsDB) *entity.PartnerSettings {
|
|
return &entity.PartnerSettings{
|
|
PartnerID: dbModel.PartnerID,
|
|
TaxEnabled: dbModel.TaxEnabled,
|
|
TaxPercentage: dbModel.TaxPercentage,
|
|
InvoicePrefix: dbModel.InvoicePrefix,
|
|
BusinessHours: dbModel.BusinessHours,
|
|
LogoURL: dbModel.LogoURL,
|
|
ThemeColor: dbModel.ThemeColor,
|
|
ReceiptFooterText: dbModel.ReceiptFooterText,
|
|
ReceiptHeaderText: dbModel.ReceiptHeaderText,
|
|
CreatedAt: dbModel.CreatedAt,
|
|
UpdatedAt: dbModel.UpdatedAt,
|
|
}
|
|
}
|
|
|
|
func (r *partnerSettingsRepository) toDBModel(domainModel *entity.PartnerSettings) models.PartnerSettingsDB {
|
|
return models.PartnerSettingsDB{
|
|
PartnerID: domainModel.PartnerID,
|
|
TaxEnabled: domainModel.TaxEnabled,
|
|
TaxPercentage: domainModel.TaxPercentage,
|
|
InvoicePrefix: domainModel.InvoicePrefix,
|
|
BusinessHours: domainModel.BusinessHours,
|
|
LogoURL: domainModel.LogoURL,
|
|
ThemeColor: domainModel.ThemeColor,
|
|
ReceiptFooterText: domainModel.ReceiptFooterText,
|
|
ReceiptHeaderText: domainModel.ReceiptHeaderText,
|
|
}
|
|
}
|
|
|
|
func (r *partnerSettingsRepository) toDomainPaymentMethodModel(dbModel *models.PartnerPaymentMethodDB) *entity.PartnerPaymentMethod {
|
|
return &entity.PartnerPaymentMethod{
|
|
ID: dbModel.ID,
|
|
PartnerID: dbModel.PartnerID,
|
|
PaymentMethod: dbModel.PaymentMethod,
|
|
IsEnabled: dbModel.IsEnabled,
|
|
DisplayName: dbModel.DisplayName,
|
|
DisplayOrder: dbModel.DisplayOrder,
|
|
AdditionalInfo: dbModel.AdditionalInfo,
|
|
CreatedAt: dbModel.CreatedAt,
|
|
UpdatedAt: dbModel.UpdatedAt,
|
|
}
|
|
}
|
|
|
|
func (r *partnerSettingsRepository) toDBPaymentMethodModel(domainModel *entity.PartnerPaymentMethod) models.PartnerPaymentMethodDB {
|
|
return models.PartnerPaymentMethodDB{
|
|
ID: domainModel.ID,
|
|
PartnerID: domainModel.PartnerID,
|
|
PaymentMethod: domainModel.PaymentMethod,
|
|
IsEnabled: domainModel.IsEnabled,
|
|
DisplayName: domainModel.DisplayName,
|
|
DisplayOrder: domainModel.DisplayOrder,
|
|
AdditionalInfo: domainModel.AdditionalInfo,
|
|
}
|
|
}
|