mirror of
https://gitlab.com/mbugroup/lti-api.git
synced 2026-05-24 15:25:43 +00:00
Feat(BE-339): make a report for purchasing supplier
This commit is contained in:
@@ -0,0 +1,196 @@
|
||||
package repositories
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
|
||||
validation "gitlab.com/mbugroup/lti-api.git/internal/modules/repports/validations"
|
||||
"gitlab.com/mbugroup/lti-api.git/internal/utils"
|
||||
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
type PurchaseSupplierRepository interface {
|
||||
GetSuppliersWithPurchases(ctx context.Context, offset, limit int, filters *validation.PurchaseSupplierQuery) ([]entity.Supplier, int64, error)
|
||||
GetItemsBySuppliers(ctx context.Context, supplierIDs []uint, filters *validation.PurchaseSupplierQuery) ([]entity.PurchaseItem, error)
|
||||
}
|
||||
|
||||
type purchaseSupplierRepositoryImpl struct {
|
||||
db *gorm.DB
|
||||
}
|
||||
|
||||
func NewPurchaseSupplierRepository(db *gorm.DB) PurchaseSupplierRepository {
|
||||
return &purchaseSupplierRepositoryImpl{db: db}
|
||||
}
|
||||
|
||||
func (r *purchaseSupplierRepositoryImpl) baseSupplierQuery(ctx context.Context, filters *validation.PurchaseSupplierQuery) *gorm.DB {
|
||||
// Tentukan kolom tanggal yang akan dipakai untuk filter
|
||||
dateColumn := "purchase_items.received_date"
|
||||
switch strings.ToLower(strings.TrimSpace(filters.FilterBy)) {
|
||||
case "po_date":
|
||||
dateColumn = "purchases.po_date"
|
||||
case "receive_date", "":
|
||||
dateColumn = "purchase_items.received_date"
|
||||
}
|
||||
|
||||
db := r.db.WithContext(ctx).
|
||||
Model(&entity.Supplier{}).
|
||||
Joins("JOIN purchases ON purchases.supplier_id = suppliers.id").
|
||||
Joins("JOIN purchase_items ON purchase_items.purchase_id = purchases.id")
|
||||
|
||||
if filters.SupplierId > 0 {
|
||||
db = db.Where("suppliers.id = ?", filters.SupplierId)
|
||||
}
|
||||
|
||||
if filters.ProductId > 0 {
|
||||
db = db.Where("purchase_items.product_id = ?", filters.ProductId)
|
||||
}
|
||||
|
||||
if filters.ProductCategoryId > 0 {
|
||||
db = db.
|
||||
Joins("JOIN products ON products.id = purchase_items.product_id").
|
||||
Where("products.product_category_id = ?", filters.ProductCategoryId)
|
||||
}
|
||||
|
||||
if filters.AreaId > 0 {
|
||||
db = db.
|
||||
Joins("JOIN warehouses ON warehouses.id = purchase_items.warehouse_id").
|
||||
Where("warehouses.area_id = ?", filters.AreaId)
|
||||
}
|
||||
|
||||
if filters.DateFrom != "" {
|
||||
if dateFrom, err := utils.ParseDateString(filters.DateFrom); err == nil {
|
||||
db = db.Where(fmt.Sprintf("DATE(%s) >= ?", dateColumn), dateFrom)
|
||||
}
|
||||
}
|
||||
|
||||
if filters.DateTo != "" {
|
||||
if dateTo, err := utils.ParseDateString(filters.DateTo); err == nil {
|
||||
db = db.Where(fmt.Sprintf("DATE(%s) <= ?", dateColumn), dateTo)
|
||||
}
|
||||
}
|
||||
|
||||
return db
|
||||
}
|
||||
|
||||
func (r *purchaseSupplierRepositoryImpl) GetSuppliersWithPurchases(ctx context.Context, offset, limit int, filters *validation.PurchaseSupplierQuery) ([]entity.Supplier, int64, error) {
|
||||
query := r.baseSupplierQuery(ctx, filters)
|
||||
|
||||
var totalSuppliers int64
|
||||
if err := query.
|
||||
Distinct("suppliers.id").
|
||||
Count(&totalSuppliers).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
if totalSuppliers == 0 {
|
||||
return []entity.Supplier{}, 0, nil
|
||||
}
|
||||
|
||||
if offset < 0 {
|
||||
offset = 0
|
||||
}
|
||||
|
||||
var supplierIDs []uint
|
||||
if err := query.
|
||||
Select("suppliers.id").
|
||||
Order("suppliers.id ASC").
|
||||
Offset(offset).
|
||||
Limit(limit).
|
||||
Pluck("suppliers.id", &supplierIDs).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
if len(supplierIDs) == 0 {
|
||||
return []entity.Supplier{}, totalSuppliers, nil
|
||||
}
|
||||
|
||||
var suppliers []entity.Supplier
|
||||
if err := r.db.WithContext(ctx).
|
||||
Where("id IN ?", supplierIDs).
|
||||
Find(&suppliers).Error; err != nil {
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
return suppliers, totalSuppliers, nil
|
||||
}
|
||||
|
||||
func (r *purchaseSupplierRepositoryImpl) GetItemsBySuppliers(ctx context.Context, supplierIDs []uint, filters *validation.PurchaseSupplierQuery) ([]entity.PurchaseItem, error) {
|
||||
if len(supplierIDs) == 0 {
|
||||
return []entity.PurchaseItem{}, nil
|
||||
}
|
||||
|
||||
// Tentukan kolom tanggal yang akan dipakai untuk filter & sort
|
||||
dateColumn := "purchase_items.received_date"
|
||||
switch strings.ToLower(strings.TrimSpace(filters.FilterBy)) {
|
||||
case "po_date":
|
||||
dateColumn = "purchases.po_date"
|
||||
case "receive_date", "":
|
||||
dateColumn = "purchase_items.received_date"
|
||||
}
|
||||
|
||||
orderDirection := "ASC"
|
||||
switch strings.ToUpper(strings.TrimSpace(filters.SortBy)) {
|
||||
case "DESC":
|
||||
orderDirection = "DESC"
|
||||
case "ASC", "":
|
||||
orderDirection = "ASC"
|
||||
}
|
||||
|
||||
db := r.db.WithContext(ctx).
|
||||
Model(&entity.PurchaseItem{}).
|
||||
Preload("Purchase").
|
||||
Preload("Purchase.Supplier").
|
||||
Preload("Product").
|
||||
Preload("Product.ProductCategory").
|
||||
Preload("Warehouse").
|
||||
Preload("Warehouse.Area").
|
||||
Preload("Warehouse.Location").
|
||||
Preload("Warehouse.Kandang").
|
||||
Preload("ExpenseNonstock").
|
||||
Preload("ExpenseNonstock.Expense").
|
||||
Preload("ExpenseNonstock.Expense.Supplier").
|
||||
Joins("JOIN purchases ON purchases.id = purchase_items.purchase_id").
|
||||
Where("purchases.supplier_id IN ?", supplierIDs)
|
||||
|
||||
if filters.ProductId > 0 {
|
||||
db = db.Where("purchase_items.product_id = ?", filters.ProductId)
|
||||
}
|
||||
|
||||
if filters.ProductCategoryId > 0 {
|
||||
db = db.
|
||||
Joins("JOIN products ON products.id = purchase_items.product_id").
|
||||
Where("products.product_category_id = ?", filters.ProductCategoryId)
|
||||
}
|
||||
|
||||
if filters.AreaId > 0 {
|
||||
db = db.
|
||||
Joins("JOIN warehouses ON warehouses.id = purchase_items.warehouse_id").
|
||||
Where("warehouses.area_id = ?", filters.AreaId)
|
||||
}
|
||||
|
||||
if filters.DateFrom != "" {
|
||||
if dateFrom, err := utils.ParseDateString(filters.DateFrom); err == nil {
|
||||
db = db.Where(fmt.Sprintf("DATE(%s) >= ?", dateColumn), dateFrom)
|
||||
}
|
||||
}
|
||||
|
||||
if filters.DateTo != "" {
|
||||
if dateTo, err := utils.ParseDateString(filters.DateTo); err == nil {
|
||||
db = db.Where(fmt.Sprintf("DATE(%s) <= ?", dateColumn), dateTo)
|
||||
}
|
||||
}
|
||||
|
||||
// Urutkan berdasarkan kolom tanggal yang dipilih dan arah sort
|
||||
db = db.Order(fmt.Sprintf("%s %s", dateColumn, orderDirection)).
|
||||
Order("purchase_items.id ASC")
|
||||
|
||||
var items []entity.PurchaseItem
|
||||
if err := db.Find(&items).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return items, nil
|
||||
}
|
||||
Reference in New Issue
Block a user