cargo-platform/pkg/datatable/datatable.go
teguh nugroho 10575b2512
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful
filter
2026-08-18 20:24:23 +07:00

109 lines
2.3 KiB
Go

package datatable
import (
"cargo-erp-backend/internal/handlers/dto"
"fmt"
"strings"
"gorm.io/gorm"
)
type DatatableInterface interface {
Render(coldef []dto.DataTableColDef) dto.DataTableResponse
}
type Datatable struct {
DB *gorm.DB
Req dto.DataTableRequest
}
func NewDatatable(db *gorm.DB, table_request dto.DataTableRequest) DatatableInterface {
return &Datatable{
DB: db,
Req: table_request,
}
}
func (d *Datatable) SetTable(db *gorm.DB) {
d.DB = db
}
func (d *Datatable) Render(coldef []dto.DataTableColDef) dto.DataTableResponse {
var totaldata int64 = 0
d.DB.Count(&totaldata)
//select
selectAlias := make([]string, 0)
for _, v := range coldef {
selectAlias = append(selectAlias, fmt.Sprintf("%v AS %v", v.Field, v.Alias))
}
d.DB.Select(selectAlias)
//global filter
var g *gorm.DB
is_filtering := false
if len(d.Req.Search.Value) > 0 {
for _, vcol := range d.Req.Columns {
if vcol.Searchable {
for _, v := range coldef {
if v.Alias == vcol.Data {
g.Or(fmt.Sprintf("%v::TEXT ILIKE '%%%v%%'", v.Field, d.Req.Search.Value))
is_filtering = true
}
}
}
}
}
if is_filtering {
d.DB.Where(g)
}
//order
if len(d.Req.Order) > 0 {
for _, vOrder := range d.Req.Order {
for _, vcol := range d.Req.Columns {
if vcol.Orderable && vOrder.Column == vcol.Data {
for _, v := range coldef {
if v.Alias == vcol.Data {
d.DB.Order(fmt.Sprintf("%v %v", v.Field, strings.ToUpper(vOrder.Dir)))
}
}
}
}
}
}
//order
if len(d.Req.AdditionalFilter) > 0 {
for k, vFilter := range d.Req.AdditionalFilter {
for _, v := range coldef {
if v.Alias == k {
d.DB.Where(fmt.Sprintf("%v=?", v.Field), vFilter)
}
}
}
}
var totalFiltered int64 = 0
d.DB.Count(&totalFiltered)
start := d.Req.Start
if start == 0 {
start = 1
}
limit := d.Req.Length
d.DB.Limit(limit).Offset(start*limit - limit)
output := make([]map[string]interface{}, 0)
d.DB.Scan(&output)
for _, voutput := range output {
for kv, vv := range voutput {
for _, v := range coldef {
if v.Alias == kv {
if v.Formatter != nil {
voutput[kv] = v.Formatter(voutput, vv)
}
}
}
}
}
result := dto.DataTableResponse{
Draw: 1,
RecordsTotal: totaldata,
RecordsFiltered: totalFiltered,
Data: output,
}
return result
}