mirror of
https://gitlab.com/mbugroup/lti-api.git
synced 2026-05-25 07:45:44 +00:00
Refactor[BE]: : delete sales orders and delivery order folder and refactor to just one root marketing folder
This commit is contained in:
@@ -0,0 +1,122 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"gitlab.com/mbugroup/lti-api.git/internal/common/repository"
|
||||
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
|
||||
"gitlab.com/mbugroup/lti-api.git/internal/utils"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/clause"
|
||||
)
|
||||
|
||||
type MarketingRepository interface {
|
||||
repository.BaseRepository[entity.Marketing]
|
||||
IdExists(ctx context.Context, id uint) (bool, error)
|
||||
GetNextSequence(ctx context.Context) (uint, error)
|
||||
NextSoNumber(ctx context.Context, tx *gorm.DB) (string, error)
|
||||
}
|
||||
|
||||
type MarketingRepositoryImpl struct {
|
||||
*repository.BaseRepositoryImpl[entity.Marketing]
|
||||
}
|
||||
|
||||
func NewMarketingRepository(db *gorm.DB) MarketingRepository {
|
||||
return &MarketingRepositoryImpl{
|
||||
BaseRepositoryImpl: repository.NewBaseRepository[entity.Marketing](db),
|
||||
}
|
||||
}
|
||||
|
||||
func (r *MarketingRepositoryImpl) IdExists(ctx context.Context, id uint) (bool, error) {
|
||||
return repository.Exists[entity.Marketing](ctx, r.DB(), id)
|
||||
}
|
||||
|
||||
func (r *MarketingRepositoryImpl) GetNextSequence(ctx context.Context) (uint, error) {
|
||||
var maxID uint
|
||||
if err := r.DB().WithContext(ctx).Model(&entity.Marketing{}).Select("COALESCE(MAX(id), 0)").Scan(&maxID).Error; err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return maxID + 1, nil
|
||||
}
|
||||
|
||||
func (r *MarketingRepositoryImpl) NextSoNumber(ctx context.Context, tx *gorm.DB) (string, error) {
|
||||
return r.generateSequentialNumber(ctx, tx, "so_number", utils.MarketingSoNumberPrefix, utils.MarketingNumberPadding)
|
||||
}
|
||||
|
||||
func parseNumericSuffix(value, prefix string) (int, bool) {
|
||||
if !strings.HasPrefix(value, prefix) {
|
||||
return 0, false
|
||||
}
|
||||
suffix := strings.TrimPrefix(value, prefix)
|
||||
if suffix == "" {
|
||||
return 0, false
|
||||
}
|
||||
trimmed := strings.TrimLeft(suffix, "0")
|
||||
if trimmed == "" {
|
||||
trimmed = "0"
|
||||
}
|
||||
number, err := strconv.Atoi(trimmed)
|
||||
if err != nil {
|
||||
return 0, false
|
||||
}
|
||||
return number, true
|
||||
}
|
||||
|
||||
func (r *MarketingRepositoryImpl) numberExists(ctx context.Context, db *gorm.DB, column, value string) (bool, error) {
|
||||
var count int64
|
||||
if err := db.WithContext(ctx).
|
||||
Model(&entity.Marketing{}).
|
||||
Where(fmt.Sprintf("%s = ?", column), value).
|
||||
Count(&count).Error; err != nil {
|
||||
return false, err
|
||||
}
|
||||
return count > 0, nil
|
||||
}
|
||||
|
||||
func (r *MarketingRepositoryImpl) generateSequentialNumber(ctx context.Context, tx *gorm.DB, column, prefix string, padding int) (string, error) {
|
||||
|
||||
db := tx
|
||||
if db == nil {
|
||||
db = r.DB()
|
||||
}
|
||||
|
||||
var values []string
|
||||
err := db.WithContext(ctx).
|
||||
Model(&entity.Marketing{}).
|
||||
Where(fmt.Sprintf("%s LIKE ?", column), prefix+"%").
|
||||
Select(column).
|
||||
Order(fmt.Sprintf("%s DESC", column)).
|
||||
Limit(20).
|
||||
Clauses(clause.Locking{Strength: "UPDATE"}).
|
||||
Pluck(column, &values).Error
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
next := 1
|
||||
for _, value := range values {
|
||||
if number, ok := parseNumericSuffix(value, prefix); ok {
|
||||
next = number + 1
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
const maxAttempts = 20
|
||||
for attempt := 0; attempt < maxAttempts; attempt++ {
|
||||
candidate := fmt.Sprintf("%s%0*d", prefix, padding, next)
|
||||
exists, err := r.numberExists(ctx, db, column, candidate)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if !exists {
|
||||
return candidate, nil
|
||||
}
|
||||
next++
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("unable to generate unique %s", column)
|
||||
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"gitlab.com/mbugroup/lti-api.git/internal/common/repository"
|
||||
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type MarketingDeliveryProductRepository interface {
|
||||
repository.BaseRepository[entity.MarketingDeliveryProduct]
|
||||
GetDeliveryProductsByProjectFlockID(ctx context.Context, projectFlockID uint, callback func(*gorm.DB) *gorm.DB) ([]entity.MarketingDeliveryProduct, error)
|
||||
GetByMarketingId(ctx context.Context, marketingId uint) ([]entity.MarketingDeliveryProduct, error)
|
||||
GetByMarketingProductID(ctx context.Context, marketingProductID uint) (*entity.MarketingDeliveryProduct, error)
|
||||
}
|
||||
|
||||
type MarketingDeliveryProductRepositoryImpl struct {
|
||||
*repository.BaseRepositoryImpl[entity.MarketingDeliveryProduct]
|
||||
}
|
||||
|
||||
func NewMarketingDeliveryProductRepository(db *gorm.DB) MarketingDeliveryProductRepository {
|
||||
return &MarketingDeliveryProductRepositoryImpl{
|
||||
BaseRepositoryImpl: repository.NewBaseRepository[entity.MarketingDeliveryProduct](db),
|
||||
}
|
||||
}
|
||||
|
||||
func (r *MarketingDeliveryProductRepositoryImpl) GetDeliveryProductsByProjectFlockID(ctx context.Context, projectFlockID uint, callback func(*gorm.DB) *gorm.DB) ([]entity.MarketingDeliveryProduct, error) {
|
||||
var deliveryProducts []entity.MarketingDeliveryProduct
|
||||
|
||||
// JOIN digunakan untuk filter WHERE clause ke ProjectFlockID yang berada 3 level relasi atas
|
||||
// Entity relations digunakan di Preload (callback) untuk load data, bukan untuk filter
|
||||
db := r.DB().WithContext(ctx).
|
||||
Joins("JOIN marketing_products ON marketing_products.id = marketing_delivery_products.marketing_product_id").
|
||||
Joins("JOIN product_warehouses ON product_warehouses.id = marketing_products.product_warehouse_id").
|
||||
Joins("JOIN project_flock_kandangs ON project_flock_kandangs.id = product_warehouses.project_flock_kandang_id").
|
||||
Where("project_flock_kandangs.project_flock_id = ?", projectFlockID).
|
||||
Distinct("marketing_delivery_products.*")
|
||||
|
||||
if callback != nil {
|
||||
db = callback(db)
|
||||
}
|
||||
|
||||
if err := db.Find(&deliveryProducts).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return deliveryProducts, nil
|
||||
}
|
||||
|
||||
func (r *MarketingDeliveryProductRepositoryImpl) GetByMarketingId(ctx context.Context, marketingId uint) ([]entity.MarketingDeliveryProduct, error) {
|
||||
var deliveryProducts []entity.MarketingDeliveryProduct
|
||||
|
||||
// JOIN untuk filter by marketing_id yang ada di related table
|
||||
db := r.DB().WithContext(ctx).
|
||||
Joins("JOIN marketing_products ON marketing_products.id = marketing_delivery_products.marketing_product_id").
|
||||
Where("marketing_products.marketing_id = ?", marketingId)
|
||||
|
||||
if err := db.Find(&deliveryProducts).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return deliveryProducts, nil
|
||||
}
|
||||
|
||||
func (r *MarketingDeliveryProductRepositoryImpl) GetByMarketingProductID(ctx context.Context, marketingProductID uint) (*entity.MarketingDeliveryProduct, error) {
|
||||
var deliveryProduct entity.MarketingDeliveryProduct
|
||||
|
||||
if err := r.DB().WithContext(ctx).
|
||||
Where("marketing_product_id = ?", marketingProductID).
|
||||
First(&deliveryProduct).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &deliveryProduct, nil
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"gitlab.com/mbugroup/lti-api.git/internal/common/repository"
|
||||
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type MarketingProductRepository interface {
|
||||
repository.BaseRepository[entity.MarketingProduct]
|
||||
GetByMarketingID(ctx context.Context, marketingID uint) ([]entity.MarketingProduct, error)
|
||||
IdExists(ctx context.Context, id uint) (bool, error)
|
||||
}
|
||||
|
||||
type MarketingProductRepositoryImpl struct {
|
||||
*repository.BaseRepositoryImpl[entity.MarketingProduct]
|
||||
}
|
||||
|
||||
func NewMarketingProductRepository(db *gorm.DB) MarketingProductRepository {
|
||||
return &MarketingProductRepositoryImpl{
|
||||
BaseRepositoryImpl: repository.NewBaseRepository[entity.MarketingProduct](db),
|
||||
}
|
||||
}
|
||||
|
||||
func (r *MarketingProductRepositoryImpl) GetByMarketingID(ctx context.Context, marketingID uint) ([]entity.MarketingProduct, error) {
|
||||
var products []entity.MarketingProduct
|
||||
if err := r.DB().WithContext(ctx).Where("marketing_id = ?", marketingID).Find(&products).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(products) == 0 {
|
||||
return products, gorm.ErrRecordNotFound
|
||||
}
|
||||
return products, nil
|
||||
}
|
||||
|
||||
func (r *MarketingProductRepositoryImpl) IdExists(ctx context.Context, id uint) (bool, error) {
|
||||
return repository.Exists[entity.MarketingProduct](ctx, r.DB(), id)
|
||||
}
|
||||
Reference in New Issue
Block a user