diff --git a/go.mod b/go.mod index 078bcfe0..517bcdc1 100644 --- a/go.mod +++ b/go.mod @@ -5,12 +5,10 @@ go 1.23 require ( github.com/MicahParks/keyfunc/v2 v2.1.0 github.com/bytedance/sonic v1.12.1 - github.com/glebarez/sqlite v1.11.0 github.com/go-playground/validator/v10 v10.27.0 github.com/gofiber/contrib/jwt v1.0.10 github.com/gofiber/fiber/v2 v2.52.5 github.com/golang-jwt/jwt/v5 v5.2.1 - github.com/google/uuid v1.6.0 github.com/jackc/pgconn v1.14.1 github.com/redis/go-redis/v9 v9.14.0 github.com/sirupsen/logrus v1.9.3 @@ -27,13 +25,12 @@ require ( github.com/cloudwego/base64x v0.1.4 // indirect github.com/cloudwego/iasm v0.2.0 // indirect github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect - github.com/dustin/go-humanize v1.0.1 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/gabriel-vasile/mimetype v1.4.8 // indirect - github.com/glebarez/go-sqlite v1.21.2 // indirect github.com/go-playground/locales v0.14.1 // indirect github.com/go-playground/universal-translator v0.18.1 // indirect github.com/google/go-cmp v0.6.0 // indirect + github.com/google/uuid v1.6.0 // indirect github.com/hashicorp/hcl v1.0.0 // indirect github.com/jackc/chunkreader/v2 v2.0.1 // indirect github.com/jackc/pgio v1.0.0 // indirect @@ -54,7 +51,6 @@ require ( github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/pelletier/go-toml/v2 v2.2.2 // indirect github.com/philhofer/fwd v1.1.2 // indirect - github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect github.com/rivo/uniseg v0.4.7 // indirect github.com/rogpeppe/go-internal v1.11.0 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect @@ -79,8 +75,4 @@ require ( golang.org/x/text v0.22.0 // indirect gopkg.in/ini.v1 v1.67.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - modernc.org/libc v1.22.5 // indirect - modernc.org/mathutil v1.5.0 // indirect - modernc.org/memory v1.5.0 // indirect - modernc.org/sqlite v1.23.1 // indirect ) diff --git a/go.sum b/go.sum index ea477c5d..c07e37e3 100644 --- a/go.sum +++ b/go.sum @@ -27,18 +27,12 @@ github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1 github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= -github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= -github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= github.com/gabriel-vasile/mimetype v1.4.8 h1:FfZ3gj38NjllZIeJAmMhr+qKL8Wu+nOoI3GqacKw1NM= github.com/gabriel-vasile/mimetype v1.4.8/go.mod h1:ByKUIKGjh1ODkGM1asKUbQZOLGrPjydw3hYPU2YU9t8= -github.com/glebarez/go-sqlite v1.21.2 h1:3a6LFC4sKahUunAmynQKLZceZCOzUthkRkEAl9gAXWo= -github.com/glebarez/go-sqlite v1.21.2/go.mod h1:sfxdZyhQjTM2Wry3gVYWaW072Ri1WMdWJi0k6+3382k= -github.com/glebarez/sqlite v1.11.0 h1:wSG0irqzP6VurnMEpFGer5Li19RpIRi2qvQz++w0GMw= -github.com/glebarez/sqlite v1.11.0/go.mod h1:h8/o8j5wiAsqSPoWELDUdJXhjAhsVliSn7bWZjOhrgQ= github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= github.com/go-playground/assert/v2 v2.2.0/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= @@ -56,8 +50,6 @@ github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17w github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= -github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ= -github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo= github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= @@ -154,9 +146,6 @@ github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRI github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/redis/go-redis/v9 v9.14.0 h1:u4tNCjXOyzfgeLN+vAZaW1xUooqWDqVEsZN0U01jfAE= github.com/redis/go-redis/v9 v9.14.0/go.mod h1:huWgSWd8mW6+m0VPhJjSSQ+d6Nh1VICQ6Q5lHuCH/Iw= -github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= -github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= -github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= @@ -317,12 +306,4 @@ gorm.io/driver/postgres v1.5.9 h1:DkegyItji119OlcaLjqN11kHoUgZ/j13E0jkJZgD6A8= gorm.io/driver/postgres v1.5.9/go.mod h1:DX3GReXH+3FPWGrrgffdvCk3DQ1dwDPdmbenSkweRGI= gorm.io/gorm v1.25.11 h1:/Wfyg1B/je1hnDx3sMkX+gAlxrlZpn6X0BXRlwXlvHg= gorm.io/gorm v1.25.11/go.mod h1:xh7N7RHfYlNc5EmcI/El95gXusucDrQnHXe0+CgWcLQ= -modernc.org/libc v1.22.5 h1:91BNch/e5B0uPbJFgqbxXuOnxBQjlS//icfQEGmvyjE= -modernc.org/libc v1.22.5/go.mod h1:jj+Z7dTNX8fBScMVNRAYZ/jF91K8fdT2hYMThc3YjBY= -modernc.org/mathutil v1.5.0 h1:rV0Ko/6SfM+8G+yKiyI830l3Wuz1zRutdslNoQ0kfiQ= -modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E= -modernc.org/memory v1.5.0 h1:N+/8c5rE6EqugZwHii4IFsaJ7MUhoWX07J5tC/iI5Ds= -modernc.org/memory v1.5.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU= -modernc.org/sqlite v1.23.1 h1:nrSBg4aRQQwq59JpvGEQ15tNxoO5pX/kUjcRNwSAGQM= -modernc.org/sqlite v1.23.1/go.mod h1:OrDj17Mggn6MhE+iPbBNf7RGKODDE9NFT0f3EwDzJqk= nullprogram.com/x/optparse v1.0.0/go.mod h1:KdyPE+Igbe0jQUrVfMqDMeJQIJZEuyV7pjYmp6pbG50= diff --git a/internal/database/seed/seeder.go b/internal/database/seed/seeder.go index 7c1f8a1e..d848711e 100644 --- a/internal/database/seed/seeder.go +++ b/internal/database/seed/seeder.go @@ -82,7 +82,7 @@ func Run(db *gorm.DB) error { return err } - if err := seedTransferStock(tx, adminID); err != nil { + if err := seedTransferStock(tx); err != nil { return err } fmt.Println("✅ Master data seeding completed") @@ -692,7 +692,7 @@ func seedProducts(tx *gorm.DB, createdBy uint, uoms map[string]uint, categories var existing entity.ProductSupplier err := tx.Where("product_id = ? AND supplier_id = ?", product.Id, supplierID).First(&existing).Error if errors.Is(err, gorm.ErrRecordNotFound) { - link := entity.ProductSupplier{ProductID: product.Id, SupplierID: supplierID} + link := entity.ProductSupplier{ProductId: product.Id, SupplierId: supplierID} if err := tx.Create(&link).Error; err != nil { return err } @@ -765,7 +765,7 @@ func seedNonstocks(tx *gorm.DB, createdBy uint, uoms map[string]uint, suppliers var existing entity.NonstockSupplier err := tx.Where("nonstock_id = ? AND supplier_id = ?", nonstock.Id, supplierID).First(&existing).Error if errors.Is(err, gorm.ErrRecordNotFound) { - link := entity.NonstockSupplier{NonstockID: nonstock.Id, SupplierID: supplierID} + link := entity.NonstockSupplier{NonstockId: nonstock.Id, SupplierId: supplierID} if err := tx.Create(&link).Error; err != nil { return err } @@ -929,7 +929,7 @@ func seedProductWarehouse(tx *gorm.DB, createdBy uint) error { return nil } -func seedTransferStock(tx *gorm.DB, createdBy uint) error { +func seedTransferStock(tx *gorm.DB) error { transfer := entity.StockTransfer{ FromWarehouseId: 1, diff --git a/internal/entities/nonstock.go b/internal/entities/nonstock.go index 3f291cc5..0e78ca8b 100644 --- a/internal/entities/nonstock.go +++ b/internal/entities/nonstock.go @@ -15,8 +15,8 @@ type Nonstock struct { UpdatedAt time.Time `gorm:"autoUpdateTime"` DeletedAt gorm.DeletedAt `gorm:"index" json:"-"` - CreatedUser User `gorm:"foreignKey:CreatedBy;references:Id"` - Uom Uom `gorm:"foreignKey:UomId;references:Id"` - Suppliers []Supplier `gorm:"many2many:nonstock_suppliers;joinForeignKey:NonstockID;joinReferences:SupplierID"` - Flags []Flag `gorm:"polymorphic:Flagable;polymorphicValue:nonstocks"` + CreatedUser User `gorm:"foreignKey:CreatedBy;references:Id"` + Uom Uom `gorm:"foreignKey:UomId;references:Id"` + NonstockSuppliers []NonstockSupplier `gorm:"foreignKey:NonstockId;references:Id"` + Flags []Flag `gorm:"polymorphic:Flagable;polymorphicValue:nonstocks"` } diff --git a/internal/entities/nonstock_supplier.go b/internal/entities/nonstock_supplier.go index 2d56a680..2206390c 100644 --- a/internal/entities/nonstock_supplier.go +++ b/internal/entities/nonstock_supplier.go @@ -3,7 +3,10 @@ package entities import "time" type NonstockSupplier struct { - NonstockID uint `gorm:"primaryKey"` - SupplierID uint `gorm:"primaryKey"` + NonstockId uint `gorm:"not null"` + SupplierId uint `gorm:"not null"` CreatedAt time.Time `gorm:"autoCreateTime"` + + Nonstock Nonstock `gorm:"foreignKey:NonstockId;references:Id"` + Supplier Supplier `gorm:"foreignKey:SupplierId;references:Id"` } diff --git a/internal/entities/product.go b/internal/entities/product.go index 120a018c..52b04627 100644 --- a/internal/entities/product.go +++ b/internal/entities/product.go @@ -22,9 +22,9 @@ type Product struct { UpdatedAt time.Time `gorm:"autoUpdateTime"` DeletedAt gorm.DeletedAt `gorm:"index" json:"-"` - CreatedUser User `gorm:"foreignKey:CreatedBy;references:Id"` - Uom Uom `gorm:"foreignKey:UomId;references:Id"` - ProductCategory ProductCategory `gorm:"foreignKey:ProductCategoryId;references:Id"` - Suppliers []Supplier `gorm:"many2many:product_suppliers;joinForeignKey:ProductID;joinReferences:SupplierID"` - Flags []Flag `gorm:"polymorphic:Flagable;polymorphicValue:products"` + CreatedUser User `gorm:"foreignKey:CreatedBy;references:Id"` + Uom Uom `gorm:"foreignKey:UomId;references:Id"` + ProductCategory ProductCategory `gorm:"foreignKey:ProductCategoryId;references:Id"` + ProductSuppliers []ProductSupplier `gorm:"foreignKey:ProductId;references:Id"` + Flags []Flag `gorm:"polymorphic:Flagable;polymorphicValue:products"` } diff --git a/internal/entities/product_supplier.go b/internal/entities/product_supplier.go index 9aa2deec..d64b1e85 100644 --- a/internal/entities/product_supplier.go +++ b/internal/entities/product_supplier.go @@ -3,7 +3,10 @@ package entities import "time" type ProductSupplier struct { - ProductID uint `gorm:"primaryKey"` - SupplierID uint `gorm:"primaryKey"` + ProductId uint `gorm:"not null"` + SupplierId uint `gorm:"not null"` CreatedAt time.Time `gorm:"autoCreateTime"` + + Product Product `gorm:"foreignKey:ProductId;references:Id"` + Supplier Supplier `gorm:"foreignKey:SupplierId;references:Id"` } diff --git a/internal/entities/supplier.go b/internal/entities/supplier.go index 141c4a58..7d801896 100644 --- a/internal/entities/supplier.go +++ b/internal/entities/supplier.go @@ -26,5 +26,7 @@ type Supplier struct { UpdatedAt time.Time `gorm:"autoUpdateTime"` DeletedAt gorm.DeletedAt `gorm:"index" json:"-"` - CreatedUser User `gorm:"foreignKey:CreatedBy;references:Id"` + CreatedUser User `gorm:"foreignKey:CreatedBy;references:Id"` + ProductSuppliers []ProductSupplier `gorm:"foreignKey:SupplierId;references:Id"` + NonstockSuppliers []NonstockSupplier `gorm:"foreignKey:SupplierId;references:Id"` } diff --git a/internal/modules/approvals/controllers/approval.controller.go b/internal/modules/approvals/controllers/approval.controller.go index fd0baa6e..94a66afd 100644 --- a/internal/modules/approvals/controllers/approval.controller.go +++ b/internal/modules/approvals/controllers/approval.controller.go @@ -85,7 +85,7 @@ func (u *ApprovalController) GetAll(c *fiber.Ctx) error { flat := dto.ToApprovalDTOs(records) return c.Status(fiber.StatusOK). - JSON(response.SuccessWithPaginate[dto.ApprovalBaseDTO]{ + JSON(response.SuccessWithPaginate[dto.ApprovalRelationDTO]{ Code: fiber.StatusOK, Status: "success", Message: "Get All approvals successfully", diff --git a/internal/modules/approvals/dto/approval.dto.go b/internal/modules/approvals/dto/approval.dto.go index 52b99fc6..0ef9f8d5 100644 --- a/internal/modules/approvals/dto/approval.dto.go +++ b/internal/modules/approvals/dto/approval.dto.go @@ -10,24 +10,24 @@ import ( approvalutils "gitlab.com/mbugroup/lti-api.git/internal/utils/approvals" ) -type ApprovalBaseDTO struct { - Id uint `json:"id"` - StepNumber uint16 `json:"step_number"` - StepName string `json:"step_name"` - Action *string `json:"action"` - Notes *string `json:"notes"` - ActionBy userDTO.UserBaseDTO `json:"action_by"` - ActionAt time.Time `json:"action_at"` +type ApprovalRelationDTO struct { + Id uint `json:"id"` + StepNumber uint16 `json:"step_number"` + StepName string `json:"step_name"` + Action *string `json:"action"` + Notes *string `json:"notes"` + ActionBy userDTO.UserRelationDTO `json:"action_by"` + ActionAt time.Time `json:"action_at"` } type ApprovalGroupDTO struct { - StepNumber uint16 `json:"step_number"` - StepName string `json:"step_name"` - Approvals []ApprovalBaseDTO `json:"approvals"` + StepNumber uint16 `json:"step_number"` + StepName string `json:"step_name"` + Approvals []ApprovalRelationDTO `json:"approvals"` } -func ToApprovalDTO(e entity.Approval) ApprovalBaseDTO { - dto := ApprovalBaseDTO{ +func ToApprovalDTO(e entity.Approval) ApprovalRelationDTO { + dto := ApprovalRelationDTO{ Id: e.Id, Notes: e.Notes, } @@ -54,10 +54,10 @@ func ToApprovalDTO(e entity.Approval) ApprovalBaseDTO { } if e.ActionUser != nil && e.ActionUser.Id != 0 { - user := userDTO.ToUserBaseDTO(*e.ActionUser) + user := userDTO.ToUserRelationDTO(*e.ActionUser) dto.ActionBy = user } else if e.ActionBy != nil && *e.ActionBy != 0 { - dto.ActionBy = userDTO.UserBaseDTO{ + dto.ActionBy = userDTO.UserRelationDTO{ Id: *e.ActionBy, IdUser: int64(*e.ActionBy), } @@ -71,8 +71,8 @@ func ToApprovalDTO(e entity.Approval) ApprovalBaseDTO { return dto } -func ToApprovalDTOs(items []entity.Approval) []ApprovalBaseDTO { - result := make([]ApprovalBaseDTO, len(items)) +func ToApprovalDTOs(items []entity.Approval) []ApprovalRelationDTO { + result := make([]ApprovalRelationDTO, len(items)) for i, item := range items { result[i] = ToApprovalDTO(item) } @@ -86,7 +86,7 @@ func ToApprovalGroupDTOs(items []entity.Approval) []ApprovalGroupDTO { type groupAccumulator struct { StepName string - Approvals []ApprovalBaseDTO + Approvals []ApprovalRelationDTO } groups := make(map[uint16]*groupAccumulator) diff --git a/internal/modules/expenses/dto/expense.dto.go b/internal/modules/expenses/dto/expense.dto.go index b5fca80f..21403ed9 100644 --- a/internal/modules/expenses/dto/expense.dto.go +++ b/internal/modules/expenses/dto/expense.dto.go @@ -9,7 +9,7 @@ import ( // === DTO Structs === -type ExpenseBaseDTO struct { +type ExpenseRelationDTO struct { Id uint64 `json:"id"` PoNumber string `json:"po_number"` ExpenseDate time.Time `json:"expense_date"` @@ -17,21 +17,21 @@ type ExpenseBaseDTO struct { } type ExpenseListDTO struct { - Id uint64 `json:"id"` - ReferenceNumber string `json:"reference_number"` - PoNumber string `json:"po_number"` - Category string `json:"category"` - ExpenseDate time.Time `json:"expense_date"` - GrandTotal float64 `json:"grand_total"` - CreatedUser *userDTO.UserBaseDTO `json:"created_user,omitempty"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` + Id uint64 `json:"id"` + ReferenceNumber string `json:"reference_number"` + PoNumber string `json:"po_number"` + Category string `json:"category"` + ExpenseDate time.Time `json:"expense_date"` + GrandTotal float64 `json:"grand_total"` + CreatedUser *userDTO.UserRelationDTO `json:"created_user,omitempty"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` } // === Mapper Functions === -func ToExpenseBaseDTO(e entity.Expense) ExpenseBaseDTO { - return ExpenseBaseDTO{ +func ToExpenseRelationDTO(e entity.Expense) ExpenseRelationDTO { + return ExpenseRelationDTO{ Id: e.Id, PoNumber: e.PoNumber, ExpenseDate: e.ExpenseDate, @@ -40,9 +40,9 @@ func ToExpenseBaseDTO(e entity.Expense) ExpenseBaseDTO { } func ToExpenseListDTO(e entity.Expense) ExpenseListDTO { - var createdUser *userDTO.UserBaseDTO + var createdUser *userDTO.UserRelationDTO if e.CreatedUser.Id != 0 { - mapped := userDTO.ToUserBaseDTO(*e.CreatedUser) + mapped := userDTO.ToUserRelationDTO(*e.CreatedUser) createdUser = &mapped } diff --git a/internal/modules/inventory/adjustments/dto/adjustment.dto.go b/internal/modules/inventory/adjustments/dto/adjustment.dto.go index d577e134..f91e6eda 100644 --- a/internal/modules/inventory/adjustments/dto/adjustment.dto.go +++ b/internal/modules/inventory/adjustments/dto/adjustment.dto.go @@ -10,28 +10,28 @@ import ( // === DTO Structs === -type ProductBaseDTO struct { - Id uint `json:"id"` - Name string `json:"name"` - SKU string `json:"sku"` - ProductCategory *productCategoryDTO.ProductCategoryBaseDTO `json:"product_category,omitempty"` +type ProductRelationDTO struct { + Id uint `json:"id"` + Name string `json:"name"` + SKU string `json:"sku"` + ProductCategory *productCategoryDTO.ProductCategoryRelationDTO `json:"product_category,omitempty"` } -type WarehouseBaseDTO struct { +type WarehouseRelationDTO struct { Id uint `json:"id"` Name string `json:"name"` } type ProductWarehouseDTO struct { - Id uint `json:"id"` - ProductId uint `json:"product_id"` - WarehouseId uint `json:"warehouse_id"` - Quantity float64 `json:"quantity"` - Product *ProductBaseDTO `json:"product,omitempty"` - Warehouse *WarehouseBaseDTO `json:"warehouse,omitempty"` + Id uint `json:"id"` + ProductId uint `json:"product_id"` + WarehouseId uint `json:"warehouse_id"` + Quantity float64 `json:"quantity"` + Product *ProductRelationDTO `json:"product,omitempty"` + Warehouse *WarehouseRelationDTO `json:"warehouse,omitempty"` } -type AdjustmentBaseDTO struct { +type AdjustmentRelationDTO struct { Id uint `json:"id"` TransactionType string `json:"transaction_type"` Quantity float64 `json:"quantity"` @@ -43,9 +43,9 @@ type AdjustmentBaseDTO struct { } type AdjustmentListDTO struct { - AdjustmentBaseDTO - CreatedUser *userDTO.UserBaseDTO `json:"created_user,omitempty"` - CreatedAt time.Time `json:"created_at"` + AdjustmentRelationDTO + CreatedUser *userDTO.UserRelationDTO `json:"created_user,omitempty"` + CreatedAt time.Time `json:"created_at"` } type AdjustmentDetailDTO struct { @@ -55,7 +55,7 @@ type AdjustmentDetailDTO struct { // === Mapper Functions === -func ToProductBaseDTO(e *entity.Product) *ProductBaseDTO { +func ToProductRelationDTO(e *entity.Product) *ProductRelationDTO { if e == nil { return nil } @@ -64,13 +64,13 @@ func ToProductBaseDTO(e *entity.Product) *ProductBaseDTO { sku = *e.Sku } - var category *productCategoryDTO.ProductCategoryBaseDTO + var category *productCategoryDTO.ProductCategoryRelationDTO if e.ProductCategory.Id != 0 { - mapped := productCategoryDTO.ToProductCategoryBaseDTO(e.ProductCategory) + mapped := productCategoryDTO.ToProductCategoryRelationDTO(e.ProductCategory) category = &mapped } - return &ProductBaseDTO{ + return &ProductRelationDTO{ Id: e.Id, Name: e.Name, SKU: sku, @@ -78,11 +78,11 @@ func ToProductBaseDTO(e *entity.Product) *ProductBaseDTO { } } -func ToWarehouseBaseDTO(e *entity.Warehouse) *WarehouseBaseDTO { +func ToWarehouseRelationDTO(e *entity.Warehouse) *WarehouseRelationDTO { if e == nil { return nil } - return &WarehouseBaseDTO{ + return &WarehouseRelationDTO{ Id: e.Id, Name: e.Name, } @@ -97,13 +97,13 @@ func ToProductWarehouseDTO(e *entity.ProductWarehouse) *ProductWarehouseDTO { ProductId: e.ProductId, WarehouseId: e.WarehouseId, Quantity: e.Quantity, - Product: ToProductBaseDTO(&e.Product), - Warehouse: ToWarehouseBaseDTO(&e.Warehouse), + Product: ToProductRelationDTO(&e.Product), + Warehouse: ToWarehouseRelationDTO(&e.Warehouse), } } -func ToAdjustmentBaseDTO(e *entity.StockLog) AdjustmentBaseDTO { - return AdjustmentBaseDTO{ +func ToAdjustmentRelationDTO(e *entity.StockLog) AdjustmentRelationDTO { + return AdjustmentRelationDTO{ Id: e.Id, TransactionType: e.TransactionType, Quantity: e.Quantity, @@ -116,9 +116,9 @@ func ToAdjustmentBaseDTO(e *entity.StockLog) AdjustmentBaseDTO { } func ToAdjustmentListDTO(e *entity.StockLog) AdjustmentListDTO { - var createdUser *userDTO.UserBaseDTO + var createdUser *userDTO.UserRelationDTO if e.CreatedUser != nil { - createdUser = &userDTO.UserBaseDTO{ + createdUser = &userDTO.UserRelationDTO{ Id: e.CreatedUser.Id, IdUser: e.CreatedUser.IdUser, Email: e.CreatedUser.Email, @@ -127,9 +127,9 @@ func ToAdjustmentListDTO(e *entity.StockLog) AdjustmentListDTO { } return AdjustmentListDTO{ - AdjustmentBaseDTO: ToAdjustmentBaseDTO(e), - CreatedUser: createdUser, - CreatedAt: e.CreatedAt, + AdjustmentRelationDTO: ToAdjustmentRelationDTO(e), + CreatedUser: createdUser, + CreatedAt: e.CreatedAt, } } diff --git a/internal/modules/inventory/product-warehouses/dto/product_warehouse.dto.go b/internal/modules/inventory/product-warehouses/dto/product_warehouse.dto.go index f88a6ca3..06889670 100644 --- a/internal/modules/inventory/product-warehouses/dto/product_warehouse.dto.go +++ b/internal/modules/inventory/product-warehouses/dto/product_warehouse.dto.go @@ -9,7 +9,7 @@ import ( // === DTO Structs === -type ProductWarehouseBaseDTO struct { +type ProductWarehouseRelationDTO struct { Id uint `json:"id"` ProductId uint `json:"product_id"` WarehouseId uint `json:"warehouse_id"` @@ -17,21 +17,21 @@ type ProductWarehouseBaseDTO struct { } type ProductWarehousNestedDTO struct { - Id uint `json:"id"` - Product *productDTO.ProductBaseDTO `json:"product,omitempty"` - Warehouse *WarehouseBaseDTO `json:"warehouse,omitempty"` + Id uint `json:"id"` + Product *productDTO.ProductRelationDTO `json:"product,omitempty"` + Warehouse *WarehouseRelationDTO `json:"warehouse,omitempty"` } type ProductWarehouseListDTO struct { - ProductWarehouseBaseDTO - Product *productDTO.ProductBaseDTO `json:"product,omitempty"` - Warehouse *WarehouseBaseDTO `json:"warehouse,omitempty"` - CreatedUser *UserBaseDTO `json:"created_user,omitempty"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` + ProductWarehouseRelationDTO + Product *productDTO.ProductRelationDTO `json:"product,omitempty"` + Warehouse *WarehouseRelationDTO `json:"warehouse,omitempty"` + CreatedUser *UserRelationDTO `json:"created_user,omitempty"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` } -type UserBaseDTO struct { +type UserRelationDTO struct { Id uint `json:"id"` Username string `json:"username"` } @@ -41,40 +41,40 @@ type ProductWarehouseDetailDTO struct { } // Nested DTOs for relations -type ProductBaseDTO struct { +type ProductRelationDTO struct { Id uint `json:"id"` Name string `json:"name"` Sku string `json:"sku"` Flags []string `json:"flags"` } -type WarehouseBaseDTO struct { - Id uint `json:"id"` - Name string `json:"name"` - Kandang *KandangBaseDTO `json:"kandang,omitempty"` - Location *LocationBaseDTO `json:"location,omitempty"` - Area *AreaBaseDTO `json:"area,omitempty"` +type WarehouseRelationDTO struct { + Id uint `json:"id"` + Name string `json:"name"` + Kandang *KandangRelationDTO `json:"kandang,omitempty"` + Location *LocationRelationDTO `json:"location,omitempty"` + Area *AreaRelationDTO `json:"area,omitempty"` } -type KandangBaseDTO struct { +type KandangRelationDTO struct { Id uint `json:"id"` Name string `json:"name"` } -type LocationBaseDTO struct { +type LocationRelationDTO struct { Id uint `json:"id"` Name string `json:"name"` } -type AreaBaseDTO struct { +type AreaRelationDTO struct { Id uint `json:"id"` Name string `json:"name"` } // === Mapper Functions === -func ToProductWarehouseBaseDTO(e entity.ProductWarehouse) ProductWarehouseBaseDTO { - return ProductWarehouseBaseDTO{ +func ToProductWarehouseRelationDTO(e entity.ProductWarehouse) ProductWarehouseRelationDTO { + return ProductWarehouseRelationDTO{ Id: e.Id, ProductId: e.ProductId, // Field yang benar dari entity WarehouseId: e.WarehouseId, // Field yang benar dari entity @@ -83,12 +83,12 @@ func ToProductWarehouseBaseDTO(e entity.ProductWarehouse) ProductWarehouseBaseDT } func ToProductWarehouseNestedDTO(e entity.ProductWarehouse) ProductWarehousNestedDTO { - product := productDTO.ToProductBaseDTO(e.Product) + product := productDTO.ToProductRelationDTO(e.Product) return ProductWarehousNestedDTO{ Id: e.Id, Product: &product, - Warehouse: &WarehouseBaseDTO{ + Warehouse: &WarehouseRelationDTO{ Id: e.Warehouse.Id, Name: e.Warehouse.Name, }, @@ -97,40 +97,40 @@ func ToProductWarehouseNestedDTO(e entity.ProductWarehouse) ProductWarehousNeste func ToProductWarehouseListDTO(e entity.ProductWarehouse) ProductWarehouseListDTO { dto := ProductWarehouseListDTO{ - ProductWarehouseBaseDTO: ToProductWarehouseBaseDTO(e), - CreatedAt: e.CreatedAt, - UpdatedAt: e.UpdatedAt, + ProductWarehouseRelationDTO: ToProductWarehouseRelationDTO(e), + CreatedAt: e.CreatedAt, + UpdatedAt: e.UpdatedAt, } // Map Product relation jika ada if e.Product.Id != 0 { - product := productDTO.ToProductBaseDTO(e.Product) + product := productDTO.ToProductRelationDTO(e.Product) dto.Product = &product } // Map Warehouse relation jika ada if e.Warehouse.Id != 0 { - warehouse := WarehouseBaseDTO{ + warehouse := WarehouseRelationDTO{ Id: e.Warehouse.Id, Name: e.Warehouse.Name, } // Map Kandang jika ada if e.Warehouse.Kandang != nil && e.Warehouse.Kandang.Id != 0 { - warehouse.Kandang = &KandangBaseDTO{ + warehouse.Kandang = &KandangRelationDTO{ Id: e.Warehouse.Kandang.Id, Name: e.Warehouse.Kandang.Name, } } // Map Location jika ada if e.Warehouse.Location != nil && e.Warehouse.Location.Id != 0 { - warehouse.Location = &LocationBaseDTO{ + warehouse.Location = &LocationRelationDTO{ Id: e.Warehouse.Location.Id, Name: e.Warehouse.Location.Name, } } if e.Warehouse.Area.Id != 0 { - warehouse.Area = &AreaBaseDTO{ + warehouse.Area = &AreaRelationDTO{ Id: e.Warehouse.Area.Id, Name: e.Warehouse.Area.Name, } @@ -141,7 +141,7 @@ func ToProductWarehouseListDTO(e entity.ProductWarehouse) ProductWarehouseListDT // Map CreatedUser relation jika ada if e.CreatedUser.Id != 0 { - user := UserBaseDTO{ + user := UserRelationDTO{ Id: e.CreatedUser.Id, Username: e.CreatedUser.Name, } @@ -165,22 +165,22 @@ func ToProductWarehouseDetailDTO(e entity.ProductWarehouse) ProductWarehouseDeta } } -func ToKandangBaseDTO(e entity.Kandang) KandangBaseDTO { - return KandangBaseDTO{ +func ToKandangRelationDTO(e entity.Kandang) KandangRelationDTO { + return KandangRelationDTO{ Id: e.Id, Name: e.Name, } } -func ToLocationBaseDTO(e entity.Location) LocationBaseDTO { - return LocationBaseDTO{ +func ToLocationRelationDTO(e entity.Location) LocationRelationDTO { + return LocationRelationDTO{ Id: e.Id, Name: e.Name, } } -func ToAreaBaseDTO(e entity.Area) AreaBaseDTO { - return AreaBaseDTO{ +func ToAreaRelationDTO(e entity.Area) AreaRelationDTO { + return AreaRelationDTO{ Id: e.Id, Name: e.Name, } diff --git a/internal/modules/inventory/transfers/dto/transfer.dto.go b/internal/modules/inventory/transfers/dto/transfer.dto.go index cb85af94..fe97ce0f 100644 --- a/internal/modules/inventory/transfers/dto/transfer.dto.go +++ b/internal/modules/inventory/transfers/dto/transfer.dto.go @@ -9,7 +9,7 @@ import ( // === DTO Structs === -type TransferBaseDTO struct { +type TransferRelationDTO struct { Id uint64 `json:"id"` TransferReason string `json:"transfer_reason"` TransferDate string `json:"transfer_date"` @@ -51,12 +51,12 @@ type WarehouseDetailDTO struct { } type TransferListDTO struct { - TransferBaseDTO - CreatedUser *userDTO.UserBaseDTO `json:"created_user,omitempty"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` - Details []TransferDetailItemDTO `json:"details"` - Deliveries []TransferDeliveryDTO `json:"deliveries"` + TransferRelationDTO + CreatedUser *userDTO.UserRelationDTO `json:"created_user,omitempty"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + Details []TransferDetailItemDTO `json:"details"` + Deliveries []TransferDeliveryDTO `json:"deliveries"` } type TransferDetailDTO struct { @@ -93,7 +93,7 @@ type TransferDeliveryItemDTO struct { // === Mapper Functions === -func ToTransferBaseDTO(e entity.StockTransfer) TransferBaseDTO { +func ToTransferRelationDTO(e entity.StockTransfer) TransferRelationDTO { var sourceWarehouse *WarehouseDetailDTO if e.FromWarehouse != nil && e.FromWarehouse.Id != 0 { @@ -103,7 +103,7 @@ func ToTransferBaseDTO(e entity.StockTransfer) TransferBaseDTO { if e.ToWarehouse != nil && e.ToWarehouse.Id != 0 { destinationWarehouse = toWarehouseDetailDTO(e.ToWarehouse) } - return TransferBaseDTO{ + return TransferRelationDTO{ Id: e.Id, TransferReason: e.Reason, TransferDate: e.CreatedAt.Format("2006-01-02"), @@ -145,9 +145,9 @@ func toWarehouseDetailDTO(w *entity.Warehouse) *WarehouseDetailDTO { } func ToTransferListDTO(e entity.StockTransfer) TransferListDTO { - var createdUser *userDTO.UserBaseDTO + var createdUser *userDTO.UserRelationDTO if e.CreatedUser != nil { - mapped := userDTO.ToUserBaseDTO(*e.CreatedUser) + mapped := userDTO.ToUserRelationDTO(*e.CreatedUser) createdUser = &mapped } // Map details @@ -190,12 +190,12 @@ func ToTransferListDTO(e entity.StockTransfer) TransferListDTO { }) } return TransferListDTO{ - TransferBaseDTO: ToTransferBaseDTO(e), - CreatedUser: createdUser, - CreatedAt: e.CreatedAt, - UpdatedAt: e.UpdatedAt, - Details: details, - Deliveries: deliveries, + TransferRelationDTO: ToTransferRelationDTO(e), + CreatedUser: createdUser, + CreatedAt: e.CreatedAt, + UpdatedAt: e.UpdatedAt, + Details: details, + Deliveries: deliveries, } } diff --git a/internal/modules/marketing/delivery-orderss/dto/delivery-orders.dto.go b/internal/modules/marketing/delivery-orderss/dto/delivery-orders.dto.go index 397bf0ef..b3ac5a05 100644 --- a/internal/modules/marketing/delivery-orderss/dto/delivery-orders.dto.go +++ b/internal/modules/marketing/delivery-orderss/dto/delivery-orders.dto.go @@ -12,7 +12,7 @@ import ( userDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/users/dto" ) -type MarketingBaseDTO struct { +type MarketingRelationDTO struct { Id uint `json:"id"` SoNumber string `json:"so_number"` SoDate time.Time `json:"so_date"` @@ -20,28 +20,28 @@ type MarketingBaseDTO struct { } type MarketingListDTO struct { - MarketingBaseDTO - Customer *customerDTO.CustomerBaseDTO `json:"customer,omitempty"` - SalesPerson *userDTO.UserBaseDTO `json:"sales_person,omitempty"` - SoDocs string `json:"so_docs,omitempty"` - SalesOrder []MarketingProductDTO `json:"sales_order,omitempty"` - CreatedUser *userDTO.UserBaseDTO `json:"created_user"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` - LatestApproval *approvalDTO.ApprovalBaseDTO `json:"latest_approval,omitempty"` + MarketingRelationDTO + Customer *customerDTO.CustomerRelationDTO `json:"customer,omitempty"` + SalesPerson *userDTO.UserRelationDTO `json:"sales_person,omitempty"` + SoDocs string `json:"so_docs,omitempty"` + SalesOrder []MarketingProductDTO `json:"sales_order,omitempty"` + CreatedUser *userDTO.UserRelationDTO `json:"created_user"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + LatestApproval *approvalDTO.ApprovalRelationDTO `json:"latest_approval,omitempty"` } type MarketingDetailDTO struct { - MarketingBaseDTO - Customer *customerDTO.CustomerBaseDTO `json:"customer,omitempty"` - SalesPerson *userDTO.UserBaseDTO `json:"sales_person,omitempty"` - SoDocs string `json:"so_docs,omitempty"` - SalesOrder []MarketingProductDTO `json:"sales_order,omitempty"` - DeliveryOrder []DeliveryGroupDTO `json:"delivery_order,omitempty"` - CreatedUser *userDTO.UserBaseDTO `json:"created_user"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` - LatestApproval *approvalDTO.ApprovalBaseDTO `json:"latest_approval,omitempty"` + MarketingRelationDTO + Customer *customerDTO.CustomerRelationDTO `json:"customer,omitempty"` + SalesPerson *userDTO.UserRelationDTO `json:"sales_person,omitempty"` + SoDocs string `json:"so_docs,omitempty"` + SalesOrder []MarketingProductDTO `json:"sales_order,omitempty"` + DeliveryOrder []DeliveryGroupDTO `json:"delivery_order,omitempty"` + CreatedUser *userDTO.UserRelationDTO `json:"created_user"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + LatestApproval *approvalDTO.ApprovalRelationDTO `json:"latest_approval,omitempty"` } type MarketingDeliveryProductDTO struct { Id uint `json:"id"` @@ -67,10 +67,10 @@ type DeliveryItemDTO struct { } type DeliveryGroupDTO struct { - DoNumber string `json:"do_number"` - DeliveryDate *time.Time `json:"delivery_date"` - Warehouse *productwarehouseDTO.WarehouseBaseDTO `json:"warehouse,omitempty"` - Deliveries []DeliveryItemDTO `json:"deliveries"` + DoNumber string `json:"do_number"` + DeliveryDate *time.Time `json:"delivery_date"` + Warehouse *productwarehouseDTO.WarehouseRelationDTO `json:"warehouse,omitempty"` + Deliveries []DeliveryItemDTO `json:"deliveries"` } type MarketingProductDTO struct { @@ -86,8 +86,8 @@ type MarketingProductDTO struct { VehicleNumber string `json:"vehicle_number,omitempty"` } -func ToMarketingBaseDTO(marketing *entity.Marketing) MarketingBaseDTO { - return MarketingBaseDTO{ +func ToMarketingRelationDTO(marketing *entity.Marketing) MarketingRelationDTO { + return MarketingRelationDTO{ Id: marketing.Id, SoNumber: marketing.SoNumber, SoDate: marketing.SoDate, @@ -131,25 +131,25 @@ func ToMarketingDeliveryProductDTO(e entity.MarketingDeliveryProduct) MarketingD } func ToMarketingListDTO(marketing *entity.Marketing, deliveryProducts []entity.MarketingDeliveryProduct) MarketingListDTO { - var createdUser *userDTO.UserBaseDTO + var createdUser *userDTO.UserRelationDTO if marketing.CreatedUser.Id != 0 { - mapped := userDTO.ToUserBaseDTO(marketing.CreatedUser) + mapped := userDTO.ToUserRelationDTO(marketing.CreatedUser) createdUser = &mapped } - var customer *customerDTO.CustomerBaseDTO + var customer *customerDTO.CustomerRelationDTO if marketing.Customer.Id != 0 { - mapped := customerDTO.ToCustomerBaseDTO(marketing.Customer) + mapped := customerDTO.ToCustomerRelationDTO(marketing.Customer) customer = &mapped } - var salesPerson *userDTO.UserBaseDTO + var salesPerson *userDTO.UserRelationDTO if marketing.SalesPerson.Id != 0 { - mapped := userDTO.ToUserBaseDTO(marketing.SalesPerson) + mapped := userDTO.ToUserRelationDTO(marketing.SalesPerson) salesPerson = &mapped } - var latestApproval *approvalDTO.ApprovalBaseDTO + var latestApproval *approvalDTO.ApprovalRelationDTO if marketing.LatestApproval != nil { mapped := approvalDTO.ToApprovalDTO(*marketing.LatestApproval) latestApproval = &mapped @@ -164,34 +164,34 @@ func ToMarketingListDTO(marketing *entity.Marketing, deliveryProducts []entity.M } return MarketingListDTO{ - MarketingBaseDTO: ToMarketingBaseDTO(marketing), - Customer: customer, - SalesPerson: salesPerson, - SoDocs: marketing.SoDocs, - SalesOrder: salesOrderProducts, - CreatedUser: createdUser, - CreatedAt: marketing.CreatedAt, - UpdatedAt: marketing.UpdatedAt, - LatestApproval: latestApproval, + MarketingRelationDTO: ToMarketingRelationDTO(marketing), + Customer: customer, + SalesPerson: salesPerson, + SoDocs: marketing.SoDocs, + SalesOrder: salesOrderProducts, + CreatedUser: createdUser, + CreatedAt: marketing.CreatedAt, + UpdatedAt: marketing.UpdatedAt, + LatestApproval: latestApproval, } } func ToMarketingDetailDTO(marketing *entity.Marketing, deliveryProducts []entity.MarketingDeliveryProduct) MarketingDetailDTO { - var createdUser *userDTO.UserBaseDTO + var createdUser *userDTO.UserRelationDTO if marketing.CreatedUser.Id != 0 { - mapped := userDTO.ToUserBaseDTO(marketing.CreatedUser) + mapped := userDTO.ToUserRelationDTO(marketing.CreatedUser) createdUser = &mapped } - var customer *customerDTO.CustomerBaseDTO + var customer *customerDTO.CustomerRelationDTO if marketing.Customer.Id != 0 { - mapped := customerDTO.ToCustomerBaseDTO(marketing.Customer) + mapped := customerDTO.ToCustomerRelationDTO(marketing.Customer) customer = &mapped } - var salesPerson *userDTO.UserBaseDTO + var salesPerson *userDTO.UserRelationDTO if marketing.SalesPerson.Id != 0 { - mapped := userDTO.ToUserBaseDTO(marketing.SalesPerson) + mapped := userDTO.ToUserRelationDTO(marketing.SalesPerson) salesPerson = &mapped } @@ -214,23 +214,23 @@ func ToMarketingDetailDTO(marketing *entity.Marketing, deliveryProducts []entity deliveryGroups := groupDeliveryProducts(deliveryProductsDTOs, marketing.SoNumber) - var latestApproval *approvalDTO.ApprovalBaseDTO + var latestApproval *approvalDTO.ApprovalRelationDTO if marketing.LatestApproval != nil { mapped := approvalDTO.ToApprovalDTO(*marketing.LatestApproval) latestApproval = &mapped } return MarketingDetailDTO{ - MarketingBaseDTO: ToMarketingBaseDTO(marketing), - SoDocs: marketing.SoDocs, - Customer: customer, - SalesPerson: salesPerson, - SalesOrder: salesOrderProducts, - DeliveryOrder: deliveryGroups, - CreatedUser: createdUser, - CreatedAt: marketing.CreatedAt, - UpdatedAt: marketing.UpdatedAt, - LatestApproval: latestApproval, + MarketingRelationDTO: ToMarketingRelationDTO(marketing), + SoDocs: marketing.SoDocs, + Customer: customer, + SalesPerson: salesPerson, + SalesOrder: salesOrderProducts, + DeliveryOrder: deliveryGroups, + CreatedUser: createdUser, + CreatedAt: marketing.CreatedAt, + UpdatedAt: marketing.UpdatedAt, + LatestApproval: latestApproval, } } @@ -285,7 +285,7 @@ func groupDeliveryProducts(products []MarketingDeliveryProductDTO, soNumber stri if !exists { group = &DeliveryGroupDTO{ DeliveryDate: product.DeliveryDate, - Warehouse: &productwarehouseDTO.WarehouseBaseDTO{ + Warehouse: &productwarehouseDTO.WarehouseRelationDTO{ Id: warehouseId, Name: warehouseName, }, diff --git a/internal/modules/master/areas/dto/area.dto.go b/internal/modules/master/areas/dto/area.dto.go index eceff7a9..a3e08607 100644 --- a/internal/modules/master/areas/dto/area.dto.go +++ b/internal/modules/master/areas/dto/area.dto.go @@ -9,16 +9,16 @@ import ( // === DTO Structs === -type AreaBaseDTO struct { +type AreaRelationDTO struct { Id uint `json:"id"` Name string `json:"name"` } type AreaListDTO struct { - AreaBaseDTO - CreatedUser *userDTO.UserBaseDTO `json:"created_user"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` + AreaRelationDTO + CreatedUser *userDTO.UserRelationDTO `json:"created_user"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` } type AreaDetailDTO struct { @@ -27,25 +27,25 @@ type AreaDetailDTO struct { // === Mapper Functions === -func ToAreaBaseDTO(e entity.Area) AreaBaseDTO { - return AreaBaseDTO{ +func ToAreaRelationDTO(e entity.Area) AreaRelationDTO { + return AreaRelationDTO{ Id: e.Id, Name: e.Name, } } func ToAreaListDTO(e entity.Area) AreaListDTO { - var createdUser *userDTO.UserBaseDTO + var createdUser *userDTO.UserRelationDTO if e.CreatedUser.Id != 0 { - mapped := userDTO.ToUserBaseDTO(e.CreatedUser) + mapped := userDTO.ToUserRelationDTO(e.CreatedUser) createdUser = &mapped } return AreaListDTO{ - AreaBaseDTO: ToAreaBaseDTO(e), - CreatedUser: createdUser, - CreatedAt: e.CreatedAt, - UpdatedAt: e.UpdatedAt, + AreaRelationDTO: ToAreaRelationDTO(e), + CreatedUser: createdUser, + CreatedAt: e.CreatedAt, + UpdatedAt: e.UpdatedAt, } } diff --git a/internal/modules/master/banks/dto/bank.dto.go b/internal/modules/master/banks/dto/bank.dto.go index 415c5f6b..d440b197 100644 --- a/internal/modules/master/banks/dto/bank.dto.go +++ b/internal/modules/master/banks/dto/bank.dto.go @@ -9,7 +9,7 @@ import ( // === DTO Structs === -type BankBaseDTO struct { +type BankRelationDTO struct { Id uint `json:"id"` Name string `json:"name"` Alias string `json:"alias"` @@ -18,10 +18,10 @@ type BankBaseDTO struct { } type BankListDTO struct { - BankBaseDTO - CreatedUser *userDTO.UserBaseDTO `json:"created_user"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` + BankRelationDTO + CreatedUser *userDTO.UserRelationDTO `json:"created_user"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` } type BankDetailDTO struct { @@ -30,8 +30,8 @@ type BankDetailDTO struct { // === Mapper Functions === -func ToBankBaseDTO(e entity.Bank) BankBaseDTO { - return BankBaseDTO{ +func ToBankRelationDTO(e entity.Bank) BankRelationDTO { + return BankRelationDTO{ Id: e.Id, Name: e.Name, Alias: e.Alias, @@ -41,17 +41,17 @@ func ToBankBaseDTO(e entity.Bank) BankBaseDTO { } func ToBankListDTO(e entity.Bank) BankListDTO { - var createdUser *userDTO.UserBaseDTO + var createdUser *userDTO.UserRelationDTO if e.CreatedUser.Id != 0 { - mapped := userDTO.ToUserBaseDTO(e.CreatedUser) + mapped := userDTO.ToUserRelationDTO(e.CreatedUser) createdUser = &mapped } return BankListDTO{ - BankBaseDTO: ToBankBaseDTO(e), - CreatedAt: e.CreatedAt, - UpdatedAt: e.UpdatedAt, - CreatedUser: createdUser, + BankRelationDTO: ToBankRelationDTO(e), + CreatedAt: e.CreatedAt, + UpdatedAt: e.UpdatedAt, + CreatedUser: createdUser, } } diff --git a/internal/modules/master/customers/dto/customer.dto.go b/internal/modules/master/customers/dto/customer.dto.go index e1fb8d0d..333c1297 100644 --- a/internal/modules/master/customers/dto/customer.dto.go +++ b/internal/modules/master/customers/dto/customer.dto.go @@ -9,7 +9,7 @@ import ( // === DTO Structs === -type CustomerBaseDTO struct { +type CustomerRelationDTO struct { Id uint `json:"id"` Name string `json:"name"` PicId uint `json:"pic_id"` @@ -20,14 +20,14 @@ type CustomerBaseDTO struct { AccountNumber string `json:"account_number"` Balance float64 `json:"balance"` - Pic *userDTO.UserBaseDTO `json:"pic,omitempty"` + Pic *userDTO.UserRelationDTO `json:"pic,omitempty"` } type CustomerListDTO struct { - CustomerBaseDTO - CreatedUser *userDTO.UserBaseDTO `json:"created_user"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` + CustomerRelationDTO + CreatedUser *userDTO.UserRelationDTO `json:"created_user"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` } type CustomerDetailDTO struct { @@ -36,14 +36,14 @@ type CustomerDetailDTO struct { // === Mapper Functions === -func ToCustomerBaseDTO(e entity.Customer) CustomerBaseDTO { - var pic *userDTO.UserBaseDTO +func ToCustomerRelationDTO(e entity.Customer) CustomerRelationDTO { + var pic *userDTO.UserRelationDTO if e.Pic.Id != 0 { - mapped := userDTO.ToUserBaseDTO(e.Pic) + mapped := userDTO.ToUserRelationDTO(e.Pic) pic = &mapped } - return CustomerBaseDTO{ + return CustomerRelationDTO{ Id: e.Id, Name: e.Name, PicId: e.PicId, @@ -57,17 +57,17 @@ func ToCustomerBaseDTO(e entity.Customer) CustomerBaseDTO { } func ToCustomerListDTO(e entity.Customer) CustomerListDTO { - var createdUser *userDTO.UserBaseDTO + var createdUser *userDTO.UserRelationDTO if e.CreatedUser.Id != 0 { - mapped := userDTO.ToUserBaseDTO(e.CreatedUser) + mapped := userDTO.ToUserRelationDTO(e.CreatedUser) createdUser = &mapped } return CustomerListDTO{ - CustomerBaseDTO: ToCustomerBaseDTO(e), - CreatedAt: e.CreatedAt, - UpdatedAt: e.UpdatedAt, - CreatedUser: createdUser, + CustomerRelationDTO: ToCustomerRelationDTO(e), + CreatedAt: e.CreatedAt, + UpdatedAt: e.UpdatedAt, + CreatedUser: createdUser, } } diff --git a/internal/modules/master/fcrs/dto/fcr.dto.go b/internal/modules/master/fcrs/dto/fcr.dto.go index c88bb1a5..7b2a4e68 100644 --- a/internal/modules/master/fcrs/dto/fcr.dto.go +++ b/internal/modules/master/fcrs/dto/fcr.dto.go @@ -9,7 +9,7 @@ import ( // === DTO Structs === -type FcrBaseDTO struct { +type FcrRelationDTO struct { Id uint `json:"id"` Name string `json:"name"` } @@ -22,10 +22,10 @@ type FcrStandardDTO struct { } type FcrListDTO struct { - FcrBaseDTO - CreatedUser *userDTO.UserBaseDTO `json:"created_user"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` + FcrRelationDTO + CreatedUser *userDTO.UserRelationDTO `json:"created_user"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` } type FcrDetailDTO struct { @@ -35,25 +35,25 @@ type FcrDetailDTO struct { // === Mapper Functions === -func ToFcrBaseDTO(e entity.Fcr) FcrBaseDTO { - return FcrBaseDTO{ +func ToFcrRelationDTO(e entity.Fcr) FcrRelationDTO { + return FcrRelationDTO{ Id: e.Id, Name: e.Name, } } func ToFcrListDTO(e entity.Fcr) FcrListDTO { - var createdUser *userDTO.UserBaseDTO + var createdUser *userDTO.UserRelationDTO if e.CreatedUser.Id != 0 { - mapped := userDTO.ToUserBaseDTO(e.CreatedUser) + mapped := userDTO.ToUserRelationDTO(e.CreatedUser) createdUser = &mapped } return FcrListDTO{ - FcrBaseDTO: ToFcrBaseDTO(e), - CreatedAt: e.CreatedAt, - UpdatedAt: e.UpdatedAt, - CreatedUser: createdUser, + FcrRelationDTO: ToFcrRelationDTO(e), + CreatedAt: e.CreatedAt, + UpdatedAt: e.UpdatedAt, + CreatedUser: createdUser, } } diff --git a/internal/modules/master/flocks/dto/flock.dto.go b/internal/modules/master/flocks/dto/flock.dto.go index 8038ddb0..d5a44ee2 100644 --- a/internal/modules/master/flocks/dto/flock.dto.go +++ b/internal/modules/master/flocks/dto/flock.dto.go @@ -9,16 +9,16 @@ import ( // === DTO Structs === -type FlockBaseDTO struct { +type FlockRelationDTO struct { Id uint `json:"id"` Name string `json:"name"` } type FlockListDTO struct { - FlockBaseDTO - CreatedUser *userDTO.UserBaseDTO `json:"created_user"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` + FlockRelationDTO + CreatedUser *userDTO.UserRelationDTO `json:"created_user"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` } type FlockDetailDTO struct { @@ -27,25 +27,25 @@ type FlockDetailDTO struct { // === Mapper Functions === -func ToFlockBaseDTO(e entity.Flock) FlockBaseDTO { - return FlockBaseDTO{ +func ToFlockRelationDTO(e entity.Flock) FlockRelationDTO { + return FlockRelationDTO{ Id: e.Id, Name: e.Name, } } func ToFlockListDTO(e entity.Flock) FlockListDTO { - var createdUser *userDTO.UserBaseDTO + var createdUser *userDTO.UserRelationDTO if e.CreatedUser.Id != 0 { - mapped := userDTO.ToUserBaseDTO(e.CreatedUser) + mapped := userDTO.ToUserRelationDTO(e.CreatedUser) createdUser = &mapped } return FlockListDTO{ - FlockBaseDTO: ToFlockBaseDTO(e), - CreatedAt: e.CreatedAt, - UpdatedAt: e.UpdatedAt, - CreatedUser: createdUser, + FlockRelationDTO: ToFlockRelationDTO(e), + CreatedAt: e.CreatedAt, + UpdatedAt: e.UpdatedAt, + CreatedUser: createdUser, } } diff --git a/internal/modules/master/kandangs/dto/kandang.dto.go b/internal/modules/master/kandangs/dto/kandang.dto.go index 5e775c68..9f99d5fa 100644 --- a/internal/modules/master/kandangs/dto/kandang.dto.go +++ b/internal/modules/master/kandangs/dto/kandang.dto.go @@ -10,25 +10,25 @@ import ( // === DTO Structs === -type KandangBaseDTO struct { - Id uint `json:"id"` - Name string `json:"name"` - Status string `json:"status"` - Capacity float64 `json:"capacity"` - Location locationDTO.LocationBaseDTO `json:"location,omitempty"` - Pic userDTO.UserBaseDTO `json:"pic,omitempty"` +type KandangRelationDTO struct { + Id uint `json:"id"` + Name string `json:"name"` + Status string `json:"status"` + Capacity float64 `json:"capacity"` + Location locationDTO.LocationRelationDTO `json:"location,omitempty"` + Pic userDTO.UserRelationDTO `json:"pic,omitempty"` } type KandangListDTO struct { - Id uint `json:"id"` - Name string `json:"name"` - Status string `json:"status"` - Capacity float64 `json:"capacity"` - Location locationDTO.LocationBaseDTO `json:"location"` - Pic userDTO.UserBaseDTO `json:"pic"` - CreatedUser userDTO.UserBaseDTO `json:"created_user"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` + Id uint `json:"id"` + Name string `json:"name"` + Status string `json:"status"` + Capacity float64 `json:"capacity"` + Location locationDTO.LocationRelationDTO `json:"location"` + Pic userDTO.UserRelationDTO `json:"pic"` + CreatedUser userDTO.UserRelationDTO `json:"created_user"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` } type KandangDetailDTO struct { @@ -37,20 +37,20 @@ type KandangDetailDTO struct { // === Mapper Functions === -func ToKandangBaseDTO(e entity.Kandang) KandangBaseDTO { - var location locationDTO.LocationBaseDTO +func ToKandangRelationDTO(e entity.Kandang) KandangRelationDTO { + var location locationDTO.LocationRelationDTO if e.Location.Id != 0 { - mapped := locationDTO.ToLocationBaseDTO(e.Location) + mapped := locationDTO.ToLocationRelationDTO(e.Location) location = mapped } - var pic userDTO.UserBaseDTO + var pic userDTO.UserRelationDTO if e.Pic.Id != 0 { - mapped := userDTO.ToUserBaseDTO(e.Pic) + mapped := userDTO.ToUserRelationDTO(e.Pic) pic = mapped } - return KandangBaseDTO{ + return KandangRelationDTO{ Id: e.Id, Name: e.Name, Status: e.Status, @@ -61,21 +61,21 @@ func ToKandangBaseDTO(e entity.Kandang) KandangBaseDTO { } func ToKandangListDTO(e entity.Kandang) KandangListDTO { - var location locationDTO.LocationBaseDTO + var location locationDTO.LocationRelationDTO if e.Location.Id != 0 { - mapped := locationDTO.ToLocationBaseDTO(e.Location) + mapped := locationDTO.ToLocationRelationDTO(e.Location) location = mapped } - var pic userDTO.UserBaseDTO + var pic userDTO.UserRelationDTO if e.Pic.Id != 0 { - mapped := userDTO.ToUserBaseDTO(e.Pic) + mapped := userDTO.ToUserRelationDTO(e.Pic) pic = mapped } - var createdUser userDTO.UserBaseDTO + var createdUser userDTO.UserRelationDTO if e.CreatedUser.Id != 0 { - mapped := userDTO.ToUserBaseDTO(e.CreatedUser) + mapped := userDTO.ToUserRelationDTO(e.CreatedUser) createdUser = mapped } diff --git a/internal/modules/master/locations/dto/location.dto.go b/internal/modules/master/locations/dto/location.dto.go index d5d5b26e..ce3d5821 100644 --- a/internal/modules/master/locations/dto/location.dto.go +++ b/internal/modules/master/locations/dto/location.dto.go @@ -10,21 +10,21 @@ import ( // === DTO Structs === -type LocationBaseDTO struct { - Id uint `json:"id"` - Name string `json:"name"` - Address string `json:"address"` - Area *areaDTO.AreaBaseDTO `json:"area,omitempty"` +type LocationRelationDTO struct { + Id uint `json:"id"` + Name string `json:"name"` + Address string `json:"address"` + Area *areaDTO.AreaRelationDTO `json:"area,omitempty"` } type LocationListDTO struct { - Id uint `json:"id"` - Name string `json:"name"` - Address string `json:"address"` - Area *areaDTO.AreaBaseDTO `json:"area"` - CreatedUser *userDTO.UserBaseDTO `json:"created_user"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` + Id uint `json:"id"` + Name string `json:"name"` + Address string `json:"address"` + Area *areaDTO.AreaRelationDTO `json:"area"` + CreatedUser *userDTO.UserRelationDTO `json:"created_user"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` } type LocationDetailDTO struct { @@ -33,14 +33,14 @@ type LocationDetailDTO struct { // === Mapper Functions === -func ToLocationBaseDTO(e entity.Location) LocationBaseDTO { - var area *areaDTO.AreaBaseDTO +func ToLocationRelationDTO(e entity.Location) LocationRelationDTO { + var area *areaDTO.AreaRelationDTO if e.Area.Id != 0 { - mapped := areaDTO.ToAreaBaseDTO(e.Area) + mapped := areaDTO.ToAreaRelationDTO(e.Area) area = &mapped } - return LocationBaseDTO{ + return LocationRelationDTO{ Id: e.Id, Name: e.Name, Address: e.Address, @@ -49,15 +49,15 @@ func ToLocationBaseDTO(e entity.Location) LocationBaseDTO { } func ToLocationListDTO(e entity.Location) LocationListDTO { - var createdUser *userDTO.UserBaseDTO + var createdUser *userDTO.UserRelationDTO if e.CreatedUser.Id != 0 { - mapped := userDTO.ToUserBaseDTO(e.CreatedUser) + mapped := userDTO.ToUserRelationDTO(e.CreatedUser) createdUser = &mapped } - var area *areaDTO.AreaBaseDTO + var area *areaDTO.AreaRelationDTO if e.Area.Id != 0 { - mapped := areaDTO.ToAreaBaseDTO(e.Area) + mapped := areaDTO.ToAreaRelationDTO(e.Area) area = &mapped } diff --git a/internal/modules/master/nonstocks/dto/nonstock.dto.go b/internal/modules/master/nonstocks/dto/nonstock.dto.go index fb30b6cf..dd187230 100644 --- a/internal/modules/master/nonstocks/dto/nonstock.dto.go +++ b/internal/modules/master/nonstocks/dto/nonstock.dto.go @@ -4,41 +4,39 @@ import ( "time" entity "gitlab.com/mbugroup/lti-api.git/internal/entities" - supplierDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/suppliers/dto" uomDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/uoms/dto" userDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/users/dto" ) // === DTO Structs === -type NonstockBaseDTO struct { - Id uint `json:"id"` - Name string `json:"name"` - Uom *uomDTO.UomBaseDTO `json:"uom,omitempty"` - Flags []string `json:"flags"` +type NonstockRelationDTO struct { + Id uint `json:"id"` + Name string `json:"name"` + Uom *uomDTO.UomRelationDTO `json:"uom,omitempty"` + Flags []string `json:"flags"` } type NonstockListDTO struct { - Id uint `json:"id"` - Name string `json:"name"` - Uom *uomDTO.UomBaseDTO `json:"uom"` - Suppliers []supplierDTO.SupplierBaseDTO `json:"suppliers"` - CreatedUser *userDTO.UserBaseDTO `json:"created_user"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` + Id uint `json:"id"` + Name string `json:"name"` + Flags []string `json:"flags"` + Uom *uomDTO.UomRelationDTO `json:"uom"` + CreatedUser *userDTO.UserRelationDTO `json:"created_user"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` } type NonstockDetailDTO struct { NonstockListDTO - Flags []string `json:"flags"` } // === Mapper Functions === -func ToNonstockBaseDTO(e entity.Nonstock) NonstockBaseDTO { - var uomRef *uomDTO.UomBaseDTO +func ToNonstockRelationDTO(e entity.Nonstock) NonstockRelationDTO { + var uomRef *uomDTO.UomRelationDTO if e.Uom.Id != 0 { - mapped := uomDTO.ToUomBaseDTO(e.Uom) + mapped := uomDTO.ToUomRelationDTO(e.Uom) uomRef = &mapped } @@ -47,7 +45,7 @@ func ToNonstockBaseDTO(e entity.Nonstock) NonstockBaseDTO { flags[i] = f.Name } - return NonstockBaseDTO{ + return NonstockRelationDTO{ Id: e.Id, Name: e.Name, Uom: uomRef, @@ -56,23 +54,18 @@ func ToNonstockBaseDTO(e entity.Nonstock) NonstockBaseDTO { } func ToNonstockListDTO(e entity.Nonstock) NonstockListDTO { - var createdUser *userDTO.UserBaseDTO + var createdUser *userDTO.UserRelationDTO if e.CreatedUser.Id != 0 { - mapped := userDTO.ToUserBaseDTO(e.CreatedUser) + mapped := userDTO.ToUserRelationDTO(e.CreatedUser) createdUser = &mapped } - var uomRef *uomDTO.UomBaseDTO + var uomRef *uomDTO.UomRelationDTO if e.Uom.Id != 0 { - mapped := uomDTO.ToUomBaseDTO(e.Uom) + mapped := uomDTO.ToUomRelationDTO(e.Uom) uomRef = &mapped } - suppliers := make([]supplierDTO.SupplierBaseDTO, len(e.Suppliers)) - for i, s := range e.Suppliers { - suppliers[i] = supplierDTO.ToSupplierBaseDTO(s) - } - flags := make([]string, len(e.Flags)) for i, f := range e.Flags { flags[i] = f.Name @@ -81,11 +74,11 @@ func ToNonstockListDTO(e entity.Nonstock) NonstockListDTO { return NonstockListDTO{ Id: e.Id, Name: e.Name, + Flags: flags, Uom: uomRef, CreatedAt: e.CreatedAt, UpdatedAt: e.UpdatedAt, CreatedUser: createdUser, - Suppliers: suppliers, } } @@ -98,13 +91,7 @@ func ToNonstockListDTOs(e []entity.Nonstock) []NonstockListDTO { } func ToNonstockDetailDTO(e entity.Nonstock) NonstockDetailDTO { - flags := make([]string, len(e.Flags)) - for i, f := range e.Flags { - flags[i] = f.Name - } - return NonstockDetailDTO{ NonstockListDTO: ToNonstockListDTO(e), - Flags: flags, } } diff --git a/internal/modules/master/nonstocks/repositories/nonstock.repository.go b/internal/modules/master/nonstocks/repositories/nonstock.repository.go index affcbc4b..25a36e92 100644 --- a/internal/modules/master/nonstocks/repositories/nonstock.repository.go +++ b/internal/modules/master/nonstocks/repositories/nonstock.repository.go @@ -57,7 +57,7 @@ func (r *NonstockRepositoryImpl) SyncSuppliersDiff(ctx context.Context, tx *gorm existingMap := make(map[uint]struct{}, len(existing)) for _, rel := range existing { - existingMap[rel.SupplierID] = struct{}{} + existingMap[rel.SupplierId] = struct{}{} } incomingMap := make(map[uint]struct{}, len(supplierIDs)) @@ -66,16 +66,16 @@ func (r *NonstockRepositoryImpl) SyncSuppliersDiff(ctx context.Context, tx *gorm if _, exists := existingMap[id]; exists { continue } - record := entity.NonstockSupplier{NonstockID: nonstockID, SupplierID: id} + record := entity.NonstockSupplier{NonstockId: nonstockID, SupplierId: id} if err := db.WithContext(ctx).Create(&record).Error; err != nil { return err } } for _, rel := range existing { - if _, keep := incomingMap[rel.SupplierID]; !keep { + if _, keep := incomingMap[rel.SupplierId]; !keep { if err := db.WithContext(ctx). - Where("nonstock_id = ? AND supplier_id = ?", nonstockID, rel.SupplierID). + Where("nonstock_id = ? AND supplier_id = ?", nonstockID, rel.SupplierId). Delete(&entity.NonstockSupplier{}). Error; err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { diff --git a/internal/modules/master/nonstocks/services/nonstock.service.go b/internal/modules/master/nonstocks/services/nonstock.service.go index 3833432e..c0001a52 100644 --- a/internal/modules/master/nonstocks/services/nonstock.service.go +++ b/internal/modules/master/nonstocks/services/nonstock.service.go @@ -44,7 +44,8 @@ func (s nonstockService) withRelations(db *gorm.DB) *gorm.DB { Preload("CreatedUser"). Preload("Uom"). Preload("Flags"). - Preload("Suppliers", func(db *gorm.DB) *gorm.DB { + Preload("NonstockSuppliers"). + Preload("NonstockSuppliers.Supplier", func(db *gorm.DB) *gorm.DB { return db.Order("suppliers.name ASC") }) } diff --git a/internal/modules/master/product-categories/dto/product-category.dto.go b/internal/modules/master/product-categories/dto/product-category.dto.go index 6750c7c7..fc7f3c6f 100644 --- a/internal/modules/master/product-categories/dto/product-category.dto.go +++ b/internal/modules/master/product-categories/dto/product-category.dto.go @@ -9,17 +9,17 @@ import ( // === DTO Structs === -type ProductCategoryBaseDTO struct { +type ProductCategoryRelationDTO struct { Id uint `json:"id"` Name string `json:"name"` Code string `json:"code"` } type ProductCategoryListDTO struct { - ProductCategoryBaseDTO - CreatedUser *userDTO.UserBaseDTO `json:"created_user"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` + ProductCategoryRelationDTO + CreatedUser *userDTO.UserRelationDTO `json:"created_user"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` } type ProductCategoryDetailDTO struct { @@ -28,8 +28,8 @@ type ProductCategoryDetailDTO struct { // === Mapper Functions === -func ToProductCategoryBaseDTO(e entity.ProductCategory) ProductCategoryBaseDTO { - return ProductCategoryBaseDTO{ +func ToProductCategoryRelationDTO(e entity.ProductCategory) ProductCategoryRelationDTO { + return ProductCategoryRelationDTO{ Id: e.Id, Name: e.Name, Code: e.Code, @@ -37,17 +37,17 @@ func ToProductCategoryBaseDTO(e entity.ProductCategory) ProductCategoryBaseDTO { } func ToProductCategoryListDTO(e entity.ProductCategory) ProductCategoryListDTO { - var createdUser *userDTO.UserBaseDTO + var createdUser *userDTO.UserRelationDTO if e.CreatedUser.Id != 0 { - mapped := userDTO.ToUserBaseDTO(e.CreatedUser) + mapped := userDTO.ToUserRelationDTO(e.CreatedUser) createdUser = &mapped } return ProductCategoryListDTO{ - ProductCategoryBaseDTO: ToProductCategoryBaseDTO(e), - CreatedAt: e.CreatedAt, - UpdatedAt: e.UpdatedAt, - CreatedUser: createdUser, + ProductCategoryRelationDTO: ToProductCategoryRelationDTO(e), + CreatedAt: e.CreatedAt, + UpdatedAt: e.UpdatedAt, + CreatedUser: createdUser, } } diff --git a/internal/modules/master/products/dto/product.dto.go b/internal/modules/master/products/dto/product.dto.go index 60696fc7..f676f994 100644 --- a/internal/modules/master/products/dto/product.dto.go +++ b/internal/modules/master/products/dto/product.dto.go @@ -5,55 +5,57 @@ import ( entity "gitlab.com/mbugroup/lti-api.git/internal/entities" productCategoryDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/product-categories/dto" - supplierDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/suppliers/dto" uomDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/uoms/dto" userDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/users/dto" ) // === DTO Structs === -type ProductBaseDTO struct { - Id uint `json:"id"` - Name string `json:"name"` - Uom *uomDTO.UomBaseDTO `json:"uom,omitempty"` - Flags []string `json:"flags"` +type ProductRelationDTO struct { + Id uint `json:"id"` + Name string `json:"name"` + ProductPrice float64 `gorm:"type:numeric(15,3);not null"` + SellingPrice *float64 `gorm:"type:numeric(15,3)"` + Uom *uomDTO.UomRelationDTO `json:"uom,omitempty"` + Flags []string `json:"flags"` } type ProductListDTO struct { - ProductBaseDTO - Brand string `json:"brand"` - Sku *string `json:"sku,omitempty"` - ProductPrice float64 `json:"product_price"` - SellingPrice *float64 `json:"selling_price,omitempty"` - Tax *float64 `json:"tax,omitempty"` - ExpiryPeriod *int `json:"expiry_period,omitempty"` - ProductCategory *productCategoryDTO.ProductCategoryBaseDTO `json:"product_category,omitempty"` - Suppliers []supplierDTO.SupplierBaseDTO `json:"suppliers"` - CreatedUser *userDTO.UserBaseDTO `json:"created_user"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` + Id uint `json:"id"` + Name string `json:"name"` + Brand string `json:"brand"` + Sku *string `json:"sku,omitempty"` + ProductPrice float64 `json:"product_price"` + SellingPrice *float64 `json:"selling_price,omitempty"` + Tax *float64 `json:"tax,omitempty"` + ExpiryPeriod *int `json:"expiry_period,omitempty"` + Flags []string `json:"flags"` + Uom *uomDTO.UomRelationDTO `json:"uom,omitempty"` + ProductCategory *productCategoryDTO.ProductCategoryRelationDTO `json:"product_category,omitempty"` + CreatedUser *userDTO.UserRelationDTO `json:"created_user"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` } type ProductDetailDTO struct { ProductListDTO - Flags []string `json:"flags"` } // === Mapper Functions === -func ToProductBaseDTO(e entity.Product) ProductBaseDTO { +func ToProductRelationDTO(e entity.Product) ProductRelationDTO { flags := make([]string, len(e.Flags)) for i, f := range e.Flags { flags[i] = f.Name } - var uomRef *uomDTO.UomBaseDTO + var uomRef *uomDTO.UomRelationDTO if e.Uom.Id != 0 { - mapped := uomDTO.ToUomBaseDTO(e.Uom) + mapped := uomDTO.ToUomRelationDTO(e.Uom) uomRef = &mapped } - return ProductBaseDTO{ + return ProductRelationDTO{ Id: e.Id, Name: e.Name, Flags: flags, @@ -62,36 +64,44 @@ func ToProductBaseDTO(e entity.Product) ProductBaseDTO { } func ToProductListDTO(e entity.Product) ProductListDTO { - var createdUser *userDTO.UserBaseDTO + var createdUser *userDTO.UserRelationDTO if e.CreatedUser.Id != 0 { - mapped := userDTO.ToUserBaseDTO(e.CreatedUser) + mapped := userDTO.ToUserRelationDTO(e.CreatedUser) createdUser = &mapped } - var categoryRef *productCategoryDTO.ProductCategoryBaseDTO + var categoryRef *productCategoryDTO.ProductCategoryRelationDTO if e.ProductCategory.Id != 0 { - mapped := productCategoryDTO.ToProductCategoryBaseDTO(e.ProductCategory) + mapped := productCategoryDTO.ToProductCategoryRelationDTO(e.ProductCategory) categoryRef = &mapped } - suppliers := make([]supplierDTO.SupplierBaseDTO, len(e.Suppliers)) - for i, s := range e.Suppliers { - suppliers[i] = supplierDTO.ToSupplierBaseDTO(s) + flags := make([]string, len(e.Flags)) + for i, f := range e.Flags { + flags[i] = f.Name + } + + var uomRef *uomDTO.UomRelationDTO + if e.Uom.Id != 0 { + mapped := uomDTO.ToUomRelationDTO(e.Uom) + uomRef = &mapped } return ProductListDTO{ + Id: e.Id, + Name: e.Name, + Flags: flags, + Uom: uomRef, Brand: e.Brand, Sku: e.Sku, ProductPrice: e.ProductPrice, SellingPrice: e.SellingPrice, Tax: e.Tax, ExpiryPeriod: e.ExpiryPeriod, - ProductBaseDTO: ToProductBaseDTO(e), CreatedAt: e.CreatedAt, UpdatedAt: e.UpdatedAt, CreatedUser: createdUser, ProductCategory: categoryRef, - Suppliers: suppliers, } } @@ -104,13 +114,7 @@ func ToProductListDTOs(e []entity.Product) []ProductListDTO { } func ToProductDetailDTO(e entity.Product) ProductDetailDTO { - flags := make([]string, len(e.Flags)) - for i, f := range e.Flags { - flags[i] = f.Name - } - return ProductDetailDTO{ ProductListDTO: ToProductListDTO(e), - Flags: flags, } } diff --git a/internal/modules/master/products/repositories/product.repository.go b/internal/modules/master/products/repositories/product.repository.go index d1cc5cb2..244259d5 100644 --- a/internal/modules/master/products/repositories/product.repository.go +++ b/internal/modules/master/products/repositories/product.repository.go @@ -102,13 +102,13 @@ func (r *ProductRepositoryImpl) IsLinkedToSupplier(ctx context.Context, productI return count > 0, nil } -func (r *ProductRepositoryImpl) SyncSuppliersDiff(ctx context.Context, tx *gorm.DB, productID uint, supplierIDs []uint) error { +func (r *ProductRepositoryImpl) SyncSuppliersDiff(ctx context.Context, tx *gorm.DB, productID uint, supplierIds []uint) error { db := tx if db == nil { db = r.DB() } - if supplierIDs == nil { + if supplierIds == nil { return db.WithContext(ctx). Where("product_id = ?", productID). Delete(&entity.ProductSupplier{}). @@ -125,25 +125,25 @@ func (r *ProductRepositoryImpl) SyncSuppliersDiff(ctx context.Context, tx *gorm. existingMap := make(map[uint]struct{}, len(existing)) for _, rel := range existing { - existingMap[rel.SupplierID] = struct{}{} + existingMap[rel.SupplierId] = struct{}{} } - incomingMap := make(map[uint]struct{}, len(supplierIDs)) - for _, id := range supplierIDs { + incomingMap := make(map[uint]struct{}, len(supplierIds)) + for _, id := range supplierIds { incomingMap[id] = struct{}{} if _, exists := existingMap[id]; exists { continue } - record := entity.ProductSupplier{ProductID: productID, SupplierID: id} + record := entity.ProductSupplier{ProductId: productID, SupplierId: id} if err := db.WithContext(ctx).Create(&record).Error; err != nil { return err } } for _, rel := range existing { - if _, keep := incomingMap[rel.SupplierID]; !keep { + if _, keep := incomingMap[rel.SupplierId]; !keep { if err := db.WithContext(ctx). - Where("product_id = ? AND supplier_id = ?", productID, rel.SupplierID). + Where("product_id = ? AND supplier_id = ?", productID, rel.SupplierId). Delete(&entity.ProductSupplier{}). Error; err != nil { return err diff --git a/internal/modules/master/products/services/product.service.go b/internal/modules/master/products/services/product.service.go index fb1fe00f..35e24927 100644 --- a/internal/modules/master/products/services/product.service.go +++ b/internal/modules/master/products/services/product.service.go @@ -55,7 +55,8 @@ func (s productService) withRelations(db *gorm.DB) *gorm.DB { Preload("Uom"). Preload("ProductCategory"). Preload("Flags"). - Preload("Suppliers", func(db *gorm.DB) *gorm.DB { + Preload("ProductSuppliers"). + Preload("ProductSuppliers.Supplier", func(db *gorm.DB) *gorm.DB { return db.Order("suppliers.name ASC") }) } diff --git a/internal/modules/master/suppliers/controllers/supplier.controller.go b/internal/modules/master/suppliers/controllers/supplier.controller.go index 5d70e43e..c427316d 100644 --- a/internal/modules/master/suppliers/controllers/supplier.controller.go +++ b/internal/modules/master/suppliers/controllers/supplier.controller.go @@ -24,9 +24,10 @@ func NewSupplierController(supplierService service.SupplierService) *SupplierCon func (u *SupplierController) GetAll(c *fiber.Ctx) error { query := &validation.Query{ - Page: c.QueryInt("page", 1), - Limit: c.QueryInt("limit", 10), - Search: c.Query("search", ""), + Page: c.QueryInt("page", 1), + Limit: c.QueryInt("limit", 10), + Search: c.Query("search", ""), + Category: c.Query("category", ""), } if query.Page < 1 || query.Limit < 1 { @@ -71,7 +72,7 @@ func (u *SupplierController) GetOne(c *fiber.Ctx) error { Code: fiber.StatusOK, Status: "success", Message: "Get supplier successfully", - Data: dto.ToSupplierListDTO(*result), + Data: dto.ToSupplierDetailDTO(*result), }) } diff --git a/internal/modules/master/suppliers/dto/supplier.dto.go b/internal/modules/master/suppliers/dto/supplier.dto.go index 7e0df680..c8302b0b 100644 --- a/internal/modules/master/suppliers/dto/supplier.dto.go +++ b/internal/modules/master/suppliers/dto/supplier.dto.go @@ -9,7 +9,7 @@ import ( // === DTO Structs === -type SupplierBaseDTO struct { +type SupplierRelationDTO struct { Id uint `json:"id"` Name string `json:"name"` Alias string `json:"alias"` @@ -17,30 +17,32 @@ type SupplierBaseDTO struct { } type SupplierListDTO struct { - SupplierBaseDTO - Pic string `json:"pic"` - Type string `json:"type"` - Hatchery *string `json:"hatchery,omitempty"` - Phone string `json:"phone"` - Email string `json:"email"` - Address string `json:"address"` - Npwp *string `json:"npwp,omitempty"` - AccountNumber *string `json:"account_number,omitempty"` - Balance float64 `json:"balance"` - DueDate int `json:"due_date"` - CreatedUser *userDTO.UserBaseDTO `json:"created_user"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` + SupplierRelationDTO + Pic string `json:"pic"` + Type string `json:"type"` + Hatchery *string `json:"hatchery,omitempty"` + Phone string `json:"phone"` + Email string `json:"email"` + Address string `json:"address"` + Npwp *string `json:"npwp,omitempty"` + AccountNumber *string `json:"account_number,omitempty"` + Balance float64 `json:"balance"` + DueDate int `json:"due_date"` + CreatedUser *userDTO.UserRelationDTO `json:"created_user"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` } type SupplierDetailDTO struct { SupplierListDTO + Products []SupplierProductDTO `json:"products"` + Nonstocks []SupplierNonstockDTO `json:"nonstocks"` } // === Mapper Functions === -func ToSupplierBaseDTO(e entity.Supplier) SupplierBaseDTO { - return SupplierBaseDTO{ +func ToSupplierRelationDTO(e entity.Supplier) SupplierRelationDTO { + return SupplierRelationDTO{ Id: e.Id, Name: e.Name, Alias: e.Alias, @@ -49,27 +51,27 @@ func ToSupplierBaseDTO(e entity.Supplier) SupplierBaseDTO { } func ToSupplierListDTO(e entity.Supplier) SupplierListDTO { - var createdUser *userDTO.UserBaseDTO + var createdUser *userDTO.UserRelationDTO if e.CreatedUser.Id != 0 { - mapped := userDTO.ToUserBaseDTO(e.CreatedUser) + mapped := userDTO.ToUserRelationDTO(e.CreatedUser) createdUser = &mapped } return SupplierListDTO{ - Pic: e.Pic, - Type: e.Type, - Hatchery: e.Hatchery, - Phone: e.Phone, - Email: e.Email, - Address: e.Address, - Npwp: e.Npwp, - AccountNumber: e.AccountNumber, - Balance: e.Balance, - DueDate: e.DueDate, - SupplierBaseDTO: ToSupplierBaseDTO(e), - CreatedAt: e.CreatedAt, - UpdatedAt: e.UpdatedAt, - CreatedUser: createdUser, + Pic: e.Pic, + Type: e.Type, + Hatchery: e.Hatchery, + Phone: e.Phone, + Email: e.Email, + Address: e.Address, + Npwp: e.Npwp, + AccountNumber: e.AccountNumber, + Balance: e.Balance, + DueDate: e.DueDate, + SupplierRelationDTO: ToSupplierRelationDTO(e), + CreatedAt: e.CreatedAt, + UpdatedAt: e.UpdatedAt, + CreatedUser: createdUser, } } @@ -84,5 +86,7 @@ func ToSupplierListDTOs(e []entity.Supplier) []SupplierListDTO { func ToSupplierDetailDTO(e entity.Supplier) SupplierDetailDTO { return SupplierDetailDTO{ SupplierListDTO: ToSupplierListDTO(e), + Products: toSupplierProductDTOs(e.ProductSuppliers), + Nonstocks: toSupplierNonstockDTOs(e.NonstockSuppliers), } } diff --git a/internal/modules/master/suppliers/dto/supplier_nonstock.dto.go b/internal/modules/master/suppliers/dto/supplier_nonstock.dto.go new file mode 100644 index 00000000..828063eb --- /dev/null +++ b/internal/modules/master/suppliers/dto/supplier_nonstock.dto.go @@ -0,0 +1,50 @@ +package dto + +import ( + entity "gitlab.com/mbugroup/lti-api.git/internal/entities" + uomDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/uoms/dto" +) + +// === DTO Structs === + +type SupplierNonstockDTO struct { + Id uint `json:"id"` + Name string `json:"name"` + Uom *uomDTO.UomRelationDTO `json:"uom,omitempty"` + Flags []string `json:"flags"` +} + +// === Mapper Functions === + +func toSupplierNonstockDTOs(relations []entity.NonstockSupplier) []SupplierNonstockDTO { + if len(relations) == 0 { + return nil + } + + result := make([]SupplierNonstockDTO, 0, len(relations)) + for _, relation := range relations { + Nonstock := relation.Nonstock + if Nonstock.Id == 0 { + continue + } + + flags := make([]string, len(Nonstock.Flags)) + for i, f := range Nonstock.Flags { + flags[i] = f.Name + } + + var uomRef *uomDTO.UomRelationDTO + if Nonstock.Uom.Id != 0 { + mapped := uomDTO.ToUomRelationDTO(Nonstock.Uom) + uomRef = &mapped + } + + result = append(result, SupplierNonstockDTO{ + Id: Nonstock.Id, + Name: Nonstock.Name, + Uom: uomRef, + Flags: flags, + }) + } + return result +} diff --git a/internal/modules/master/suppliers/dto/supplier_product.dto.go b/internal/modules/master/suppliers/dto/supplier_product.dto.go new file mode 100644 index 00000000..47a6ae0e --- /dev/null +++ b/internal/modules/master/suppliers/dto/supplier_product.dto.go @@ -0,0 +1,54 @@ +package dto + +import ( + entity "gitlab.com/mbugroup/lti-api.git/internal/entities" + uomDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/uoms/dto" +) + +// === DTO Structs === + +type SupplierProductDTO struct { + Id uint `json:"id"` + Name string `json:"name"` + ProductPrice float64 `gorm:"type:numeric(15,3);not null"` + SellingPrice *float64 `gorm:"type:numeric(15,3)"` + Uom *uomDTO.UomRelationDTO `json:"uom,omitempty"` + Flags []string `json:"flags"` +} + +// === Mapper Functions === + +func toSupplierProductDTOs(relations []entity.ProductSupplier) []SupplierProductDTO { + if len(relations) == 0 { + return nil + } + + result := make([]SupplierProductDTO, 0, len(relations)) + for _, relation := range relations { + product := relation.Product + if product.Id == 0 { + continue + } + + flags := make([]string, len(product.Flags)) + for i, f := range product.Flags { + flags[i] = f.Name + } + + var uomRef *uomDTO.UomRelationDTO + if product.Uom.Id != 0 { + mapped := uomDTO.ToUomRelationDTO(product.Uom) + uomRef = &mapped + } + + result = append(result, SupplierProductDTO{ + Id: product.Id, + Name: product.Name, + ProductPrice: product.ProductPrice, + SellingPrice: product.SellingPrice, + Uom: uomRef, + Flags: flags, + }) + } + return result +} diff --git a/internal/modules/master/suppliers/route.go b/internal/modules/master/suppliers/route.go index 17271d4a..3a57f645 100644 --- a/internal/modules/master/suppliers/route.go +++ b/internal/modules/master/suppliers/route.go @@ -1,7 +1,7 @@ package suppliers import ( - m "gitlab.com/mbugroup/lti-api.git/internal/middleware" + // m "gitlab.com/mbugroup/lti-api.git/internal/middleware" controller "gitlab.com/mbugroup/lti-api.git/internal/modules/master/suppliers/controllers" supplier "gitlab.com/mbugroup/lti-api.git/internal/modules/master/suppliers/services" user "gitlab.com/mbugroup/lti-api.git/internal/modules/users/services" @@ -13,7 +13,7 @@ func SupplierRoutes(v1 fiber.Router, u user.UserService, s supplier.SupplierServ ctrl := controller.NewSupplierController(s) route := v1.Group("/suppliers") - route.Use(m.Auth(u)) + // route.Use(m.Auth(u)) route.Get("/", ctrl.GetAll) route.Post("/", ctrl.CreateOne) diff --git a/internal/modules/master/suppliers/services/supplier.service.go b/internal/modules/master/suppliers/services/supplier.service.go index 99e15b29..30ff4b9b 100644 --- a/internal/modules/master/suppliers/services/supplier.service.go +++ b/internal/modules/master/suppliers/services/supplier.service.go @@ -39,7 +39,12 @@ func NewSupplierService(repo repository.SupplierRepository, validate *validator. } func (s supplierService) withRelations(db *gorm.DB) *gorm.DB { - return db.Preload("CreatedUser") + return db. + Preload("CreatedUser"). + Preload("ProductSuppliers.Product.Uom"). + Preload("ProductSuppliers.Product.Flags"). + Preload("NonstockSuppliers.Nonstock.Uom"). + Preload("NonstockSuppliers.Nonstock.Flags") } func (s supplierService) GetAll(c *fiber.Ctx, params *validation.Query) ([]entity.Supplier, int64, error) { @@ -47,6 +52,14 @@ func (s supplierService) GetAll(c *fiber.Ctx, params *validation.Query) ([]entit return nil, 0, err } + if params.Category != "" { + category := strings.ToUpper(params.Category) + if category != "BOP" && category != "SAPRONAK" { + return nil, 0, fiber.NewError(fiber.StatusBadRequest, "Invalid supplier category") + } + params.Category = category + } + offset := (params.Page - 1) * params.Limit suppliers, total, err := s.Repository.GetAll(c.Context(), offset, params.Limit, func(db *gorm.DB) *gorm.DB { @@ -54,6 +67,11 @@ func (s supplierService) GetAll(c *fiber.Ctx, params *validation.Query) ([]entit if params.Search != "" { return db.Where("name LIKE ?", "%"+params.Search+"%") } + + if params.Category != "" { + db = db.Where("category LIKE ?", "%"+params.Category+"%") + } + return db.Order("created_at DESC").Order("updated_at DESC") }) diff --git a/internal/modules/master/suppliers/validations/supplier.validation.go b/internal/modules/master/suppliers/validations/supplier.validation.go index 7eeff716..fa1d135d 100644 --- a/internal/modules/master/suppliers/validations/supplier.validation.go +++ b/internal/modules/master/suppliers/validations/supplier.validation.go @@ -31,7 +31,8 @@ type Update struct { } type Query struct { - Page int `query:"page" validate:"omitempty,number,min=1"` - Limit int `query:"limit" validate:"omitempty,number,min=1,max=100"` - Search string `query:"search" validate:"omitempty,max=50"` + Page int `query:"page" validate:"omitempty,number,min=1"` + Limit int `query:"limit" validate:"omitempty,number,min=1,max=100"` + Search string `query:"search" validate:"omitempty,max=50"` + Category string `query:"category" validate:"omitempty,max=50"` } diff --git a/internal/modules/master/uoms/dto/uom.dto.go b/internal/modules/master/uoms/dto/uom.dto.go index 2e614de0..cc32a702 100644 --- a/internal/modules/master/uoms/dto/uom.dto.go +++ b/internal/modules/master/uoms/dto/uom.dto.go @@ -9,17 +9,17 @@ import ( // === DTO Structs === -type UomBaseDTO struct { +type UomRelationDTO struct { Id uint `json:"id"` Name string `json:"name"` } type UomListDTO struct { - Id uint `json:"id"` - Name string `json:"name"` - CreatedUser *userDTO.UserBaseDTO `json:"created_user"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` + Id uint `json:"id"` + Name string `json:"name"` + CreatedUser *userDTO.UserRelationDTO `json:"created_user"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` } type UomDetailDTO struct { @@ -28,17 +28,17 @@ type UomDetailDTO struct { // === Mapper Functions === -func ToUomBaseDTO(e entity.Uom) UomBaseDTO { - return UomBaseDTO{ +func ToUomRelationDTO(e entity.Uom) UomRelationDTO { + return UomRelationDTO{ Id: e.Id, Name: e.Name, } } func ToUomListDTO(e entity.Uom) UomListDTO { - var createdUser *userDTO.UserBaseDTO + var createdUser *userDTO.UserRelationDTO if e.CreatedUser.Id != 0 { - mapped := userDTO.ToUserBaseDTO(e.CreatedUser) + mapped := userDTO.ToUserRelationDTO(e.CreatedUser) createdUser = &mapped } diff --git a/internal/modules/master/warehouses/dto/warehouse.dto.go b/internal/modules/master/warehouses/dto/warehouse.dto.go index f3c3715b..e80c4f9f 100644 --- a/internal/modules/master/warehouses/dto/warehouse.dto.go +++ b/internal/modules/master/warehouses/dto/warehouse.dto.go @@ -12,25 +12,25 @@ import ( // === DTO Structs === -type WarehouseBaseDTO struct { - Id uint `json:"id"` - Name string `json:"name"` - Type string `json:"type"` - Area *areaDTO.AreaBaseDTO `json:"area,omitempty"` - Location *locationDTO.LocationBaseDTO `json:"location,omitempty"` - Kandang *kandangDTO.KandangBaseDTO `json:"kandang,omitempty"` +type WarehouseRelationDTO struct { + Id uint `json:"id"` + Name string `json:"name"` + Type string `json:"type"` + Area *areaDTO.AreaRelationDTO `json:"area,omitempty"` + Location *locationDTO.LocationRelationDTO `json:"location,omitempty"` + Kandang *kandangDTO.KandangRelationDTO `json:"kandang,omitempty"` } type WarehouseListDTO struct { - Id uint `json:"id"` - Name string `json:"name"` - Type string `json:"type"` - Area *areaDTO.AreaBaseDTO `json:"area"` - Location *locationDTO.LocationBaseDTO `json:"location"` - Kandang *kandangDTO.KandangBaseDTO `json:"kandang"` - CreatedUser *userDTO.UserBaseDTO `json:"created_user"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` + Id uint `json:"id"` + Name string `json:"name"` + Type string `json:"type"` + Area *areaDTO.AreaRelationDTO `json:"area"` + Location *locationDTO.LocationRelationDTO `json:"location"` + Kandang *kandangDTO.KandangRelationDTO `json:"kandang"` + CreatedUser *userDTO.UserRelationDTO `json:"created_user"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` } type WarehouseDetailDTO struct { @@ -39,26 +39,26 @@ type WarehouseDetailDTO struct { // === Mapper Functions === -func ToWarehouseBaseDTO(e entity.Warehouse) WarehouseBaseDTO { - var area *areaDTO.AreaBaseDTO +func ToWarehouseRelationDTO(e entity.Warehouse) WarehouseRelationDTO { + var area *areaDTO.AreaRelationDTO if e.Area.Id != 0 { - mapped := areaDTO.ToAreaBaseDTO(e.Area) + mapped := areaDTO.ToAreaRelationDTO(e.Area) area = &mapped } - var location *locationDTO.LocationBaseDTO + var location *locationDTO.LocationRelationDTO if e.Location != nil && e.Location.Id != 0 { - mapped := locationDTO.ToLocationBaseDTO(*e.Location) + mapped := locationDTO.ToLocationRelationDTO(*e.Location) location = &mapped } - var kandang *kandangDTO.KandangBaseDTO + var kandang *kandangDTO.KandangRelationDTO if e.Kandang != nil && e.Kandang.Id != 0 { - mapped := kandangDTO.ToKandangBaseDTO(*e.Kandang) + mapped := kandangDTO.ToKandangRelationDTO(*e.Kandang) kandang = &mapped } - return WarehouseBaseDTO{ + return WarehouseRelationDTO{ Id: e.Id, Name: e.Name, Type: e.Type, @@ -69,27 +69,27 @@ func ToWarehouseBaseDTO(e entity.Warehouse) WarehouseBaseDTO { } func ToWarehouseListDTO(e entity.Warehouse) WarehouseListDTO { - var createdUser *userDTO.UserBaseDTO + var createdUser *userDTO.UserRelationDTO if e.CreatedUser.Id != 0 { - mapped := userDTO.ToUserBaseDTO(e.CreatedUser) + mapped := userDTO.ToUserRelationDTO(e.CreatedUser) createdUser = &mapped } - var area *areaDTO.AreaBaseDTO + var area *areaDTO.AreaRelationDTO if e.Area.Id != 0 { - mapped := areaDTO.ToAreaBaseDTO(e.Area) + mapped := areaDTO.ToAreaRelationDTO(e.Area) area = &mapped } - var location *locationDTO.LocationBaseDTO + var location *locationDTO.LocationRelationDTO if e.Location != nil && e.Location.Id != 0 { - mapped := locationDTO.ToLocationBaseDTO(*e.Location) + mapped := locationDTO.ToLocationRelationDTO(*e.Location) location = &mapped } - var kandang *kandangDTO.KandangBaseDTO + var kandang *kandangDTO.KandangRelationDTO if e.Kandang != nil && e.Kandang.Id != 0 { - mapped := kandangDTO.ToKandangBaseDTO(*e.Kandang) + mapped := kandangDTO.ToKandangRelationDTO(*e.Kandang) kandang = &mapped } diff --git a/internal/modules/production/chickins/dto/chickin.dto.go b/internal/modules/production/chickins/dto/chickin.dto.go index 4a0e1bbb..d53b9491 100644 --- a/internal/modules/production/chickins/dto/chickin.dto.go +++ b/internal/modules/production/chickins/dto/chickin.dto.go @@ -4,26 +4,26 @@ import ( "time" entity "gitlab.com/mbugroup/lti-api.git/internal/entities" - areaBaseDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/areas/dto" - fcrBaseDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/fcrs/dto" - flockBaseDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/flocks/dto" - kandangBaseDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/kandangs/dto" - locationBaseDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/locations/dto" + areaRelationDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/areas/dto" + fcrRelationDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/fcrs/dto" + flockRelationDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/flocks/dto" + kandangRelationDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/kandangs/dto" + locationRelationDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/locations/dto" productDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/products/dto" warehouseDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/warehouses/dto" pfutils "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/utils" - userBaseDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/users/dto" + userRelationDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/users/dto" ) // === DTO Structs (ordered) === type ProductWarehouseDTO struct { - Id uint `json:"id"` - Product *productDTO.ProductBaseDTO `json:"product,omitempty"` - Warehouse *warehouseDTO.WarehouseBaseDTO `json:"warehouse,omitempty"` + Id uint `json:"id"` + Product *productDTO.ProductRelationDTO `json:"product,omitempty"` + Warehouse *warehouseDTO.WarehouseRelationDTO `json:"warehouse,omitempty"` } -type ChickinBaseDTO struct { +type ChickinRelationDTO struct { Id uint `json:"id"` ProjectFlockKandangId uint `json:"project_flock_kandang_id"` ChickInDate time.Time `json:"chick_in_date"` @@ -35,19 +35,19 @@ type ChickinBaseDTO struct { } type ProjectFlockDTO struct { - Id uint `json:"id"` - Period int `json:"period"` - Category string `json:"category"` - Flock *flockBaseDTO.FlockBaseDTO `json:"flock"` - Area *areaBaseDTO.AreaBaseDTO `json:"area"` - Fcr *fcrBaseDTO.FcrBaseDTO `json:"fcr"` - Location *locationBaseDTO.LocationBaseDTO `json:"location"` + Id uint `json:"id"` + Period int `json:"period"` + Category string `json:"category"` + Flock *flockRelationDTO.FlockRelationDTO `json:"flock"` + Area *areaRelationDTO.AreaRelationDTO `json:"area"` + Fcr *fcrRelationDTO.FcrRelationDTO `json:"fcr"` + Location *locationRelationDTO.LocationRelationDTO `json:"location"` } type ProjectFlockKandangDTO struct { - Id uint `json:"id"` - ProjectFlock *ProjectFlockDTO `json:"project_flock"` - Kandang *kandangBaseDTO.KandangBaseDTO `json:"kandang"` + Id uint `json:"id"` + ProjectFlock *ProjectFlockDTO `json:"project_flock"` + Kandang *kandangRelationDTO.KandangRelationDTO `json:"kandang"` } // gunakan base DTO dari package users @@ -64,71 +64,71 @@ type ChickinSimpleDTO struct { } type ChickinListDTO struct { - ChickinBaseDTO - CreatedUser *userBaseDTO.UserBaseDTO `json:"created_user"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` + ChickinRelationDTO + CreatedUser *userRelationDTO.UserRelationDTO `json:"created_user"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` } type ChickinDetailDTO struct { - Id uint `json:"id"` - ProjectFlockKandangId uint `json:"project_flock_kandang_id"` - ChickInDate time.Time `json:"chick_in_date"` - ProductWarehouseId uint `json:"product_warehouse_id"` - UsageQty float64 `json:"usage_qty"` - PendingUsageQty float64 `json:"pending_usage_qty"` - Notes string `json:"notes"` - CreatedBy uint `json:"created_by"` - CreatedUser *userBaseDTO.UserBaseDTO `json:"created_user"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` + Id uint `json:"id"` + ProjectFlockKandangId uint `json:"project_flock_kandang_id"` + ChickInDate time.Time `json:"chick_in_date"` + ProductWarehouseId uint `json:"product_warehouse_id"` + UsageQty float64 `json:"usage_qty"` + PendingUsageQty float64 `json:"pending_usage_qty"` + Notes string `json:"notes"` + CreatedBy uint `json:"created_by"` + CreatedUser *userRelationDTO.UserRelationDTO `json:"created_user"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` } // === Mapper Functions (ordered) === -func ToFlockDTO(e entity.Flock) flockBaseDTO.FlockBaseDTO { - return flockBaseDTO.ToFlockBaseDTO(e) +func ToFlockDTO(e entity.Flock) flockRelationDTO.FlockRelationDTO { + return flockRelationDTO.ToFlockRelationDTO(e) } -func ToKandangDTO(e entity.Kandang) kandangBaseDTO.KandangBaseDTO { - return kandangBaseDTO.ToKandangBaseDTO(e) +func ToKandangDTO(e entity.Kandang) kandangRelationDTO.KandangRelationDTO { + return kandangRelationDTO.ToKandangRelationDTO(e) } -func ToAreaDTO(e entity.Area) areaBaseDTO.AreaBaseDTO { - return areaBaseDTO.ToAreaBaseDTO(e) +func ToAreaDTO(e entity.Area) areaRelationDTO.AreaRelationDTO { + return areaRelationDTO.ToAreaRelationDTO(e) } -func ToFcrDTO(e entity.Fcr) fcrBaseDTO.FcrBaseDTO { - return fcrBaseDTO.ToFcrBaseDTO(e) +func ToFcrDTO(e entity.Fcr) fcrRelationDTO.FcrRelationDTO { + return fcrRelationDTO.ToFcrRelationDTO(e) } -func ToLocationDTO(e entity.Location) locationBaseDTO.LocationBaseDTO { - return locationBaseDTO.ToLocationBaseDTO(e) +func ToLocationDTO(e entity.Location) locationRelationDTO.LocationRelationDTO { + return locationRelationDTO.ToLocationRelationDTO(e) } -func ToUserBaseDTO(e entity.User) userBaseDTO.UserBaseDTO { - return userBaseDTO.ToUserBaseDTO(e) +func ToUserRelationDTO(e entity.User) userRelationDTO.UserRelationDTO { + return userRelationDTO.ToUserRelationDTO(e) } func ToProjectFlockDTO(pfk entity.ProjectFlockKandang) ProjectFlockDTO { e := pfk.ProjectFlock - var flock *flockBaseDTO.FlockBaseDTO + var flock *flockRelationDTO.FlockRelationDTO if base := pfutils.DeriveBaseName(e.FlockName); base != "" { - summary := flockBaseDTO.FlockBaseDTO{Id: 0, Name: base} + summary := flockRelationDTO.FlockRelationDTO{Id: 0, Name: base} flock = &summary } - var area *areaBaseDTO.AreaBaseDTO + var area *areaRelationDTO.AreaRelationDTO if e.Area.Id != 0 { - mapped := areaBaseDTO.ToAreaBaseDTO(e.Area) + mapped := areaRelationDTO.ToAreaRelationDTO(e.Area) area = &mapped } - var fcr *fcrBaseDTO.FcrBaseDTO + var fcr *fcrRelationDTO.FcrRelationDTO if e.Fcr.Id != 0 { - mapped := fcrBaseDTO.ToFcrBaseDTO(e.Fcr) + mapped := fcrRelationDTO.ToFcrRelationDTO(e.Fcr) fcr = &mapped } - var location *locationBaseDTO.LocationBaseDTO + var location *locationRelationDTO.LocationRelationDTO if e.Location.Id != 0 { - mapped := locationBaseDTO.ToLocationBaseDTO(e.Location) + mapped := locationRelationDTO.ToLocationRelationDTO(e.Location) location = &mapped } return ProjectFlockDTO{ @@ -148,9 +148,9 @@ func ToProjectFlockKandangDTO(e entity.ProjectFlockKandang) ProjectFlockKandangD mapped := ToProjectFlockDTO(e) pf = &mapped } - var kandang *kandangBaseDTO.KandangBaseDTO + var kandang *kandangRelationDTO.KandangRelationDTO if e.Kandang.Id != 0 { - mapped := kandangBaseDTO.ToKandangBaseDTO(e.Kandang) + mapped := kandangRelationDTO.ToKandangRelationDTO(e.Kandang) kandang = &mapped } return ProjectFlockKandangDTO{ @@ -160,7 +160,7 @@ func ToProjectFlockKandangDTO(e entity.ProjectFlockKandang) ProjectFlockKandangD } } -func ToChickinBaseDTO(e entity.ProjectChickin) ChickinBaseDTO { +func ToChickinRelationDTO(e entity.ProjectChickin) ChickinRelationDTO { var projectFlockKandangId uint // Check if ProjectFlockKandang relation is loaded if e.ProjectFlockKandang != nil && e.ProjectFlockKandang.Id != 0 { @@ -175,7 +175,7 @@ func ToChickinBaseDTO(e entity.ProjectChickin) ChickinBaseDTO { productWarehouse = toProductWarehouseDTO(e.ProductWarehouse) } - return ChickinBaseDTO{ + return ChickinRelationDTO{ Id: e.Id, ProjectFlockKandangId: projectFlockKandangId, ChickInDate: e.ChickInDate, @@ -201,16 +201,16 @@ func ToChickinSimpleDTO(e entity.ProjectChickin) ChickinSimpleDTO { } func ToChickinListDTO(e entity.ProjectChickin) ChickinListDTO { - var createdUser *userBaseDTO.UserBaseDTO + var createdUser *userRelationDTO.UserRelationDTO if e.CreatedUser != nil && e.CreatedUser.Id != 0 { - mapped := userBaseDTO.ToUserBaseDTO(*e.CreatedUser) + mapped := userRelationDTO.ToUserRelationDTO(*e.CreatedUser) createdUser = &mapped } return ChickinListDTO{ - ChickinBaseDTO: ToChickinBaseDTO(e), - CreatedUser: createdUser, - CreatedAt: e.CreatedAt, - UpdatedAt: e.UpdatedAt, + ChickinRelationDTO: ToChickinRelationDTO(e), + CreatedUser: createdUser, + CreatedAt: e.CreatedAt, + UpdatedAt: e.UpdatedAt, } } @@ -231,9 +231,9 @@ func ToChickinSimpleDTOs(e []entity.ProjectChickin) []ChickinSimpleDTO { } func ToChickinDetailDTO(e entity.ProjectChickin) ChickinDetailDTO { - var createdUser *userBaseDTO.UserBaseDTO + var createdUser *userRelationDTO.UserRelationDTO if e.CreatedUser != nil && e.CreatedUser.Id != 0 { - mapped := userBaseDTO.ToUserBaseDTO(*e.CreatedUser) + mapped := userRelationDTO.ToUserRelationDTO(*e.CreatedUser) createdUser = &mapped } @@ -268,8 +268,8 @@ func ToProductWarehouseDTO(pw *entity.ProductWarehouse) *ProductWarehouseDTO { return nil } - product := productDTO.ToProductBaseDTO(pw.Product) - warehouse := warehouseDTO.ToWarehouseBaseDTO(pw.Warehouse) + product := productDTO.ToProductRelationDTO(pw.Product) + warehouse := warehouseDTO.ToWarehouseRelationDTO(pw.Warehouse) return &ProductWarehouseDTO{ Id: pw.Id, diff --git a/internal/modules/production/project-flock-kandangs/controllers/project_flock_kandang.controller.go b/internal/modules/production/project-flock-kandangs/controllers/project_flock_kandang.controller.go index d65cedfd..f3ef7271 100644 --- a/internal/modules/production/project-flock-kandangs/controllers/project_flock_kandang.controller.go +++ b/internal/modules/production/project-flock-kandangs/controllers/project_flock_kandang.controller.go @@ -48,7 +48,7 @@ func (u *ProjectFlockKandangController) GetAll(c *fiber.Ctx) error { data := make([]dto.ProjectFlockKandangListDTO, 0) for _, result := range results { - var flock *flockDTO.FlockBaseDTO + var flock *flockDTO.FlockRelationDTO if flockMap != nil { flock = flockMap[result.ProjectFlock.Id] } diff --git a/internal/modules/production/project-flock-kandangs/dto/project_flock_kandang.dto.go b/internal/modules/production/project-flock-kandangs/dto/project_flock_kandang.dto.go index 1a076232..1cc0c1f5 100644 --- a/internal/modules/production/project-flock-kandangs/dto/project_flock_kandang.dto.go +++ b/internal/modules/production/project-flock-kandangs/dto/project_flock_kandang.dto.go @@ -18,24 +18,24 @@ import ( // === DTO Structs (ordered) === -type ProjectFlockKandangBaseDTO struct { +type ProjectFlockKandangRelationDTO struct { Id uint `json:"id"` KandangId uint `json:"kandang_id"` ProjectFlockId uint `json:"project_flock_id"` } type ProjectFlockDTO struct { - Id uint `json:"id"` - Name string `json:"flock_name,omitempty"` - Period int `json:"period"` - Flock *flockDTO.FlockBaseDTO `json:"flock,omitempty"` - Area *areaDTO.AreaBaseDTO `json:"area,omitempty"` - Category string `json:"category"` - Fcr *fcrDTO.FcrBaseDTO `json:"fcr,omitempty"` - Location *locationDTO.LocationBaseDTO `json:"location,omitempty"` - CreatedUser *userDTO.UserBaseDTO `json:"created_user,omitempty"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` + Id uint `json:"id"` + Name string `json:"flock_name,omitempty"` + Period int `json:"period"` + Flock *flockDTO.FlockRelationDTO `json:"flock,omitempty"` + Area *areaDTO.AreaRelationDTO `json:"area,omitempty"` + Category string `json:"category"` + Fcr *fcrDTO.FcrRelationDTO `json:"fcr,omitempty"` + Location *locationDTO.LocationRelationDTO `json:"location,omitempty"` + CreatedUser *userDTO.UserRelationDTO `json:"created_user,omitempty"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` } type KandangDTO struct { @@ -45,9 +45,9 @@ type KandangDTO struct { } type ProductWarehouseDTO struct { - Id uint `json:"id"` - Product *productDTO.ProductBaseDTO `json:"product,omitempty"` - Warehouse *warehouseDTO.WarehouseBaseDTO `json:"warehouse,omitempty"` + Id uint `json:"id"` + Product *productDTO.ProductRelationDTO `json:"product,omitempty"` + Warehouse *warehouseDTO.WarehouseRelationDTO `json:"warehouse,omitempty"` } type AvailableQtyDTO struct { @@ -56,24 +56,24 @@ type AvailableQtyDTO struct { } type ProjectFlockKandangListDTO struct { - ProjectFlockKandangBaseDTO - ProjectFlock *ProjectFlockDTO `json:"project_flock,omitempty"` - Kandang *KandangDTO `json:"kandang,omitempty"` - CreatedUser *userDTO.UserBaseDTO `json:"created_user,omitempty"` - CreatedAt time.Time `json:"created_at"` - Approval *approvalDTO.ApprovalBaseDTO `json:"approval,omitempty"` + ProjectFlockKandangRelationDTO + ProjectFlock *ProjectFlockDTO `json:"project_flock,omitempty"` + Kandang *KandangDTO `json:"kandang,omitempty"` + CreatedUser *userDTO.UserRelationDTO `json:"created_user,omitempty"` + CreatedAt time.Time `json:"created_at"` + Approval *approvalDTO.ApprovalRelationDTO `json:"approval,omitempty"` } type ProjectFlockKandangDetailDTO struct { ProjectFlockKandangListDTO - Chickins []chickinDTO.ChickinBaseDTO `json:"chickins,omitempty"` - AvailableQtys []AvailableQtyDTO `json:"available_qtys,omitempty"` + Chickins []chickinDTO.ChickinRelationDTO `json:"chickins,omitempty"` + AvailableQtys []AvailableQtyDTO `json:"available_qtys,omitempty"` } // === Mapper Functions (ordered) === -func ToProjectFlockKandangBaseDTO(e entity.ProjectFlockKandang) ProjectFlockKandangBaseDTO { - return ProjectFlockKandangBaseDTO{ +func ToProjectFlockKandangRelationDTO(e entity.ProjectFlockKandang) ProjectFlockKandangRelationDTO { + return ProjectFlockKandangRelationDTO{ Id: e.Id, KandangId: e.KandangId, ProjectFlockId: e.ProjectFlockId, @@ -104,20 +104,20 @@ func ToProjectFlockKandangDetailDTOWithAvailableQty(e entity.ProjectFlockKandang return ToProjectFlockKandangDetailDTOWithAvailableQtyAndFlock(e, availableQtyMap, productWarehouses, nil) } -func ToProjectFlockKandangDetailDTOWithAvailableQtyAndFlock(e entity.ProjectFlockKandang, availableQtyMap map[uint]float64, productWarehouses []entity.ProductWarehouse, flock *flockDTO.FlockBaseDTO) ProjectFlockKandangDetailDTO { +func ToProjectFlockKandangDetailDTOWithAvailableQtyAndFlock(e entity.ProjectFlockKandang, availableQtyMap map[uint]float64, productWarehouses []entity.ProductWarehouse, flock *flockDTO.FlockRelationDTO) ProjectFlockKandangDetailDTO { var projectFlockSummary *projectFlockDTO.ProjectFlockListDTO if e.ProjectFlock.Id != 0 { - mapped := projectFlockDTO.ToProjectFlockListDTO(e.ProjectFlock, flock) + mapped := projectFlockDTO.ToProjectFlockListDTO(e.ProjectFlock) projectFlockSummary = &mapped } listDTO := ProjectFlockKandangListDTO{ - ProjectFlockKandangBaseDTO: ToProjectFlockKandangBaseDTO(e), - ProjectFlock: toProjectFlockDTO(projectFlockSummary), - Kandang: toKandangDTO(e.Kandang), - CreatedAt: e.CreatedAt, - CreatedUser: toCreatedUserDTO(e.ProjectFlock), - Approval: toApprovalDTO(e), + ProjectFlockKandangRelationDTO: ToProjectFlockKandangRelationDTO(e), + ProjectFlock: toProjectFlockDTO(projectFlockSummary), + Kandang: toKandangDTO(e.Kandang), + CreatedAt: e.CreatedAt, + CreatedUser: toCreatedUserDTO(e.ProjectFlock), + Approval: toApprovalDTO(e), } return ProjectFlockKandangDetailDTO{ @@ -139,18 +139,18 @@ func toKandangDTO(kandang entity.Kandang) *KandangDTO { } } -func toFlockDTO(flock *entity.Flock) *flockDTO.FlockBaseDTO { - if flock == nil || flock.Id == 0 { - return nil - } +// func toFlockDTO(flock *entity.Flock) *flockDTO.FlockRelationDTO { +// if flock == nil || flock.Id == 0 { +// return nil +// } - return &flockDTO.FlockBaseDTO{ - Id: flock.Id, - Name: flock.Name, - } -} +// return &flockDTO.FlockRelationDTO{ +// Id: flock.Id, +// Name: flock.Name, +// } +// } -func toApprovalDTO(e entity.ProjectFlockKandang) *approvalDTO.ApprovalBaseDTO { +func toApprovalDTO(e entity.ProjectFlockKandang) *approvalDTO.ApprovalRelationDTO { if e.LatestApproval != nil { mapped := approvalDTO.ToApprovalDTO(*e.LatestApproval) return &mapped @@ -162,7 +162,7 @@ func ToProjectFlockKandangListDTO(e entity.ProjectFlockKandang) ProjectFlockKand return ToProjectFlockKandangListDTOWithFlock(e, nil) } -func ToProjectFlockKandangListDTOWithFlock(e entity.ProjectFlockKandang, flock *flockDTO.FlockBaseDTO) ProjectFlockKandangListDTO { +func ToProjectFlockKandangListDTOWithFlock(e entity.ProjectFlockKandang, flock *flockDTO.FlockRelationDTO) ProjectFlockKandangListDTO { var projectFlockSummary *projectFlockDTO.ProjectFlockListDTO if e.ProjectFlock.Id != 0 { mapped := projectFlockDTO.ToProjectFlockListDTOWithFlock(e.ProjectFlock, flock) @@ -170,12 +170,12 @@ func ToProjectFlockKandangListDTOWithFlock(e entity.ProjectFlockKandang, flock * } return ProjectFlockKandangListDTO{ - ProjectFlockKandangBaseDTO: ToProjectFlockKandangBaseDTO(e), - ProjectFlock: toProjectFlockDTO(projectFlockSummary), - Kandang: toKandangDTO(e.Kandang), - CreatedAt: e.CreatedAt, - CreatedUser: toCreatedUserDTO(e.ProjectFlock), - Approval: toApprovalDTO(e), + ProjectFlockKandangRelationDTO: ToProjectFlockKandangRelationDTO(e), + ProjectFlock: toProjectFlockDTO(projectFlockSummary), + Kandang: toKandangDTO(e.Kandang), + CreatedAt: e.CreatedAt, + CreatedUser: toCreatedUserDTO(e.ProjectFlock), + Approval: toApprovalDTO(e), } } @@ -187,12 +187,12 @@ func ToProjectFlockKandangListDTOs(e []entity.ProjectFlockKandang) []ProjectFloc return result } -func toCreatedUserDTO(pf entity.ProjectFlock) *userDTO.UserBaseDTO { +func toCreatedUserDTO(pf entity.ProjectFlock) *userDTO.UserRelationDTO { if pf.CreatedUser.Id != 0 { - mapped := userDTO.ToUserBaseDTO(pf.CreatedUser) + mapped := userDTO.ToUserRelationDTO(pf.CreatedUser) return &mapped } else if pf.CreatedBy != 0 { - return &userDTO.UserBaseDTO{ + return &userDTO.UserRelationDTO{ Id: pf.CreatedBy, IdUser: int64(pf.CreatedBy), } @@ -200,14 +200,14 @@ func toCreatedUserDTO(pf entity.ProjectFlock) *userDTO.UserBaseDTO { return nil } -func toChickinDTOs(chickins []entity.ProjectChickin) []chickinDTO.ChickinBaseDTO { +func toChickinDTOs(chickins []entity.ProjectChickin) []chickinDTO.ChickinRelationDTO { if len(chickins) == 0 { return nil } - result := make([]chickinDTO.ChickinBaseDTO, len(chickins)) + result := make([]chickinDTO.ChickinRelationDTO, len(chickins)) for i, ch := range chickins { - result[i] = chickinDTO.ToChickinBaseDTO(ch) + result[i] = chickinDTO.ToChickinRelationDTO(ch) } return result } diff --git a/internal/modules/production/project-flock-kandangs/services/project_flock_kandang.service.go b/internal/modules/production/project-flock-kandangs/services/project_flock_kandang.service.go index ec61a7e4..6e28a245 100644 --- a/internal/modules/production/project-flock-kandangs/services/project_flock_kandang.service.go +++ b/internal/modules/production/project-flock-kandangs/services/project_flock_kandang.service.go @@ -21,8 +21,8 @@ import ( ) type ProjectFlockKandangService interface { - GetAll(ctx *fiber.Ctx, params *validation.Query) ([]entity.ProjectFlockKandang, int64, map[uint]*flockDTO.FlockBaseDTO, error) - GetOne(ctx *fiber.Ctx, id uint) (*entity.ProjectFlockKandang, map[uint]float64, []entity.ProductWarehouse, *flockDTO.FlockBaseDTO, error) + GetAll(ctx *fiber.Ctx, params *validation.Query) ([]entity.ProjectFlockKandang, int64, map[uint]*flockDTO.FlockRelationDTO, error) + GetOne(ctx *fiber.Ctx, id uint) (*entity.ProjectFlockKandang, map[uint]float64, []entity.ProductWarehouse, *flockDTO.FlockRelationDTO, error) } // Note: map[uint]float64 adalah mapping dari ProductWarehouse ID ke calculated available quantity @@ -51,7 +51,7 @@ func NewProjectFlockKandangService(repo repository.ProjectFlockKandangRepository } } -func (s projectFlockKandangService) GetAll(c *fiber.Ctx, params *validation.Query) ([]entity.ProjectFlockKandang, int64, map[uint]*flockDTO.FlockBaseDTO, error) { +func (s projectFlockKandangService) GetAll(c *fiber.Ctx, params *validation.Query) ([]entity.ProjectFlockKandang, int64, map[uint]*flockDTO.FlockRelationDTO, error) { if err := s.Validate.Struct(params); err != nil { return nil, 0, nil, err } @@ -85,7 +85,7 @@ func (s projectFlockKandangService) GetAll(c *fiber.Ctx, params *validation.Quer } } - flockMap := make(map[uint]*flockDTO.FlockBaseDTO) + flockMap := make(map[uint]*flockDTO.FlockRelationDTO) for i := range projectFlockKandangs { if projectFlockKandangs[i].ProjectFlock.Id != 0 { baseName := pfutils.DeriveBaseName(projectFlockKandangs[i].ProjectFlock.FlockName) @@ -95,7 +95,7 @@ func (s projectFlockKandangService) GetAll(c *fiber.Ctx, params *validation.Quer s.Log.Warnf("Failed to fetch flock %q: %+v", baseName, err) } else if flock != nil { - flockMap[projectFlockKandangs[i].ProjectFlock.Id] = &flockDTO.FlockBaseDTO{ + flockMap[projectFlockKandangs[i].ProjectFlock.Id] = &flockDTO.FlockRelationDTO{ Id: flock.Id, Name: flock.Name, } @@ -107,7 +107,7 @@ func (s projectFlockKandangService) GetAll(c *fiber.Ctx, params *validation.Quer return projectFlockKandangs, total, flockMap, nil } -func (s projectFlockKandangService) GetOne(c *fiber.Ctx, id uint) (*entity.ProjectFlockKandang, map[uint]float64, []entity.ProductWarehouse, *flockDTO.FlockBaseDTO, error) { +func (s projectFlockKandangService) GetOne(c *fiber.Ctx, id uint) (*entity.ProjectFlockKandang, map[uint]float64, []entity.ProductWarehouse, *flockDTO.FlockRelationDTO, error) { projectFlockKandang, err := s.Repository.GetByID(c.Context(), id) if errors.Is(err, gorm.ErrRecordNotFound) { return nil, nil, nil, nil, fiber.NewError(fiber.StatusNotFound, "ProjectFlockKandang not found") @@ -147,7 +147,7 @@ func (s projectFlockKandangService) GetOne(c *fiber.Ctx, id uint) (*entity.Proje productWarehouses = []entity.ProductWarehouse{} } } - var flockResult *flockDTO.FlockBaseDTO + var flockResult *flockDTO.FlockRelationDTO if projectFlockKandang.ProjectFlock.Id != 0 { baseName := pfutils.DeriveBaseName(projectFlockKandang.ProjectFlock.FlockName) if baseName != "" { @@ -155,7 +155,7 @@ func (s projectFlockKandangService) GetOne(c *fiber.Ctx, id uint) (*entity.Proje if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) { s.Log.Warnf("Failed to fetch flock %q: %+v", baseName, err) } else if flock != nil { - flockResult = &flockDTO.FlockBaseDTO{ + flockResult = &flockDTO.FlockRelationDTO{ Id: flock.Id, Name: flock.Name, } diff --git a/internal/modules/production/project_flocks/controllers/projectflock.controller.go b/internal/modules/production/project_flocks/controllers/projectflock.controller.go index 13b46cfd..5d51b985 100644 --- a/internal/modules/production/project_flocks/controllers/projectflock.controller.go +++ b/internal/modules/production/project_flocks/controllers/projectflock.controller.go @@ -7,7 +7,6 @@ import ( "strconv" "strings" - flockDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/flocks/dto" "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/dto" service "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/services" validation "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/validations" @@ -85,7 +84,7 @@ func (u *ProjectflockController) GetAll(c *fiber.Ctx) error { query.KandangIds = ids } - result, totalResults, flockMap, err := u.ProjectflockService.GetAll(c, query) + result, totalResults, _, err := u.ProjectflockService.GetAll(c, query) if err != nil { return err } @@ -124,7 +123,7 @@ func (u *ProjectflockController) GetOne(c *fiber.Ctx) error { return fiber.NewError(fiber.StatusBadRequest, "Invalid Id") } - result, flock, err := u.ProjectflockService.GetOne(c, uint(id)) + result, _, err := u.ProjectflockService.GetOne(c, uint(id)) if err != nil { return err } @@ -162,7 +161,7 @@ func (u *ProjectflockController) CreateOne(c *fiber.Ctx) error { Code: fiber.StatusCreated, Status: "success", Message: "Create projectflock successfully", - Data: dto.ToProjectFlockListDTO(*result, nil), + Data: dto.ToProjectFlockListDTO(*result), }) } @@ -189,7 +188,7 @@ func (u *ProjectflockController) UpdateOne(c *fiber.Ctx) error { Code: fiber.StatusOK, Status: "success", Message: "Update projectflock successfully", - Data: dto.ToProjectFlockListDTO(*result, nil), + Data: dto.ToProjectFlockListDTO(*result), }) } diff --git a/internal/modules/production/project_flocks/dto/projectflock.dto.go b/internal/modules/production/project_flocks/dto/projectflock.dto.go index 24b673d6..f2bc95df 100644 --- a/internal/modules/production/project_flocks/dto/projectflock.dto.go +++ b/internal/modules/production/project_flocks/dto/projectflock.dto.go @@ -17,28 +17,28 @@ import ( approvalutils "gitlab.com/mbugroup/lti-api.git/internal/utils/approvals" ) -type ProjectFlockBaseDTO struct { +type ProjectFlockRelationDTO struct { Id uint `json:"id"` Period int `json:"period"` FlockName string `json:"flock_name"` } type ProjectFlockListDTO struct { - ProjectFlockBaseDTO - Flock *flockDTO.FlockBaseDTO `json:"flock,omitempty"` - Area *areaDTO.AreaBaseDTO `json:"area,omitempty"` - Category string `json:"category"` - Fcr *fcrDTO.FcrBaseDTO `json:"fcr,omitempty"` - Location *locationDTO.LocationBaseDTO `json:"location,omitempty"` - Kandangs []KandangWithProjectFlockIdDTO `json:"kandangs,omitempty"` - CreatedUser *userDTO.UserBaseDTO `json:"created_user"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` - Approval approvalDTO.ApprovalBaseDTO `json:"approval"` + ProjectFlockRelationDTO + Flock *flockDTO.FlockRelationDTO `json:"flock,omitempty"` + Area *areaDTO.AreaRelationDTO `json:"area,omitempty"` + Category string `json:"category"` + Fcr *fcrDTO.FcrRelationDTO `json:"fcr,omitempty"` + Location *locationDTO.LocationRelationDTO `json:"location,omitempty"` + Kandangs []KandangWithProjectFlockIdDTO `json:"kandangs,omitempty"` + CreatedUser *userDTO.UserRelationDTO `json:"created_user"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + Approval approvalDTO.ApprovalRelationDTO `json:"approval"` } type KandangWithProjectFlockIdDTO struct { - kandangDTO.KandangBaseDTO + kandangDTO.KandangRelationDTO ProjectFlockKandangId uint `json:"project_flock_kandang_id"` } @@ -47,8 +47,8 @@ type ProjectFlockDetailDTO struct { } type FlockPeriodDTO struct { - Flock flockDTO.FlockBaseDTO `json:"flock"` - NextPeriod int `json:"next_period"` + Flock flockDTO.FlockRelationDTO `json:"flock"` + NextPeriod int `json:"next_period"` } type KandangPeriodSummaryDTO struct { @@ -58,9 +58,9 @@ type KandangPeriodSummaryDTO struct { } func ToProjectFlockListDTOWithPeriod(e entity.ProjectFlock, period int) ProjectFlockListDTO { - var createdUser *userDTO.UserBaseDTO + var createdUser *userDTO.UserRelationDTO if e.CreatedUser.Id != 0 { - mapped := userDTO.ToUserBaseDTO(e.CreatedUser) + mapped := userDTO.ToUserRelationDTO(e.CreatedUser) createdUser = &mapped } @@ -77,34 +77,34 @@ func ToProjectFlockListDTOWithPeriod(e entity.ProjectFlock, period int) ProjectF } } kandangSummaries[i] = KandangWithProjectFlockIdDTO{ - KandangBaseDTO: kandangDTO.ToKandangBaseDTO(kandang), + KandangRelationDTO: kandangDTO.ToKandangRelationDTO(kandang), ProjectFlockKandangId: pfkId, } } } - var areaSummary *areaDTO.AreaBaseDTO + var areaSummary *areaDTO.AreaRelationDTO if e.Area.Id != 0 { - mapped := areaDTO.ToAreaBaseDTO(e.Area) + mapped := areaDTO.ToAreaRelationDTO(e.Area) areaSummary = &mapped } - var fcrSummary *fcrDTO.FcrBaseDTO + var fcrSummary *fcrDTO.FcrRelationDTO if e.Fcr.Id != 0 { - mapped := fcrDTO.ToFcrBaseDTO(e.Fcr) + mapped := fcrDTO.ToFcrRelationDTO(e.Fcr) fcrSummary = &mapped } - var locationSummary *locationDTO.LocationBaseDTO + var locationSummary *locationDTO.LocationRelationDTO if e.Location.Id != 0 { - mapped := locationDTO.ToLocationBaseDTO(e.Location) + mapped := locationDTO.ToLocationRelationDTO(e.Location) locationSummary = &mapped } - var flockSummary *flockDTO.FlockBaseDTO - if flock != nil && flock.Id != 0 { - flockSummary = flock - } + // var flockSummary *flockDTO.FlockRelationDTO + // if flock != nil && flock.Id != 0 { + // flockSummary = flock + // } latestApproval := defaultProjectFlockLatestApproval(e) if e.LatestApproval != nil { @@ -113,7 +113,7 @@ func ToProjectFlockListDTOWithPeriod(e entity.ProjectFlock, period int) ProjectF } return ProjectFlockListDTO{ - ProjectFlockBaseDTO: createProjectFlockBaseDTO(e, period), + ProjectFlockRelationDTO: createProjectFlockRelationDTO(e, period), // Flock: flockSummary, Area: areaSummary, Kandangs: kandangSummaries, @@ -127,8 +127,8 @@ func ToProjectFlockListDTOWithPeriod(e entity.ProjectFlock, period int) ProjectF } } -func ToProjectFlockListDTOWithFlock(e entity.ProjectFlock, flock *flockDTO.FlockBaseDTO) ProjectFlockListDTO { - return ToProjectFlockListDTO(e, flock) +func ToProjectFlockListDTOWithFlock(e entity.ProjectFlock, flock *flockDTO.FlockRelationDTO) ProjectFlockListDTO { + return ToProjectFlockListDTO(e) } func ToProjectFlockListDTOs(items []entity.ProjectFlock) []ProjectFlockListDTO { @@ -160,10 +160,10 @@ func ToProjectFlockListDTOsWithPeriods(items []entity.ProjectFlock, periods map[ func ToProjectFlockListDTOsWithFlocks(items []entity.ProjectFlock, flocks map[uint]*entity.Flock) []ProjectFlockListDTO { result := make([]ProjectFlockListDTO, len(items)) for i, item := range items { - var flock *flockDTO.FlockBaseDTO + var flock *flockDTO.FlockRelationDTO if flocks != nil { if f := flocks[item.Id]; f != nil { - flock = &flockDTO.FlockBaseDTO{ + flock = &flockDTO.FlockRelationDTO{ Id: f.Id, Name: f.Name, } @@ -174,14 +174,14 @@ func ToProjectFlockListDTOsWithFlocks(items []entity.ProjectFlock, flocks map[ui return result } -func ToProjectFlockDetailDTO(e entity.ProjectFlock, flock *flockDTO.FlockBaseDTO) ProjectFlockDetailDTO { +func ToProjectFlockDetailDTO(e entity.ProjectFlock, flock *flockDTO.FlockRelationDTO) ProjectFlockDetailDTO { return ProjectFlockDetailDTO{ ProjectFlockListDTO: ToProjectFlockListDTOWithPeriod(e, 0), } } -func defaultProjectFlockLatestApproval(e entity.ProjectFlock) approvalDTO.ApprovalBaseDTO { - result := approvalDTO.ApprovalBaseDTO{} +func defaultProjectFlockLatestApproval(e entity.ProjectFlock) approvalDTO.ApprovalRelationDTO { + result := approvalDTO.ApprovalRelationDTO{} step := utils.ProjectFlockStepPengajuan if step > 0 { @@ -194,9 +194,9 @@ func defaultProjectFlockLatestApproval(e entity.ProjectFlock) approvalDTO.Approv } if e.CreatedUser.Id != 0 { - result.ActionBy = userDTO.ToUserBaseDTO(e.CreatedUser) + result.ActionBy = userDTO.ToUserRelationDTO(e.CreatedUser) } else if e.CreatedBy != 0 { - result.ActionBy = userDTO.UserBaseDTO{ + result.ActionBy = userDTO.UserRelationDTO{ Id: e.CreatedBy, IdUser: int64(e.CreatedBy), } @@ -205,16 +205,16 @@ func defaultProjectFlockLatestApproval(e entity.ProjectFlock) approvalDTO.Approv return result } -func createProjectFlockBaseDTO(e entity.ProjectFlock, period int) ProjectFlockBaseDTO { - return ProjectFlockBaseDTO{ +func createProjectFlockRelationDTO(e entity.ProjectFlock, period int) ProjectFlockRelationDTO { + return ProjectFlockRelationDTO{ Id: e.Id, Period: period, FlockName: e.FlockName, } } -func ToFlockSummaryDTO(e entity.Flock) flockDTO.FlockBaseDTO { - return flockDTO.FlockBaseDTO{ +func ToFlockSummaryDTO(e entity.Flock) flockDTO.FlockRelationDTO { + return flockDTO.FlockRelationDTO{ Id: e.Id, Name: e.Name, } diff --git a/internal/modules/production/project_flocks/dto/projectflock_kandang.dto.go b/internal/modules/production/project_flocks/dto/projectflock_kandang.dto.go index 2e25bf09..416c7821 100644 --- a/internal/modules/production/project_flocks/dto/projectflock_kandang.dto.go +++ b/internal/modules/production/project_flocks/dto/projectflock_kandang.dto.go @@ -12,35 +12,35 @@ import ( ) type KandangWithPivotDTO struct { - kandangDTO.KandangBaseDTO + kandangDTO.KandangRelationDTO AvailableQuantity float64 `json:"available_quantity"` } type ProjectFlockWithPivotDTO struct { - ProjectFlockBaseDTO - Flock *flockDTO.FlockBaseDTO `json:"flock,omitempty"` - Area *areaDTO.AreaBaseDTO `json:"area,omitempty"` - Category string `json:"category"` - Fcr *fcrDTO.FcrBaseDTO `json:"fcr,omitempty"` - Location *locationDTO.LocationBaseDTO `json:"location,omitempty"` - Kandangs []KandangWithPivotDTO `json:"kandangs,omitempty"` - CreatedUser *userDTO.UserBaseDTO `json:"created_user,omitempty"` + ProjectFlockRelationDTO + Flock *flockDTO.FlockRelationDTO `json:"flock,omitempty"` + Area *areaDTO.AreaRelationDTO `json:"area,omitempty"` + Category string `json:"category"` + Fcr *fcrDTO.FcrRelationDTO `json:"fcr,omitempty"` + Location *locationDTO.LocationRelationDTO `json:"location,omitempty"` + Kandangs []KandangWithPivotDTO `json:"kandangs,omitempty"` + CreatedUser *userDTO.UserRelationDTO `json:"created_user,omitempty"` } type ProjectFlockKandangDTO struct { - Id uint `json:"id"` - ProjectFlockKandangId uint `json:"project_flock_kandang_id"` - ProjectFlockId uint `json:"project_flock_id"` - KandangId uint `json:"kandang_id"` - Kandang *kandangDTO.KandangBaseDTO `json:"kandang,omitempty"` - ProjectFlock *ProjectFlockWithPivotDTO `json:"project_flock,omitempty"` - AvailableQuantity float64 `json:"available_quantity"` + Id uint `json:"id"` + ProjectFlockKandangId uint `json:"project_flock_kandang_id"` + ProjectFlockId uint `json:"project_flock_id"` + KandangId uint `json:"kandang_id"` + Kandang *kandangDTO.KandangRelationDTO `json:"kandang,omitempty"` + ProjectFlock *ProjectFlockWithPivotDTO `json:"project_flock,omitempty"` + AvailableQuantity float64 `json:"available_quantity"` } func ToProjectFlockKandangDTO(e entity.ProjectFlockKandang) ProjectFlockKandangDTO { - var kandang *kandangDTO.KandangBaseDTO + var kandang *kandangDTO.KandangRelationDTO if e.Kandang.Id != 0 { - mapped := kandangDTO.ToKandangBaseDTO(e.Kandang) + mapped := kandangDTO.ToKandangRelationDTO(e.Kandang) kandang = &mapped } @@ -48,7 +48,7 @@ func ToProjectFlockKandangDTO(e entity.ProjectFlockKandang) ProjectFlockKandangD if e.ProjectFlock.Id != 0 { pfLocal := ProjectFlockWithPivotDTO{ - ProjectFlockBaseDTO: ProjectFlockBaseDTO{ + ProjectFlockRelationDTO: ProjectFlockRelationDTO{ Id: e.ProjectFlock.Id, Period: e.Period, FlockName: e.ProjectFlock.FlockName, @@ -57,31 +57,31 @@ func ToProjectFlockKandangDTO(e entity.ProjectFlockKandang) ProjectFlockKandangD } if base := pfutils.DeriveBaseName(e.ProjectFlock.FlockName); base != "" { - summary := flockDTO.FlockBaseDTO{Id: 0, Name: base} + summary := flockDTO.FlockRelationDTO{Id: 0, Name: base} pfLocal.Flock = &summary } if e.ProjectFlock.Area.Id != 0 { - mapped := areaDTO.ToAreaBaseDTO(e.ProjectFlock.Area) + mapped := areaDTO.ToAreaRelationDTO(e.ProjectFlock.Area) pfLocal.Area = &mapped } if e.ProjectFlock.Fcr.Id != 0 { - mapped := fcrDTO.ToFcrBaseDTO(e.ProjectFlock.Fcr) + mapped := fcrDTO.ToFcrRelationDTO(e.ProjectFlock.Fcr) pfLocal.Fcr = &mapped } if e.ProjectFlock.Location.Id != 0 { - mapped := locationDTO.ToLocationBaseDTO(e.ProjectFlock.Location) + mapped := locationDTO.ToLocationRelationDTO(e.ProjectFlock.Location) pfLocal.Location = &mapped } if e.ProjectFlock.CreatedUser.Id != 0 { - mapped := userDTO.ToUserBaseDTO(e.ProjectFlock.CreatedUser) + mapped := userDTO.ToUserRelationDTO(e.ProjectFlock.CreatedUser) pfLocal.CreatedUser = &mapped } for _, k := range e.ProjectFlock.Kandangs { - kb := kandangDTO.ToKandangBaseDTO(k) + kb := kandangDTO.ToKandangRelationDTO(k) pfLocal.Kandangs = append(pfLocal.Kandangs, KandangWithPivotDTO{ - KandangBaseDTO: kb, - AvailableQuantity: 0, + KandangRelationDTO: kb, + AvailableQuantity: 0, }) } diff --git a/internal/modules/production/project_flocks/services/projectflock.service.go b/internal/modules/production/project_flocks/services/projectflock.service.go index d7dc5ad8..f6fa2638 100644 --- a/internal/modules/production/project_flocks/services/projectflock.service.go +++ b/internal/modules/production/project_flocks/services/projectflock.service.go @@ -29,8 +29,8 @@ import ( ) type ProjectflockService interface { - GetAll(ctx *fiber.Ctx, params *validation.Query) ([]entity.ProjectFlock, int64, map[uint]*flockDTO.FlockBaseDTO, error) - GetOne(ctx *fiber.Ctx, id uint) (*entity.ProjectFlock, *flockDTO.FlockBaseDTO, error) + GetAll(ctx *fiber.Ctx, params *validation.Query) ([]entity.ProjectFlock, int64, map[uint]*flockDTO.FlockRelationDTO, error) + GetOne(ctx *fiber.Ctx, id uint) (*entity.ProjectFlock, *flockDTO.FlockRelationDTO, error) CreateOne(ctx *fiber.Ctx, req *validation.Create) (*entity.ProjectFlock, error) UpdateOne(ctx *fiber.Ctx, req *validation.Update, id uint) (*entity.ProjectFlock, error) GetAvailableDocQuantity(ctx *fiber.Ctx, kandangID uint) (float64, error) @@ -96,7 +96,7 @@ func (s projectflockService) withRelations(db *gorm.DB) *gorm.DB { Preload("KandangHistory.Kandang") } -func (s projectflockService) GetAll(c *fiber.Ctx, params *validation.Query) ([]entity.ProjectFlock, int64, map[uint]*flockDTO.FlockBaseDTO, error) { +func (s projectflockService) GetAll(c *fiber.Ctx, params *validation.Query) ([]entity.ProjectFlock, int64, map[uint]*flockDTO.FlockRelationDTO, error) { if err := s.Validate.Struct(params); err != nil { return nil, 0, nil, err } @@ -137,7 +137,7 @@ func (s projectflockService) GetAll(c *fiber.Ctx, params *validation.Query) ([]e } } - flockMap := make(map[uint]*flockDTO.FlockBaseDTO) + flockMap := make(map[uint]*flockDTO.FlockRelationDTO) for i := range projectflocks { if projectflocks[i].FlockName != "" { baseName := pfutils.DeriveBaseName(projectflocks[i].FlockName) @@ -146,7 +146,7 @@ func (s projectflockService) GetAll(c *fiber.Ctx, params *validation.Query) ([]e if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) { s.Log.Warnf("Failed to fetch flock %q: %+v", baseName, err) } else if flock != nil { - flockMap[projectflocks[i].Id] = &flockDTO.FlockBaseDTO{ + flockMap[projectflocks[i].Id] = &flockDTO.FlockRelationDTO{ Id: flock.Id, Name: flock.Name, } @@ -187,7 +187,7 @@ func (s projectflockService) getOneEntityOnly(c *fiber.Ctx, id uint) (*entity.Pr return projectflock, nil } -func (s projectflockService) GetOne(c *fiber.Ctx, id uint) (*entity.ProjectFlock, *flockDTO.FlockBaseDTO, error) { +func (s projectflockService) GetOne(c *fiber.Ctx, id uint) (*entity.ProjectFlock, *flockDTO.FlockRelationDTO, error) { projectflock, err := s.Repository.GetByID(c.Context(), id, s.Repository.WithDefaultRelations()) if errors.Is(err, gorm.ErrRecordNotFound) { return nil, nil, fiber.NewError(fiber.StatusNotFound, "Projectflock not found") @@ -214,7 +214,7 @@ func (s projectflockService) GetOne(c *fiber.Ctx, id uint) (*entity.ProjectFlock } // Fetch Flock master data for this ProjectFlock - var flockResult *flockDTO.FlockBaseDTO + var flockResult *flockDTO.FlockRelationDTO if projectflock.FlockName != "" { baseName := pfutils.DeriveBaseName(projectflock.FlockName) if baseName != "" { @@ -222,7 +222,7 @@ func (s projectflockService) GetOne(c *fiber.Ctx, id uint) (*entity.ProjectFlock if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) { s.Log.Warnf("Failed to fetch flock %q: %+v", baseName, err) } else if flock != nil { - flockResult = &flockDTO.FlockBaseDTO{ + flockResult = &flockDTO.FlockRelationDTO{ Id: flock.Id, Name: flock.Name, } diff --git a/internal/modules/production/recordings/dto/recording.dto.go b/internal/modules/production/recordings/dto/recording.dto.go index 21fccd41..f7cc4ee2 100644 --- a/internal/modules/production/recordings/dto/recording.dto.go +++ b/internal/modules/production/recordings/dto/recording.dto.go @@ -15,30 +15,30 @@ import ( // === DTO Structs === -type RecordingBaseDTO struct { - Id uint `json:"id"` - ProjectFlockKandangId uint `json:"project_flock_kandang_id"` - RecordDatetime time.Time `json:"record_datetime"` - Day int `json:"day"` - ProjectFlockCategory string `json:"project_flock_category"` - TotalDepletionQty float64 `json:"total_depletion_qty"` - CumDepletionRate float64 `json:"cum_depletion_rate"` - DailyGain float64 `json:"daily_gain"` - AvgDailyGain float64 `json:"avg_daily_gain"` - CumIntake int `json:"cum_intake"` - FcrValue float64 `json:"fcr_value"` - TotalChickQty float64 `json:"total_chick_qty"` - Approval approvalDTO.ApprovalBaseDTO `json:"approval"` - EggGradingStatus *string `json:"egg_grading_status"` - EggGradingPendingQty *int `json:"egg_grading_pending_qty"` - EggGradingCompletedQty *int `json:"egg_grading_completed_qty"` +type RecordingRelationDTO struct { + Id uint `json:"id"` + ProjectFlockKandangId uint `json:"project_flock_kandang_id"` + RecordDatetime time.Time `json:"record_datetime"` + Day int `json:"day"` + ProjectFlockCategory string `json:"project_flock_category"` + TotalDepletionQty float64 `json:"total_depletion_qty"` + CumDepletionRate float64 `json:"cum_depletion_rate"` + DailyGain float64 `json:"daily_gain"` + AvgDailyGain float64 `json:"avg_daily_gain"` + CumIntake int `json:"cum_intake"` + FcrValue float64 `json:"fcr_value"` + TotalChickQty float64 `json:"total_chick_qty"` + Approval approvalDTO.ApprovalRelationDTO `json:"approval"` + EggGradingStatus *string `json:"egg_grading_status"` + EggGradingPendingQty *int `json:"egg_grading_pending_qty"` + EggGradingCompletedQty *int `json:"egg_grading_completed_qty"` } type RecordingListDTO struct { - RecordingBaseDTO - CreatedUser *userDTO.UserBaseDTO `json:"created_user"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` + RecordingRelationDTO + CreatedUser *userDTO.UserRelationDTO `json:"created_user"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` } type RecordingDetailDTO struct { @@ -91,7 +91,7 @@ type RecordingEggGradingDTO struct { // === Mapper Functions === -func ToRecordingBaseDTO(e entity.Recording) RecordingBaseDTO { +func ToRecordingRelationDTO(e entity.Recording) RecordingRelationDTO { var ( projectFlockCategory string day int @@ -142,7 +142,7 @@ func ToRecordingBaseDTO(e entity.Recording) RecordingBaseDTO { gradingStatus, gradingPending, gradingCompleted := computeEggGradingStatus(e) - return RecordingBaseDTO{ + return RecordingRelationDTO{ Id: e.Id, ProjectFlockKandangId: e.ProjectFlockKandangId, RecordDatetime: e.RecordDatetime, @@ -163,17 +163,17 @@ func ToRecordingBaseDTO(e entity.Recording) RecordingBaseDTO { } func ToRecordingListDTO(e entity.Recording) RecordingListDTO { - var createdUser *userDTO.UserBaseDTO + var createdUser *userDTO.UserRelationDTO if e.CreatedUser != nil && e.CreatedUser.Id != 0 { - mapped := userDTO.ToUserBaseDTO(*e.CreatedUser) + mapped := userDTO.ToUserRelationDTO(*e.CreatedUser) createdUser = &mapped } return RecordingListDTO{ - RecordingBaseDTO: ToRecordingBaseDTO(e), - CreatedAt: e.CreatedAt, - UpdatedAt: e.UpdatedAt, - CreatedUser: createdUser, + RecordingRelationDTO: ToRecordingRelationDTO(e), + CreatedAt: e.CreatedAt, + UpdatedAt: e.UpdatedAt, + CreatedUser: createdUser, } } @@ -344,8 +344,8 @@ func filterGoodEggs(eggs []entity.RecordingEgg) []entity.RecordingEgg { return result } -func defaultRecordingLatestApproval(e entity.Recording) approvalDTO.ApprovalBaseDTO { - result := approvalDTO.ApprovalBaseDTO{} +func defaultRecordingLatestApproval(e entity.Recording) approvalDTO.ApprovalRelationDTO { + result := approvalDTO.ApprovalRelationDTO{} step := utils.RecordingStepPengajuan result.StepNumber = uint16(step) @@ -356,9 +356,9 @@ func defaultRecordingLatestApproval(e entity.Recording) approvalDTO.ApprovalBase } if e.CreatedUser != nil && e.CreatedUser.Id != 0 { - result.ActionBy = userDTO.ToUserBaseDTO(*e.CreatedUser) + result.ActionBy = userDTO.ToUserRelationDTO(*e.CreatedUser) } else if e.CreatedBy != 0 { - result.ActionBy = userDTO.UserBaseDTO{ + result.ActionBy = userDTO.UserRelationDTO{ Id: e.CreatedBy, IdUser: int64(e.CreatedBy), } diff --git a/internal/modules/production/transfer_layings/dto/transfer_laying.dto.go b/internal/modules/production/transfer_layings/dto/transfer_laying.dto.go index ef537e19..aeb12e5e 100644 --- a/internal/modules/production/transfer_layings/dto/transfer_laying.dto.go +++ b/internal/modules/production/transfer_layings/dto/transfer_laying.dto.go @@ -10,7 +10,7 @@ import ( // === DTO Structs === -type TransferLayingBaseDTO struct { +type TransferLayingRelationDTO struct { Id uint `json:"id"` TransferNumber string `json:"transfer_number"` TransferDate time.Time `json:"transfer_date"` @@ -64,22 +64,22 @@ type LayingTransferTargetDTO struct { } type TransferLayingListDTO struct { - TransferLayingBaseDTO - FromProjectFlock *ProjectFlockSummaryDTO `json:"from_project_flock,omitempty"` - ToProjectFlock *ProjectFlockSummaryDTO `json:"to_project_flock,omitempty"` - PendingUsageQty *float64 `json:"pending_usage_qty"` - UsageQty *float64 `json:"usage_qty"` - CreatedBy uint `json:"created_by"` - CreatedUser *userDTO.UserBaseDTO `json:"created_user,omitempty"` - CreatedAt time.Time `json:"created_at"` - Approval *approvalDTO.ApprovalBaseDTO `json:"approval,omitempty"` + TransferLayingRelationDTO + FromProjectFlock *ProjectFlockSummaryDTO `json:"from_project_flock,omitempty"` + ToProjectFlock *ProjectFlockSummaryDTO `json:"to_project_flock,omitempty"` + PendingUsageQty *float64 `json:"pending_usage_qty"` + UsageQty *float64 `json:"usage_qty"` + CreatedBy uint `json:"created_by"` + CreatedUser *userDTO.UserRelationDTO `json:"created_user,omitempty"` + CreatedAt time.Time `json:"created_at"` + Approval *approvalDTO.ApprovalRelationDTO `json:"approval,omitempty"` } type TransferLayingDetailDTO struct { TransferLayingListDTO - Sources []LayingTransferSourceDTO `json:"sources,omitempty"` - Targets []LayingTransferTargetDTO `json:"targets,omitempty"` - Approval *approvalDTO.ApprovalBaseDTO `json:"approval,omitempty"` + Sources []LayingTransferSourceDTO `json:"sources,omitempty"` + Targets []LayingTransferTargetDTO `json:"targets,omitempty"` + Approval *approvalDTO.ApprovalRelationDTO `json:"approval,omitempty"` } // === Available Quantity DTOs === @@ -203,8 +203,8 @@ func ToLayingTransferTargetDTOs(targets []entity.LayingTransferTarget) []LayingT return result } -func ToTransferLayingBaseDTO(e entity.LayingTransfer) TransferLayingBaseDTO { - return TransferLayingBaseDTO{ +func ToTransferLayingRelationDTO(e entity.LayingTransfer) TransferLayingRelationDTO { + return TransferLayingRelationDTO{ Id: e.Id, TransferNumber: e.TransferNumber, TransferDate: e.TransferDate, @@ -213,26 +213,26 @@ func ToTransferLayingBaseDTO(e entity.LayingTransfer) TransferLayingBaseDTO { } func ToTransferLayingListDTO(e entity.LayingTransfer) TransferLayingListDTO { - var createdUser *userDTO.UserBaseDTO + var createdUser *userDTO.UserRelationDTO if e.CreatedUser != nil && e.CreatedUser.Id != 0 { - mapped := userDTO.ToUserBaseDTO(*e.CreatedUser) + mapped := userDTO.ToUserRelationDTO(*e.CreatedUser) createdUser = &mapped } return TransferLayingListDTO{ - TransferLayingBaseDTO: ToTransferLayingBaseDTO(e), - FromProjectFlock: ToProjectFlockSummaryDTO(e.FromProjectFlock), - ToProjectFlock: ToProjectFlockSummaryDTO(e.ToProjectFlock), - PendingUsageQty: e.PendingUsageQty, - UsageQty: e.UsageQty, - CreatedBy: e.CreatedBy, - CreatedUser: createdUser, - CreatedAt: e.CreatedAt, + TransferLayingRelationDTO: ToTransferLayingRelationDTO(e), + FromProjectFlock: ToProjectFlockSummaryDTO(e.FromProjectFlock), + ToProjectFlock: ToProjectFlockSummaryDTO(e.ToProjectFlock), + PendingUsageQty: e.PendingUsageQty, + UsageQty: e.UsageQty, + CreatedBy: e.CreatedBy, + CreatedUser: createdUser, + CreatedAt: e.CreatedAt, } } func ToTransferLayingDetailDTO(e entity.LayingTransfer, approvals []entity.Approval) TransferLayingDetailDTO { - var latestApproval *approvalDTO.ApprovalBaseDTO + var latestApproval *approvalDTO.ApprovalRelationDTO if e.LatestApproval != nil { mapped := approvalDTO.ToApprovalDTO(*e.LatestApproval) @@ -252,7 +252,7 @@ func ToTransferLayingDetailDTO(e entity.LayingTransfer, approvals []entity.Appro } func ToTransferLayingDetailDTOWithSingleApproval(e entity.LayingTransfer, approval *entity.Approval) TransferLayingDetailDTO { - var mappedApproval *approvalDTO.ApprovalBaseDTO + var mappedApproval *approvalDTO.ApprovalRelationDTO // Prefer LatestApproval from entity if e.LatestApproval != nil && e.LatestApproval.Id != 0 { diff --git a/internal/modules/purchases/dto/purchase.dto.go b/internal/modules/purchases/dto/purchase.dto.go index 5a2926cf..bbd59fdd 100644 --- a/internal/modules/purchases/dto/purchase.dto.go +++ b/internal/modules/purchases/dto/purchase.dto.go @@ -13,52 +13,52 @@ import ( ) type PurchaseListItemDTO struct { - Id uint64 `json:"id"` - PrNumber string `json:"pr_number"` - PoNumber *string `json:"po_number"` - Supplier *supplierDTO.SupplierBaseDTO `json:"supplier"` - CreditTerm *int `json:"credit_term"` - DueDate *time.Time `json:"due_date"` - PoDate *time.Time `json:"po_date"` - GrandTotal float64 `json:"grand_total"` - Notes *string `json:"notes"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` - Approval *approvalDTO.ApprovalBaseDTO `json:"approval"` + Id uint64 `json:"id"` + PrNumber string `json:"pr_number"` + PoNumber *string `json:"po_number"` + Supplier *supplierDTO.SupplierRelationDTO `json:"supplier"` + CreditTerm *int `json:"credit_term"` + DueDate *time.Time `json:"due_date"` + PoDate *time.Time `json:"po_date"` + GrandTotal float64 `json:"grand_total"` + Notes *string `json:"notes"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + Approval *approvalDTO.ApprovalRelationDTO `json:"approval"` } type PurchaseDetailDTO struct { - Id uint64 `json:"id"` - PrNumber string `json:"pr_number"` - PoNumber *string `json:"po_number"` - Supplier *supplierDTO.SupplierBaseDTO `json:"supplier"` - CreditTerm *int `json:"credit_term"` - DueDate *time.Time `json:"due_date"` - PoDate *time.Time `json:"po_date"` - GrandTotal float64 `json:"grand_total"` - Notes *string `json:"notes"` - Items []PurchaseItemDTO `json:"items"` - CreatedAt time.Time `json:"created_at"` - UpdatedAt time.Time `json:"updated_at"` - Approval *approvalDTO.ApprovalBaseDTO `json:"approval"` + Id uint64 `json:"id"` + PrNumber string `json:"pr_number"` + PoNumber *string `json:"po_number"` + Supplier *supplierDTO.SupplierRelationDTO `json:"supplier"` + CreditTerm *int `json:"credit_term"` + DueDate *time.Time `json:"due_date"` + PoDate *time.Time `json:"po_date"` + GrandTotal float64 `json:"grand_total"` + Notes *string `json:"notes"` + Items []PurchaseItemDTO `json:"items"` + CreatedAt time.Time `json:"created_at"` + UpdatedAt time.Time `json:"updated_at"` + Approval *approvalDTO.ApprovalRelationDTO `json:"approval"` } type PurchaseItemDTO struct { - Id uint64 `json:"id"` - ProductID uint64 `json:"product_id"` - Product *productDTO.ProductBaseDTO `json:"product"` - WarehouseID uint64 `json:"warehouse_id"` - Warehouse *warehouseDTO.WarehouseBaseDTO `json:"warehouse"` - ProductWarehouseID *uint64 `json:"product_warehouse_id"` - SubQty float64 `json:"sub_qty"` - TotalQty float64 `json:"total_qty"` - TotalUsed float64 `json:"total_used"` - Price float64 `json:"price"` - TotalPrice float64 `json:"total_price"` - ReceivedDate *time.Time `json:"received_date"` - TravelNumber *string `json:"travel_number"` - TravelDocumentPath *string `json:"travel_document_path"` - VehicleNumber *string `json:"vehicle_number"` + Id uint64 `json:"id"` + ProductID uint64 `json:"product_id"` + Product *productDTO.ProductRelationDTO `json:"product"` + WarehouseID uint64 `json:"warehouse_id"` + Warehouse *warehouseDTO.WarehouseRelationDTO `json:"warehouse"` + ProductWarehouseID *uint64 `json:"product_warehouse_id"` + SubQty float64 `json:"sub_qty"` + TotalQty float64 `json:"total_qty"` + TotalUsed float64 `json:"total_used"` + Price float64 `json:"price"` + TotalPrice float64 `json:"total_price"` + ReceivedDate *time.Time `json:"received_date"` + TravelNumber *string `json:"travel_number"` + TravelDocumentPath *string `json:"travel_document_path"` + VehicleNumber *string `json:"vehicle_number"` } func ToPurchaseItemDTO(item entity.PurchaseItem) PurchaseItemDTO { @@ -78,17 +78,17 @@ func ToPurchaseItemDTO(item entity.PurchaseItem) PurchaseItemDTO { VehicleNumber: item.VehicleNumber, } if item.Product != nil && item.Product.Id != 0 { - summary := productDTO.ToProductBaseDTO(*item.Product) + summary := productDTO.ToProductRelationDTO(*item.Product) dto.Product = &summary } if item.Warehouse != nil && item.Warehouse.Id != 0 { - summary := warehouseDTO.ToWarehouseBaseDTO(*item.Warehouse) + summary := warehouseDTO.ToWarehouseRelationDTO(*item.Warehouse) if item.Warehouse.Area.Id != 0 { - areaSummary := areaDTO.ToAreaBaseDTO(item.Warehouse.Area) + areaSummary := areaDTO.ToAreaRelationDTO(item.Warehouse.Area) summary.Area = &areaSummary } if item.Warehouse.Location != nil && item.Warehouse.Location.Id != 0 { - locationSummary := locationDTO.ToLocationBaseDTO(*item.Warehouse.Location) + locationSummary := locationDTO.ToLocationRelationDTO(*item.Warehouse.Location) summary.Location = &locationSummary } dto.Warehouse = &summary @@ -145,11 +145,11 @@ func ToPurchaseListDTO(p entity.Purchase) PurchaseListItemDTO { return dto } -func mapSupplier(s entity.Supplier) *supplierDTO.SupplierBaseDTO { +func mapSupplier(s entity.Supplier) *supplierDTO.SupplierRelationDTO { if s.Id == 0 { return nil } - summary := supplierDTO.ToSupplierBaseDTO(s) + summary := supplierDTO.ToSupplierRelationDTO(s) return &summary } @@ -164,7 +164,7 @@ func ToPurchaseListDTOs(items []entity.Purchase) []PurchaseListItemDTO { return result } -func toPurchaseApprovalDTO(p entity.Purchase) *approvalDTO.ApprovalBaseDTO { +func toPurchaseApprovalDTO(p entity.Purchase) *approvalDTO.ApprovalRelationDTO { if p.LatestApproval == nil || p.LatestApproval.Id == 0 { return nil } diff --git a/internal/modules/users/dto/user.dto.go b/internal/modules/users/dto/user.dto.go index 670a2810..b89a6724 100644 --- a/internal/modules/users/dto/user.dto.go +++ b/internal/modules/users/dto/user.dto.go @@ -8,7 +8,7 @@ import ( // === DTO Structs === -type UserBaseDTO struct { +type UserRelationDTO struct { Id uint `json:"id"` IdUser int64 `json:"id_user"` Email string `json:"email"` @@ -16,7 +16,7 @@ type UserBaseDTO struct { } type UserListDTO struct { - UserBaseDTO + UserRelationDTO CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` } @@ -27,8 +27,8 @@ type UserDetailDTO struct { // === Mapper Functions === -func ToUserBaseDTO(m entity.User) UserBaseDTO { - return UserBaseDTO{ +func ToUserRelationDTO(m entity.User) UserRelationDTO { + return UserRelationDTO{ Id: m.Id, IdUser: m.IdUser, Email: m.Email, @@ -38,9 +38,9 @@ func ToUserBaseDTO(m entity.User) UserBaseDTO { func ToUserListDTO(m entity.User) UserListDTO { return UserListDTO{ - UserBaseDTO: ToUserBaseDTO(m), - CreatedAt: m.CreatedAt, - UpdatedAt: m.UpdatedAt, + UserRelationDTO: ToUserRelationDTO(m), + CreatedAt: m.CreatedAt, + UpdatedAt: m.UpdatedAt, } } diff --git a/test/integration/master_data/area_test.go b/test/integration/master_data/area_test.go deleted file mode 100644 index ad8a17ad..00000000 --- a/test/integration/master_data/area_test.go +++ /dev/null @@ -1,27 +0,0 @@ -package test - -import ( - "net/http" - "testing" - - "github.com/gofiber/fiber/v2" -) - -func TestAreaIntegration(t *testing.T) { - app, db := setupIntegrationApp(t) - - t.Run("create area trims name", func(t *testing.T) { - areaID := createArea(t, app, " Area Trim ") - if got := fetchAreaName(t, db, areaID); got != "Area Trim" { - t.Fatalf("expected trimmed name, got %q", got) - } - }) - - t.Run("duplicate area returns conflict", func(t *testing.T) { - createArea(t, app, "Duplicate Area") - resp, body := doJSONRequest(t, app, http.MethodPost, "/api/master-data/areas", map[string]any{"name": "Duplicate Area"}) - if resp.StatusCode != fiber.StatusConflict { - t.Fatalf("expected 409 conflict, got %d: %s", resp.StatusCode, string(body)) - } - }) -} diff --git a/test/integration/master_data/bank_test.go b/test/integration/master_data/bank_test.go deleted file mode 100644 index 49a8c2a7..00000000 --- a/test/integration/master_data/bank_test.go +++ /dev/null @@ -1,127 +0,0 @@ -package test - -import ( - "encoding/json" - "errors" - "fmt" - "net/http" - "testing" - - "github.com/gofiber/fiber/v2" - "gorm.io/gorm" - - "gitlab.com/mbugroup/lti-api.git/internal/entities" -) - -func TestBankIntegration(t *testing.T) { - app, db := setupIntegrationApp(t) - - const bankAlias = "BNI" - const bankName = "Bank Negara Indonesia" - const bankOwner = "John Doe" - const bankAccountNumber = "1234567890" - var bankID uint - - t.Run("creating bank succeeds", func(t *testing.T) { - bankID = createBank(t, app, bankName, bankAlias, bankAccountNumber, bankOwner) - bank := fetchBank(t, db, bankID) - if bank.Alias != bankAlias { - t.Fatalf("expected alias %q, got %q", bankAlias, bank.Alias) - } - if bank.AccountNumber != bankAccountNumber { - t.Fatalf("expected account number %q, got %q", bankAccountNumber, bank.AccountNumber) - } - }) - - t.Run("creating bank with duplicate name fails", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodPost, "/api/master-data/banks", map[string]any{ - "name": bankName, - "alias": "NEWALIAS", - "owner": "Owner Name", - "account_number": "1122334455", - }) - if resp.StatusCode != fiber.StatusConflict { - t.Fatalf("expected 409 when creating duplicate bank name, got %d: %s", resp.StatusCode, string(body)) - } - }) - - t.Run("getting existing bank succeeds", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodGet, fmt.Sprintf("/api/master-data/banks/%d", bankID), nil) - if resp.StatusCode != fiber.StatusOK { - t.Fatalf("expected 200 when fetching bank, got %d: %s", resp.StatusCode, string(body)) - } - var payload struct { - Data struct { - Id uint `json:"id"` - Name string `json:"name"` - Alias string `json:"alias"` - AccountNumber string `json:"account_number"` - } `json:"data"` - } - if err := json.Unmarshal(body, &payload); err != nil { - t.Fatalf("failed to parse response: %v", err) - } - if payload.Data.Id != bankID { - t.Fatalf("expected id %d, got %d", bankID, payload.Data.Id) - } - if payload.Data.Alias != bankAlias { - t.Fatalf("expected alias %q, got %q", bankAlias, payload.Data.Alias) - } - if payload.Data.AccountNumber != bankAccountNumber { - t.Fatalf("expected account number %q, got %q", bankAccountNumber, payload.Data.AccountNumber) - } - }) - - const updatedName = "BNI Updated" - - t.Run("updating bank name succeeds", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodPatch, fmt.Sprintf("/api/master-data/banks/%d", bankID), map[string]any{ - "name": updatedName, - }) - if resp.StatusCode != fiber.StatusOK { - t.Fatalf("expected 200 when updating bank, got %d: %s", resp.StatusCode, string(body)) - } - var payload struct { - Data struct { - Name string `json:"name"` - } `json:"data"` - } - if err := json.Unmarshal(body, &payload); err != nil { - t.Fatalf("failed to parse response: %v", err) - } - if payload.Data.Name != updatedName { - t.Fatalf("expected updated name %q, got %q", updatedName, payload.Data.Name) - } - bank := fetchBank(t, db, bankID) - if bank.Name != updatedName { - t.Fatalf("expected persisted name %q, got %q", updatedName, bank.Name) - } - }) - - t.Run("updating non existent bank returns 404", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodPatch, "/api/master-data/banks/9999", map[string]any{ - "name": "Does Not Matter", - }) - if resp.StatusCode != fiber.StatusNotFound { - t.Fatalf("expected 404 when updating missing bank, got %d: %s", resp.StatusCode, string(body)) - } - }) - - t.Run("deleting bank succeeds", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodDelete, fmt.Sprintf("/api/master-data/banks/%d", bankID), nil) - if resp.StatusCode != fiber.StatusOK { - t.Fatalf("expected 200 when deleting bank, got %d: %s", resp.StatusCode, string(body)) - } - var bank entities.Bank - if err := db.First(&bank, bankID).Error; !errors.Is(err, gorm.ErrRecordNotFound) { - t.Fatalf("expected bank to be deleted, got error %v", err) - } - }) - - t.Run("deleting non existent bank returns 404", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodDelete, fmt.Sprintf("/api/master-data/banks/%d", bankID), nil) - if resp.StatusCode != fiber.StatusNotFound { - t.Fatalf("expected 404 when deleting missing bank, got %d: %s", resp.StatusCode, string(body)) - } - }) -} diff --git a/test/integration/master_data/customer_test.go b/test/integration/master_data/customer_test.go deleted file mode 100644 index f3b3dbed..00000000 --- a/test/integration/master_data/customer_test.go +++ /dev/null @@ -1,189 +0,0 @@ -package test - -import ( - "encoding/json" - "errors" - "fmt" - "net/http" - "testing" - - "github.com/gofiber/fiber/v2" - "gorm.io/gorm" - - "gitlab.com/mbugroup/lti-api.git/internal/entities" - "gitlab.com/mbugroup/lti-api.git/internal/utils" -) - -func TestCustomerIntegration(t *testing.T) { - app, db := setupIntegrationApp(t) - - t.Run("creating customer without existing pic fails", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodPost, "/api/master-data/customers", map[string]any{ - "name": "Invalid Customer", - "pic_id": 9999, - "type": utils.CustomerSupplierTypeBisnis, - "address": "Somewhere", - "phone": "0800000000", - "email": "Invalid@example.com", - "account_number": "ACC-INVALID", - }) - if resp.StatusCode != fiber.StatusNotFound { - t.Fatalf("expected 404 when pic is missing, got %d: %s", resp.StatusCode, string(body)) - } - }) - - t.Run("creating customer with Invalid type fails", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodPost, "/api/master-data/customers", map[string]any{ - "name": "Invalid Type", - "pic_id": 1, - "type": "UNKNOWN", - "address": "Somewhere", - "phone": "081234567891", - "email": "Invalid-type@example.com", - "account_number": "ACC-INVALID-TYPE", - }) - if resp.StatusCode != fiber.StatusBadRequest { - t.Fatalf("expected 400 when type is Invalid, got %d: %s", resp.StatusCode, string(body)) - } - }) - - const customerName = "Customer Alpha" - var customerID uint - - t.Run("creating customer succeeds", func(t *testing.T) { - customerID = createCustomer(t, app, customerName, 1) - customer := fetchCustomer(t, db, customerID) - if customer.Name != customerName { - t.Fatalf("expected name %q, got %q", customerName, customer.Name) - } - if customer.PicId != 1 { - t.Fatalf("expected pic id 1, got %d", customer.PicId) - } - if customer.Type != string(utils.CustomerSupplierTypeBisnis) { - t.Fatalf("expected type %q, got %q", utils.CustomerSupplierTypeBisnis, customer.Type) - } - }) - - t.Run("creating customer with duplicate name fails", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodPost, "/api/master-data/customers", map[string]any{ - "name": customerName, - "pic_id": 1, - "type": utils.CustomerSupplierTypeBisnis, - "address": "Duplicate address", - "phone": "0811111111", - "email": "duplicate@example.com", - "account_number": "ACC-DUP", - }) - if resp.StatusCode != fiber.StatusConflict { - t.Fatalf("expected 409 when creating duplicate customer, got %d: %s", resp.StatusCode, string(body)) - } - }) - - t.Run("getting existing customer succeeds", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodGet, fmt.Sprintf("/api/master-data/customers/%d", customerID), nil) - if resp.StatusCode != fiber.StatusOK { - t.Fatalf("expected 200 when fetching customer, got %d: %s", resp.StatusCode, string(body)) - } - var payload struct { - Data struct { - Id uint `json:"id"` - Name string `json:"name"` - } `json:"data"` - } - if err := json.Unmarshal(body, &payload); err != nil { - t.Fatalf("failed to parse customer response: %v", err) - } - if payload.Data.Id != customerID { - t.Fatalf("expected id %d, got %d", customerID, payload.Data.Id) - } - if payload.Data.Name != customerName { - t.Fatalf("expected name %q, got %q", customerName, payload.Data.Name) - } - }) - - const updatedName = "Customer Gamma" - - t.Run("updating customer name succeeds", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodPatch, fmt.Sprintf("/api/master-data/customers/%d", customerID), map[string]any{ - "name": updatedName, - }) - if resp.StatusCode != fiber.StatusOK { - t.Fatalf("expected 200 when updating customer, got %d: %s", resp.StatusCode, string(body)) - } - var payload struct { - Data struct { - Name string `json:"name"` - } `json:"data"` - } - if err := json.Unmarshal(body, &payload); err != nil { - t.Fatalf("failed to parse update response: %v", err) - } - if payload.Data.Name != updatedName { - t.Fatalf("expected updated name %q, got %q", updatedName, payload.Data.Name) - } - customer := fetchCustomer(t, db, customerID) - if customer.Name != updatedName { - t.Fatalf("expected persisted name %q, got %q", updatedName, customer.Name) - } - }) - - t.Run("updating customer type succeeds", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodPatch, fmt.Sprintf("/api/master-data/customers/%d", customerID), map[string]any{ - "type": utils.CustomerSupplierTypeIndividual, - }) - if resp.StatusCode != fiber.StatusOK { - t.Fatalf("expected 200 when updating customer type, got %d: %s", resp.StatusCode, string(body)) - } - customer := fetchCustomer(t, db, customerID) - if customer.Type != string(utils.CustomerSupplierTypeIndividual) { - t.Fatalf("expected persisted type %q, got %q", utils.CustomerSupplierTypeIndividual, customer.Type) - } - }) - - t.Run("updating customer with Invalid type fails", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodPatch, fmt.Sprintf("/api/master-data/customers/%d", customerID), map[string]any{ - "type": "random-type", - }) - if resp.StatusCode != fiber.StatusBadRequest { - t.Fatalf("expected 400 when updating with Invalid type, got %d: %s", resp.StatusCode, string(body)) - } - customer := fetchCustomer(t, db, customerID) - if customer.Type != string(utils.CustomerSupplierTypeIndividual) { - t.Fatalf("expected type to remain %q after Invalid update, got %q", utils.CustomerSupplierTypeIndividual, customer.Type) - } - }) - - t.Run("updating non existent customer returns 404", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodPatch, "/api/master-data/customers/9999", map[string]any{ - "name": "Does Not Matter", - }) - if resp.StatusCode != fiber.StatusNotFound { - t.Fatalf("expected 404 when updating missing customer, got %d: %s", resp.StatusCode, string(body)) - } - }) - - t.Run("deleting customer succeeds", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodDelete, fmt.Sprintf("/api/master-data/customers/%d", customerID), nil) - if resp.StatusCode != fiber.StatusOK { - t.Fatalf("expected 200 when deleting customer, got %d: %s", resp.StatusCode, string(body)) - } - var customer entities.Customer - if err := db.First(&customer, customerID).Error; !errors.Is(err, gorm.ErrRecordNotFound) { - t.Fatalf("expected customer to be deleted, got error %v", err) - } - }) - - t.Run("deleting non existent customer returns 404", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodDelete, fmt.Sprintf("/api/master-data/customers/%d", customerID), nil) - if resp.StatusCode != fiber.StatusNotFound { - t.Fatalf("expected 404 when deleting missing customer, got %d: %s", resp.StatusCode, string(body)) - } - }) - - t.Run("getting deleted customer returns 404", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodGet, fmt.Sprintf("/api/master-data/customers/%d", customerID), nil) - if resp.StatusCode != fiber.StatusNotFound { - t.Fatalf("expected 404 when fetching deleted customer, got %d: %s", resp.StatusCode, string(body)) - } - }) -} diff --git a/test/integration/master_data/fcr_test.go b/test/integration/master_data/fcr_test.go deleted file mode 100644 index a07666d8..00000000 --- a/test/integration/master_data/fcr_test.go +++ /dev/null @@ -1,218 +0,0 @@ -package test - -import ( - "encoding/json" - "errors" - "fmt" - "net/http" - "testing" - - "github.com/gofiber/fiber/v2" - "gorm.io/gorm" - - "gitlab.com/mbugroup/lti-api.git/internal/entities" -) - -func TestFcrIntegration(t *testing.T) { - app, db := setupIntegrationApp(t) - - t.Run("creating fcr without standards fails", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodPost, "/api/master-data/fcrs", map[string]any{ - "name": "FCR Alpha", - }) - if resp.StatusCode != fiber.StatusBadRequest { - t.Fatalf("expected 400 when standards missing, got %d: %s", resp.StatusCode, string(body)) - } - }) - - initialStandards := []map[string]any{ - { - "weight": 7.2, - "fcr_number": 400.0, - "mortality": 12.0, - }, - { - "weight": 7.4, - "fcr_number": 410.0, - "mortality": 11.5, - }, - } - - var fcrID uint - - t.Run("creating fcr succeeds", func(t *testing.T) { - fcrID = createFcr(t, app, "FCR Layer", initialStandards) - fcr := fetchFcr(t, db, fcrID) - if fcr.Name != "FCR Layer" { - t.Fatalf("expected name FCR Layer, got %q", fcr.Name) - } - if len(fcr.Standards) != len(initialStandards) { - t.Fatalf("expected %d standards, got %d", len(initialStandards), len(fcr.Standards)) - } - if fcr.CreatedBy != 1 { - t.Fatalf("expected created_by 1, got %d", fcr.CreatedBy) - } - }) - - t.Run("creating duplicate fcr name fails", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodPost, "/api/master-data/fcrs", map[string]any{ - "name": "FCR Layer", - "fcr_standards": initialStandards, - }) - if resp.StatusCode != fiber.StatusConflict { - t.Fatalf("expected 409 when creating duplicate, got %d: %s", resp.StatusCode, string(body)) - } - }) - - t.Run("getting fcr detail succeeds", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodGet, fmt.Sprintf("/api/master-data/fcrs/%d", fcrID), nil) - if resp.StatusCode != fiber.StatusOK { - t.Fatalf("expected 200 when fetching fcr, got %d: %s", resp.StatusCode, string(body)) - } - var payload struct { - Data struct { - Id uint `json:"id"` - Name string `json:"name"` - FcrStandards []map[string]any `json:"fcr_standards"` - } `json:"data"` - } - if err := json.Unmarshal(body, &payload); err != nil { - t.Fatalf("failed to parse fcr detail: %v", err) - } - if payload.Data.Id != fcrID { - t.Fatalf("expected id %d, got %d", fcrID, payload.Data.Id) - } - if len(payload.Data.FcrStandards) != len(initialStandards) { - t.Fatalf("expected %d standards in response, got %d", len(initialStandards), len(payload.Data.FcrStandards)) - } - }) - - updatedStandards := []map[string]any{ - { - "weight": 7.2, - "fcr_number": 395.0, - "mortality": 10.0, - }, - { - "weight": 7.5, - "fcr_number": 420.0, - "mortality": 13.0, - }, - } - - t.Run("updating fcr name and standards succeeds", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodPatch, fmt.Sprintf("/api/master-data/fcrs/%d", fcrID), map[string]any{ - "name": "FCR Layer Updated", - "fcr_standards": updatedStandards, - }) - if resp.StatusCode != fiber.StatusOK { - t.Fatalf("expected 200 when updating fcr, got %d: %s", resp.StatusCode, string(body)) - } - var payload struct { - Data struct { - Name string `json:"name"` - FcrStandards []map[string]any `json:"fcr_standards"` - } `json:"data"` - } - if err := json.Unmarshal(body, &payload); err != nil { - t.Fatalf("failed to parse update response: %v", err) - } - if payload.Data.Name != "FCR Layer Updated" { - t.Fatalf("expected updated name, got %q", payload.Data.Name) - } - if len(payload.Data.FcrStandards) != len(updatedStandards) { - t.Fatalf("expected %d standards after update, got %d", len(updatedStandards), len(payload.Data.FcrStandards)) - } - fcr := fetchFcr(t, db, fcrID) - if fcr.Name != "FCR Layer Updated" { - t.Fatalf("expected persisted name FCR Layer Updated, got %q", fcr.Name) - } - if len(fcr.Standards) != len(updatedStandards) { - t.Fatalf("expected %d persisted standards, got %d", len(updatedStandards), len(fcr.Standards)) - } - if fcr.Standards[0].FcrNumber != 395.0 { - t.Fatalf("expected first standard fcr_number 395, got %f", fcr.Standards[0].FcrNumber) - } - }) - - var otherFcrID uint - t.Run("creating another fcr for duplicate update", func(t *testing.T) { - otherFcrID = createFcr(t, app, "FCR Grower", []map[string]any{ - { - "weight": 8.0, - "fcr_number": 430.0, - "mortality": 9.0, - }, - }) - if otherFcrID == 0 { - t.Fatal("expected other fcr id to be non zero") - } - }) - - t.Run("updating fcr with duplicate name fails", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodPatch, fmt.Sprintf("/api/master-data/fcrs/%d", fcrID), map[string]any{ - "name": "FCR Grower", - }) - if resp.StatusCode != fiber.StatusConflict { - t.Fatalf("expected 409 when renaming to existing fcr, got %d: %s", resp.StatusCode, string(body)) - } - fcr := fetchFcr(t, db, fcrID) - if fcr.Name != "FCR Layer Updated" { - t.Fatalf("expected name unchanged after failed update, got %q", fcr.Name) - } - }) - - t.Run("updating fcr with invalid standards fails", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodPatch, fmt.Sprintf("/api/master-data/fcrs/%d", fcrID), map[string]any{ - "fcr_standards": []map[string]any{ - { - "weight": -1, - "fcr_number": 300, - "mortality": 5, - }, - }, - }) - if resp.StatusCode != fiber.StatusBadRequest { - t.Fatalf("expected 400 when updating with invalid standard, got %d: %s", resp.StatusCode, string(body)) - } - }) - - t.Run("deleting fcr succeeds", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodDelete, fmt.Sprintf("/api/master-data/fcrs/%d", fcrID), nil) - if resp.StatusCode != fiber.StatusOK { - t.Fatalf("expected 200 when deleting fcr, got %d: %s", resp.StatusCode, string(body)) - } - var fcr entities.Fcr - if err := db.First(&fcr, fcrID).Error; !errors.Is(err, gorm.ErrRecordNotFound) { - t.Fatalf("expected fcr to be deleted, got error %v", err) - } - var standardsCount int64 - if err := db.Model(&entities.FcrStandard{}).Where("fcr_id = ?", fcrID).Count(&standardsCount).Error; err != nil { - t.Fatalf("failed counting standards: %v", err) - } - if standardsCount != 0 { - t.Fatalf("expected standards removed, found %d", standardsCount) - } - }) - - t.Run("deleting fcr again returns 404", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodDelete, fmt.Sprintf("/api/master-data/fcrs/%d", fcrID), nil) - if resp.StatusCode != fiber.StatusNotFound { - t.Fatalf("expected 404 when deleting missing fcr, got %d: %s", resp.StatusCode, string(body)) - } - }) - - t.Run("getting deleted fcr returns 404", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodGet, fmt.Sprintf("/api/master-data/fcrs/%d", fcrID), nil) - if resp.StatusCode != fiber.StatusNotFound { - t.Fatalf("expected 404 when fetching deleted fcr, got %d: %s", resp.StatusCode, string(body)) - } - }) - - t.Run("cleanup other fcr", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodDelete, fmt.Sprintf("/api/master-data/fcrs/%d", otherFcrID), nil) - if resp.StatusCode != fiber.StatusOK { - t.Fatalf("expected 200 when deleting other fcr, got %d: %s", resp.StatusCode, string(body)) - } - }) -} diff --git a/test/integration/master_data/kandang_test.go b/test/integration/master_data/kandang_test.go deleted file mode 100644 index b7b82b21..00000000 --- a/test/integration/master_data/kandang_test.go +++ /dev/null @@ -1,96 +0,0 @@ -package test - -import ( - "encoding/json" - "fmt" - "net/http" - "testing" - - "github.com/gofiber/fiber/v2" - - "gitlab.com/mbugroup/lti-api.git/internal/entities" - "gitlab.com/mbugroup/lti-api.git/internal/utils" -) - -func TestKandangIntegration(t *testing.T) { - app, db := setupIntegrationApp(t) - areaID := createArea(t, app, "Area Kandang") - locationID := createLocation(t, app, "Location For Kandang", "Address", areaID) - - t.Run("create kandang success", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodPost, "/api/master-data/kandangs", map[string]any{ - "name": "Kandang OK", - "location_id": locationID, - "pic_id": 1, - }) - if resp.StatusCode != fiber.StatusCreated { - t.Fatalf("expected 201, got %d: %s", resp.StatusCode, string(body)) - } - - var createResp struct { - Data struct { - Status string `json:"status"` - } `json:"data"` - } - if err := json.Unmarshal(body, &createResp); err != nil { - t.Fatalf("failed to parse create response: %v", err) - } - if createResp.Data.Status == "" { - t.Fatalf("expected default status to be returned, got empty") - } - }) - - t.Run("create kandang with unknown location fails", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodPost, "/api/master-data/kandangs", map[string]any{ - "name": "Kandang Fail", - "status": "ACTIVE", - "location_id": 999, - "pic_id": 1, - }) - if resp.StatusCode != fiber.StatusNotFound { - t.Fatalf("expected 404, got %d: %s", resp.StatusCode, string(body)) - } - }) - - t.Run("cannot assign project floc with existing active kandang", func(t *testing.T) { - fcrID := createFcr(t, app, "FCR For Floc", []map[string]any{ - {"weight": 1.0, "fcr_number": 1.5, "mortality": 2.0}, - }) - flocID := createFlock(t, app, "Floc Test") - - projectFloc := entities.ProjectFlock{ - FlockName: fmt.Sprintf("Project Flock %d", flocID), - AreaId: areaID, - Category: string(utils.ProjectFlockCategoryGrowing), - FcrId: fcrID, - LocationId: locationID, - Period: 1, - CreatedBy: 1, - } - if err := db.Create(&projectFloc).Error; err != nil { - t.Fatalf("failed to seed project floc: %v", err) - } - - resp, body := doJSONRequest(t, app, http.MethodPost, "/api/master-data/kandangs", map[string]any{ - "name": "Kandang Active 1", - "status": "ACTIVE", - "location_id": locationID, - "pic_id": 1, - "project_flock_id": projectFloc.Id, - }) - if resp.StatusCode != fiber.StatusCreated { - t.Fatalf("expected 201 when creating first kandang, got %d: %s", resp.StatusCode, string(body)) - } - - resp, body = doJSONRequest(t, app, http.MethodPost, "/api/master-data/kandangs", map[string]any{ - "name": "Kandang Active 2", - "status": "ACTIVE", - "location_id": locationID, - "pic_id": 1, - "project_flock_id": projectFloc.Id, - }) - if resp.StatusCode != fiber.StatusConflict { - t.Fatalf("expected 409 when creating second active kandang, got %d: %s", resp.StatusCode, string(body)) - } - }) -} diff --git a/test/integration/master_data/location_test.go b/test/integration/master_data/location_test.go deleted file mode 100644 index 0c78ac2a..00000000 --- a/test/integration/master_data/location_test.go +++ /dev/null @@ -1,35 +0,0 @@ -package test - -import ( - "net/http" - "testing" - - "github.com/gofiber/fiber/v2" -) - -func TestLocationIntegration(t *testing.T) { - app, _ := setupIntegrationApp(t) - - t.Run("creating location without existing area fails", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodPost, "/api/master-data/locations", map[string]any{ - "name": "Loc A", - "address": "Address", - "area_id": 999, // non-existent - }) - if resp.StatusCode != fiber.StatusNotFound { - t.Fatalf("expected 404, got %d: %s", resp.StatusCode, string(body)) - } - }) - - t.Run("creating location succeeds", func(t *testing.T) { - areaID := createArea(t, app, "Area For Location") - resp, body := doJSONRequest(t, app, http.MethodPost, "/api/master-data/locations", map[string]any{ - "name": "Location OK", - "address": "Addr", - "area_id": areaID, - }) - if resp.StatusCode != fiber.StatusCreated { - t.Fatalf("expected 201, got %d: %s", resp.StatusCode, string(body)) - } - }) -} diff --git a/test/integration/master_data/master_data.go b/test/integration/master_data/master_data.go deleted file mode 100644 index d43ddf15..00000000 --- a/test/integration/master_data/master_data.go +++ /dev/null @@ -1,401 +0,0 @@ -package test - -import ( - "bytes" - "encoding/json" - "fmt" - "io" - "net/http" - "net/http/httptest" - "path/filepath" - "strings" - "testing" - "time" - - "github.com/glebarez/sqlite" - "github.com/gofiber/fiber/v2" - "gorm.io/gorm" - "gorm.io/gorm/logger" - - "gitlab.com/mbugroup/lti-api.git/internal/entities" - "gitlab.com/mbugroup/lti-api.git/internal/route" - "gitlab.com/mbugroup/lti-api.git/internal/utils" -) - -func setupIntegrationApp(t *testing.T) (*fiber.App, *gorm.DB) { - t.Helper() - dir := t.TempDir() - dsn := filepath.Join(dir, "integration.db") - - db, err := gorm.Open(sqlite.Open(dsn), &gorm.Config{Logger: logger.Default.LogMode(logger.Silent)}) - if err != nil { - t.Fatalf("failed to open sqlite database: %v", err) - } - - if err := db.Exec("PRAGMA foreign_keys = ON").Error; err != nil { - t.Fatalf("failed to enable foreign keys: %v", err) - } - - if err := db.AutoMigrate( - &entities.User{}, - &entities.Area{}, - &entities.Location{}, - &entities.Flock{}, - &entities.ProjectFlock{}, - &entities.ProjectFlockKandang{}, - &entities.Kandang{}, - &entities.Warehouse{}, - &entities.Uom{}, - &entities.Customer{}, - &entities.Supplier{}, - &entities.Flag{}, - &entities.ProductCategory{}, - &entities.Nonstock{}, - &entities.NonstockSupplier{}, - &entities.Product{}, - &entities.ProductSupplier{}, - &entities.Fcr{}, - &entities.FcrStandard{}, - &entities.Bank{}, - ); err != nil { - t.Fatalf("auto migrate failed: %v", err) - } - - seedUser := entities.User{ - Id: 1, - IdUser: 1001, - Email: "tester@example.com", - Name: "Tester", - CreatedAt: time.Now(), - UpdatedAt: time.Now(), - } - if err := db.Create(&seedUser).Error; err != nil { - t.Fatalf("failed to seed user: %v", err) - } - - app := fiber.New(fiber.Config{ErrorHandler: utils.ErrorHandler}) - route.Routes(app, db) - return app, db -} - -func doJSONRequest(t *testing.T, app *fiber.App, method, path string, payload any) (*http.Response, []byte) { - t.Helper() - - var body io.Reader - if payload != nil { - buf := &bytes.Buffer{} - if err := json.NewEncoder(buf).Encode(payload); err != nil { - t.Fatalf("failed to encode payload: %v", err) - } - body = buf - } - - req := httptest.NewRequest(method, path, body) - req.Header.Set("Content-Type", "application/json") - req.Header.Set("Accept", "application/json") - - resp, err := app.Test(req, -1) - if err != nil { - t.Fatalf("request failed: %v", err) - } - - defer resp.Body.Close() - data, err := io.ReadAll(resp.Body) - if err != nil { - t.Fatalf("failed to read response body: %v", err) - } - return resp, data -} - -func parseID(t *testing.T, body []byte) uint { - t.Helper() - var resp struct { - Data struct { - Id uint `json:"id"` - } `json:"data"` - } - if err := json.Unmarshal(body, &resp); err != nil { - t.Fatalf("failed to parse response: %v", err) - } - return resp.Data.Id -} - -func createArea(t *testing.T, app *fiber.App, name string) uint { - t.Helper() - resp, body := doJSONRequest(t, app, http.MethodPost, "/api/master-data/areas", map[string]any{"name": name}) - if resp.StatusCode != fiber.StatusCreated { - t.Fatalf("expected 201 when creating area, got %d: %s", resp.StatusCode, string(body)) - } - return parseID(t, body) -} - -func createLocation(t *testing.T, app *fiber.App, name, address string, areaID uint) uint { - t.Helper() - resp, body := doJSONRequest(t, app, http.MethodPost, "/api/master-data/locations", map[string]any{ - "name": name, - "address": address, - "area_id": areaID, - }) - if resp.StatusCode != fiber.StatusCreated { - t.Fatalf("expected 201 when creating location, got %d: %s", resp.StatusCode, string(body)) - } - return parseID(t, body) -} - -func createUom(t *testing.T, app *fiber.App, name string) uint { - t.Helper() - resp, body := doJSONRequest(t, app, http.MethodPost, "/api/master-data/uoms", map[string]any{"name": name}) - if resp.StatusCode != fiber.StatusCreated { - t.Fatalf("expected 201 when creating uom, got %d: %s", resp.StatusCode, string(body)) - } - return parseID(t, body) -} - -func createKandang(t *testing.T, app *fiber.App, name string, locationID, picID uint) uint { - t.Helper() - resp, body := doJSONRequest(t, app, http.MethodPost, "/api/master-data/kandangs", map[string]any{ - "name": name, - "status": "ACTIVE", - "location_id": locationID, - "pic_id": picID, - }) - if resp.StatusCode != fiber.StatusCreated { - t.Fatalf("expected 201 when creating kandang, got %d: %s", resp.StatusCode, string(body)) - } - return parseID(t, body) -} - -func createCustomer(t *testing.T, app *fiber.App, name string, picID uint) uint { - t.Helper() - identifier := strings.ToLower(strings.ReplaceAll(name, " ", "_")) - resp, body := doJSONRequest(t, app, http.MethodPost, "/api/master-data/customers", map[string]any{ - "name": name, - "pic_id": picID, - "type": utils.CustomerSupplierTypeBisnis, - "address": "Customer address", - "phone": "081234567890", - "email": fmt.Sprintf("%s@example.com", identifier), - "account_number": fmt.Sprintf("ACC-%s", identifier), - }) - if resp.StatusCode != fiber.StatusCreated { - t.Fatalf("expected 201 when creating customer, got %d: %s", resp.StatusCode, string(body)) - } - return parseID(t, body) -} - -func fetchCustomer(t *testing.T, db *gorm.DB, id uint) entities.Customer { - t.Helper() - var customer entities.Customer - if err := db.Preload("Pic").Preload("CreatedUser").First(&customer, id).Error; err != nil { - t.Fatalf("failed to fetch customer: %v", err) - } - return customer -} - -func fetchKandang(t *testing.T, db *gorm.DB, id uint) entities.Kandang { - t.Helper() - var kandang entities.Kandang - if err := db.Preload("ProjectFlock").First(&kandang, id).Error; err != nil { - t.Fatalf("failed to fetch kandang: %v", err) - } - return kandang -} - -func createSupplier(t *testing.T, app *fiber.App, name, alias, category string) uint { - t.Helper() - identifier := strings.ToLower(strings.ReplaceAll(name, " ", "_")) - resp, body := doJSONRequest(t, app, http.MethodPost, "/api/master-data/suppliers", map[string]any{ - "name": name, - "alias": alias, - "pic": "John Doe", - "type": utils.CustomerSupplierTypeBisnis, - "category": category, - "hatchery": "Hatchery A", - "phone": "081234567890", - "email": fmt.Sprintf("%s@supplier.com", identifier), - "address": "Supplier address", - "npwp": "NPWP-123", - "account_number": "ACC-SUPPLIER", - "due_date": 30, - }) - if resp.StatusCode != fiber.StatusCreated { - t.Fatalf("expected 201 when creating supplier, got %d: %s", resp.StatusCode, string(body)) - } - return parseID(t, body) -} - -func createProductCategory(t *testing.T, app *fiber.App, name, code string) uint { - t.Helper() - resp, body := doJSONRequest(t, app, http.MethodPost, "/api/master-data/product-categories", map[string]any{ - "name": name, - "code": code, - }) - if resp.StatusCode != fiber.StatusCreated { - t.Fatalf("expected 201 when creating product category, got %d: %s", resp.StatusCode, string(body)) - } - return parseID(t, body) -} - -func fetchProductCategory(t *testing.T, db *gorm.DB, id uint) entities.ProductCategory { - t.Helper() - var pc entities.ProductCategory - if err := db.Preload("CreatedUser").First(&pc, id).Error; err != nil { - t.Fatalf("failed to fetch product category: %v", err) - } - return pc -} - -func createProduct(t *testing.T, app *fiber.App, name, brand string, sku *string, uomID, categoryID uint, productPrice float64, supplierIDs []uint, flags []string) uint { - t.Helper() - payload := map[string]any{ - "name": name, - "brand": brand, - "uom_id": uomID, - "product_category_id": categoryID, - "product_price": productPrice, - "supplier_ids": supplierIDs, - } - if sku != nil { - payload["sku"] = *sku - } - if len(flags) > 0 { - payload["flags"] = flags - } - resp, body := doJSONRequest(t, app, http.MethodPost, "/api/master-data/products", payload) - if resp.StatusCode != fiber.StatusCreated { - t.Fatalf("expected 201 when creating product, got %d: %s", resp.StatusCode, string(body)) - } - return parseID(t, body) -} - -func fetchProduct(t *testing.T, db *gorm.DB, id uint) entities.Product { - t.Helper() - var product entities.Product - if err := db.Preload("CreatedUser"). - Preload("Uom"). - Preload("ProductCategory"). - Preload("Suppliers", func(tx *gorm.DB) *gorm.DB { return tx.Order("suppliers.name ASC") }). - Preload("Flags", func(tx *gorm.DB) *gorm.DB { return tx.Order("flags.name ASC") }). - First(&product, id).Error; err != nil { - t.Fatalf("failed to fetch product: %v", err) - } - return product -} - -func fetchSupplier(t *testing.T, db *gorm.DB, id uint) entities.Supplier { - t.Helper() - var supplier entities.Supplier - if err := db.Preload("CreatedUser").First(&supplier, id).Error; err != nil { - t.Fatalf("failed to fetch supplier: %v", err) - } - return supplier -} - -func createFcr(t *testing.T, app *fiber.App, name string, standards []map[string]any) uint { - t.Helper() - payload := map[string]any{ - "name": name, - "fcr_standards": standards, - } - resp, body := doJSONRequest(t, app, http.MethodPost, "/api/master-data/fcrs", payload) - if resp.StatusCode != fiber.StatusCreated { - t.Fatalf("expected 201 when creating fcr, got %d: %s", resp.StatusCode, string(body)) - } - return parseID(t, body) -} - -func createFlock(t *testing.T, app *fiber.App, name string) uint { - t.Helper() - resp, body := doJSONRequest(t, app, http.MethodPost, "/api/master-data/flocks", map[string]any{ - "name": name, - }) - if resp.StatusCode != fiber.StatusCreated { - t.Fatalf("expected 201 when creating flock, got %d: %s", resp.StatusCode, string(body)) - } - return parseID(t, body) -} - -func fetchFcr(t *testing.T, db *gorm.DB, id uint) entities.Fcr { - t.Helper() - var fcr entities.Fcr - if err := db.Preload("CreatedUser"). - Preload("Standards", func(tx *gorm.DB) *gorm.DB { - return tx.Order("weight ASC") - }). - First(&fcr, id).Error; err != nil { - t.Fatalf("failed to fetch fcr: %v", err) - } - return fcr -} - -func createNonstock(t *testing.T, app *fiber.App, name string, uomID uint, supplierIDs []uint, flags []string) uint { - t.Helper() - payload := map[string]any{ - "name": name, - "uom_id": uomID, - "supplier_ids": supplierIDs, - } - if len(flags) > 0 { - payload["flags"] = flags - } - resp, body := doJSONRequest(t, app, http.MethodPost, "/api/master-data/nonstocks", payload) - if resp.StatusCode != fiber.StatusCreated { - t.Fatalf("expected 201 when creating nonstock, got %d: %s", resp.StatusCode, string(body)) - } - return parseID(t, body) -} - -func fetchNonstock(t *testing.T, db *gorm.DB, id uint) entities.Nonstock { - t.Helper() - var nonstock entities.Nonstock - if err := db.Preload("CreatedUser"). - Preload("Uom"). - Preload("Suppliers", func(tx *gorm.DB) *gorm.DB { return tx.Order("suppliers.name ASC") }). - Preload("Flags", func(tx *gorm.DB) *gorm.DB { return tx.Order("flags.name ASC") }). - First(&nonstock, id).Error; err != nil { - t.Fatalf("failed to fetch nonstock: %v", err) - } - return nonstock -} - -func fetchAreaName(t *testing.T, db *gorm.DB, id uint) string { - t.Helper() - var area entities.Area - if err := db.First(&area, id).Error; err != nil { - t.Fatalf("failed to fetch area: %v", err) - } - return area.Name -} - -func fetchWarehouse(t *testing.T, db *gorm.DB, id uint) entities.Warehouse { - t.Helper() - var wh entities.Warehouse - if err := db.First(&wh, id).Error; err != nil { - t.Fatalf("failed to fetch warehouse: %v", err) - } - return wh -} - -func createBank(t *testing.T, app *fiber.App, name, alias, accountNumber string, owner any) uint { - t.Helper() - payload := map[string]any{ - "name": name, - "alias": alias, - "account_number": accountNumber, - "owner": owner, - } - resp, body := doJSONRequest(t, app, http.MethodPost, "/api/master-data/banks", payload) - if resp.StatusCode != fiber.StatusCreated { - t.Fatalf("expected 201 when creating bank, got %d: %s", resp.StatusCode, string(body)) - } - return parseID(t, body) -} - -func fetchBank(t *testing.T, db *gorm.DB, id uint) entities.Bank { - t.Helper() - var bank entities.Bank - if err := db.Preload("CreatedUser").First(&bank, id).Error; err != nil { - t.Fatalf("failed to fetch bank: %v", err) - } - return bank -} diff --git a/test/integration/master_data/nonstock_test.go b/test/integration/master_data/nonstock_test.go deleted file mode 100644 index cadea99d..00000000 --- a/test/integration/master_data/nonstock_test.go +++ /dev/null @@ -1,309 +0,0 @@ -package test - -import ( - "encoding/json" - "errors" - "fmt" - "net/http" - "strings" - "testing" - - "github.com/gofiber/fiber/v2" - "gorm.io/gorm" - - "gitlab.com/mbugroup/lti-api.git/internal/entities" - "gitlab.com/mbugroup/lti-api.git/internal/utils" -) - -func TestNonstockIntegration(t *testing.T) { - app, db := setupIntegrationApp(t) - - uomID := createUom(t, app, "Unit Piece") - altUomID := createUom(t, app, "Unit Box") - - supplierID1 := createSupplier(t, app, "Nonstock Supplier One", "ns1", string(utils.SupplierCategoryBOP)) - supplierID2 := createSupplier(t, app, "Nonstock Supplier Two", "ns2", string(utils.SupplierCategoryBOP)) - supplierID3 := createSupplier(t, app, "Nonstock Supplier Three", "ns3", string(utils.SupplierCategoryBOP)) - sapronakSupplierID := createSupplier(t, app, "SAPRONAK Supplier", "sap1", string(utils.SupplierCategorySapronak)) - - nonstockFlags := []string{string(utils.FlagEkspedisi)} - - t.Run("create nonstock without suppliers succeeds with empty relations", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodPost, "/api/master-data/nonstocks", map[string]any{ - "name": "Supplierless Nonstock", - "uom_id": uomID, - }) - if resp.StatusCode != fiber.StatusCreated { - t.Fatalf("expected 201 when suppliers omitted, got %d: %s", resp.StatusCode, string(body)) - } - id := parseID(t, body) - ns := fetchNonstock(t, db, id) - if len(ns.Suppliers) != 0 { - t.Fatalf("expected no suppliers persisted, found %d", len(ns.Suppliers)) - } - if len(ns.Flags) != 0 { - t.Fatalf("expected no flags persisted, found %d", len(ns.Flags)) - } - resp, _ = doJSONRequest(t, app, http.MethodDelete, fmt.Sprintf("/api/master-data/nonstocks/%d", id), nil) - if resp.StatusCode != fiber.StatusOK { - t.Fatalf("expected cleanup delete to succeed, got %d", resp.StatusCode) - } - }) - - t.Run("create nonstock with unknown supplier fails", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodPost, "/api/master-data/nonstocks", map[string]any{ - "name": "Unknown Supplier Nonstock", - "uom_id": uomID, - "supplier_ids": []uint{99999}, - }) - if resp.StatusCode != fiber.StatusNotFound { - t.Fatalf("expected 404 when supplier missing, got %d: %s", resp.StatusCode, string(body)) - } - }) - - t.Run("create nonstock with sapronak supplier fails", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodPost, "/api/master-data/nonstocks", map[string]any{ - "name": "Invalid Category Nonstock", - "uom_id": uomID, - "supplier_ids": []uint{sapronakSupplierID}, - }) - if resp.StatusCode != fiber.StatusBadRequest { - t.Fatalf("expected 400 when supplier category is not BOP, got %d: %s", resp.StatusCode, string(body)) - } - }) - - t.Run("create nonstock with invalid flags fails", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodPost, "/api/master-data/nonstocks", map[string]any{ - "name": "Invalid Flag Nonstock", - "uom_id": uomID, - "supplier_ids": []uint{supplierID1}, - "flags": []string{"UNKNOWN"}, - }) - if resp.StatusCode != fiber.StatusBadRequest { - t.Fatalf("expected 400 when flags invalid, got %d: %s", resp.StatusCode, string(body)) - } - }) - - var nonstockID uint - - t.Run("create nonstock succeeds", func(t *testing.T) { - nonstockID = createNonstock(t, app, "Layer Feed", uomID, []uint{supplierID1, supplierID2, supplierID1}, nonstockFlags) - if nonstockID == 0 { - t.Fatal("expected nonstock id to be non zero") - } - ns := fetchNonstock(t, db, nonstockID) - if ns.Name != "Layer Feed" { - t.Fatalf("expected name Layer Feed, got %q", ns.Name) - } - if ns.UomId != uomID { - t.Fatalf("expected uom_id %d, got %d", uomID, ns.UomId) - } - if ns.CreatedBy != 1 { - t.Fatalf("expected created_by 1, got %d", ns.CreatedBy) - } - if len(ns.Suppliers) != 2 { - t.Fatalf("expected 2 unique suppliers, got %d", len(ns.Suppliers)) - } - if len(ns.Flags) != len(nonstockFlags) { - t.Fatalf("expected %d flags, got %d", len(nonstockFlags), len(ns.Flags)) - } - expectedFlags := make(map[string]struct{}, len(nonstockFlags)) - for _, flag := range nonstockFlags { - expectedFlags[strings.ToUpper(flag)] = struct{}{} - } - for _, flag := range ns.Flags { - upper := strings.ToUpper(flag.Name) - if _, ok := expectedFlags[upper]; !ok { - t.Fatalf("unexpected flag stored: %s", upper) - } - delete(expectedFlags, upper) - } - if len(expectedFlags) != 0 { - t.Fatalf("missing flags after create: %v", expectedFlags) - } - }) - - t.Run("get nonstock detail includes suppliers", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodGet, fmt.Sprintf("/api/master-data/nonstocks/%d", nonstockID), nil) - if resp.StatusCode != fiber.StatusOK { - t.Fatalf("expected 200 when fetching nonstock, got %d: %s", resp.StatusCode, string(body)) - } - var payload struct { - Data struct { - Id uint `json:"id"` - Name string `json:"name"` - UomID uint `json:"uom_id"` - Suppliers []map[string]any `json:"suppliers"` - Flags []string `json:"flags"` - } `json:"data"` - } - if err := json.Unmarshal(body, &payload); err != nil { - t.Fatalf("failed to parse nonstock detail: %v", err) - } - if payload.Data.Id != nonstockID { - t.Fatalf("expected id %d, got %d", nonstockID, payload.Data.Id) - } - if payload.Data.UomID != uomID { - t.Fatalf("expected response uom_id %d, got %d", uomID, payload.Data.UomID) - } - if len(payload.Data.Suppliers) != 2 { - t.Fatalf("expected 2 suppliers in response, got %d", len(payload.Data.Suppliers)) - } - if len(payload.Data.Flags) != len(nonstockFlags) { - t.Fatalf("expected %d flags in response, got %d", len(nonstockFlags), len(payload.Data.Flags)) - } - expected := make(map[string]struct{}, len(nonstockFlags)) - for _, flag := range nonstockFlags { - expected[strings.ToUpper(flag)] = struct{}{} - } - for _, flag := range payload.Data.Flags { - flag = strings.ToUpper(flag) - if _, ok := expected[flag]; !ok { - t.Fatalf("unexpected flag %s returned", flag) - } - delete(expected, flag) - } - if len(expected) != 0 { - t.Fatalf("missing flags in response: %v", expected) - } - }) - - t.Run("update nonstock with invalid uom fails", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodPatch, fmt.Sprintf("/api/master-data/nonstocks/%d", nonstockID), map[string]any{ - "uom_id": 99999, - }) - if resp.StatusCode != fiber.StatusNotFound { - t.Fatalf("expected 404 when updating with invalid uom, got %d: %s", resp.StatusCode, string(body)) - } - }) - - t.Run("update nonstock with invalid supplier fails", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodPatch, fmt.Sprintf("/api/master-data/nonstocks/%d", nonstockID), map[string]any{ - "supplier_ids": []uint{supplierID1, 99999}, - }) - if resp.StatusCode != fiber.StatusNotFound { - t.Fatalf("expected 404 when updating with invalid supplier, got %d: %s", resp.StatusCode, string(body)) - } - }) - - t.Run("update nonstock with sapronak supplier fails", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodPatch, fmt.Sprintf("/api/master-data/nonstocks/%d", nonstockID), map[string]any{ - "supplier_ids": []uint{sapronakSupplierID}, - }) - if resp.StatusCode != fiber.StatusBadRequest { - t.Fatalf("expected 400 when updating with non-BOP supplier, got %d: %s", resp.StatusCode, string(body)) - } - }) - - t.Run("update nonstock with invalid flags fails", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodPatch, fmt.Sprintf("/api/master-data/nonstocks/%d", nonstockID), map[string]any{ - "flags": []string{"BAD"}, - }) - if resp.StatusCode != fiber.StatusBadRequest { - t.Fatalf("expected 400 when updating flags invalid, got %d: %s", resp.StatusCode, string(body)) - } - }) - - t.Run("update nonstock name uom and suppliers succeeds", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodPatch, fmt.Sprintf("/api/master-data/nonstocks/%d", nonstockID), map[string]any{ - "name": "Layer Feed Premium", - "uom_id": altUomID, - "supplier_ids": []uint{supplierID3}, - "flags": nonstockFlags, - }) - if resp.StatusCode != fiber.StatusOK { - t.Fatalf("expected 200 when updating nonstock, got %d: %s", resp.StatusCode, string(body)) - } - ns := fetchNonstock(t, db, nonstockID) - if ns.Name != "Layer Feed Premium" { - t.Fatalf("expected name Layer Feed Premium, got %q", ns.Name) - } - if ns.UomId != altUomID { - t.Fatalf("expected uom_id %d, got %d", altUomID, ns.UomId) - } - if len(ns.Suppliers) != 1 || ns.Suppliers[0].Id != supplierID3 { - t.Fatalf("expected suppliers to contain only %d", supplierID3) - } - if len(ns.Flags) != len(nonstockFlags) { - t.Fatalf("expected flags retained, got %d", len(ns.Flags)) - } - }) - - t.Run("clear suppliers succeeds", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodPatch, fmt.Sprintf("/api/master-data/nonstocks/%d", nonstockID), map[string]any{ - "supplier_ids": []uint{}, - }) - if resp.StatusCode != fiber.StatusOK { - t.Fatalf("expected 200 when clearing suppliers, got %d: %s", resp.StatusCode, string(body)) - } - ns := fetchNonstock(t, db, nonstockID) - if len(ns.Suppliers) != 0 { - t.Fatalf("expected suppliers to be cleared, got %d entries", len(ns.Suppliers)) - } - if len(ns.Flags) != len(nonstockFlags) { - t.Fatalf("expected flags unaffected, got %d", len(ns.Flags)) - } - }) - - t.Run("clear nonstock flags succeeds", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodPatch, fmt.Sprintf("/api/master-data/nonstocks/%d", nonstockID), map[string]any{ - "flags": []string{}, - }) - if resp.StatusCode != fiber.StatusOK { - t.Fatalf("expected 200 when clearing nonstock flags, got %d: %s", resp.StatusCode, string(body)) - } - ns := fetchNonstock(t, db, nonstockID) - if len(ns.Flags) != 0 { - t.Fatalf("expected flags cleared, got %d", len(ns.Flags)) - } - }) - - t.Run("delete nonstock succeeds", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodDelete, fmt.Sprintf("/api/master-data/nonstocks/%d", nonstockID), nil) - if resp.StatusCode != fiber.StatusOK { - t.Fatalf("expected 200 when deleting nonstock, got %d: %s", resp.StatusCode, string(body)) - } - var ns entities.Nonstock - if err := db.First(&ns, nonstockID).Error; !errors.Is(err, gorm.ErrRecordNotFound) { - t.Fatalf("expected nonstock to be deleted, got error %v", err) - } - var links int64 - if err := db.Model(&entities.NonstockSupplier{}).Where("nonstock_id = ?", nonstockID).Count(&links).Error; err != nil { - t.Fatalf("failed counting nonstock suppliers: %v", err) - } - if links != 0 { - t.Fatalf("expected link table cleared, found %d rows", links) - } - var flagCount int64 - if err := db.Model(&entities.Flag{}). - Where("flagable_id = ? AND flagable_type = ?", nonstockID, entities.FlagableTypeNonstock). - Count(&flagCount).Error; err != nil { - t.Fatalf("failed counting nonstock flags: %v", err) - } - if flagCount != 0 { - t.Fatalf("expected flags removed, found %d", flagCount) - } - }) - - t.Run("deleting nonstock twice returns 404", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodDelete, fmt.Sprintf("/api/master-data/nonstocks/%d", nonstockID), nil) - if resp.StatusCode != fiber.StatusNotFound { - t.Fatalf("expected 404 when deleting missing nonstock, got %d: %s", resp.StatusCode, string(body)) - } - }) - - t.Run("fetching deleted nonstock returns 404", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodGet, fmt.Sprintf("/api/master-data/nonstocks/%d", nonstockID), nil) - if resp.StatusCode != fiber.StatusNotFound { - t.Fatalf("expected 404 when fetching deleted nonstock, got %d: %s", resp.StatusCode, string(body)) - } - }) - - t.Run("cleanup additional supplier references", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodDelete, fmt.Sprintf("/api/master-data/suppliers/%d", supplierID3), nil) - if resp.StatusCode != fiber.StatusOK { - t.Fatalf("expected 200 when deleting supplier, got %d: %s", resp.StatusCode, string(body)) - } - doJSONRequest(t, app, http.MethodDelete, fmt.Sprintf("/api/master-data/suppliers/%d", sapronakSupplierID), nil) - }) -} diff --git a/test/integration/master_data/product_category_test.go b/test/integration/master_data/product_category_test.go deleted file mode 100644 index 14012301..00000000 --- a/test/integration/master_data/product_category_test.go +++ /dev/null @@ -1,150 +0,0 @@ -package test - -import ( - "encoding/json" - "errors" - "fmt" - "net/http" - "testing" - - "github.com/gofiber/fiber/v2" - "gorm.io/gorm" - - "gitlab.com/mbugroup/lti-api.git/internal/entities" -) - -func TestProductCategoryIntegration(t *testing.T) { - app, db := setupIntegrationApp(t) - - t.Run("create product category missing code fails", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodPost, "/api/master-data/product-categories", map[string]any{ - "name": "Layer Feed", - }) - if resp.StatusCode != fiber.StatusBadRequest { - t.Fatalf("expected 400 when code missing, got %d: %s", resp.StatusCode, string(body)) - } - }) - - var categoryID uint - - t.Run("create product category succeeds", func(t *testing.T) { - categoryID = createProductCategory(t, app, "Layer Feed", "LFD") - pc := fetchProductCategory(t, db, categoryID) - if pc.Name != "Layer Feed" { - t.Fatalf("expected name Layer Feed, got %q", pc.Name) - } - if pc.Code != "LFD" { - t.Fatalf("expected code LFD, got %q", pc.Code) - } - if pc.CreatedBy != 1 { - t.Fatalf("expected created_by 1, got %d", pc.CreatedBy) - } - }) - - t.Run("creating duplicate name fails", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodPost, "/api/master-data/product-categories", map[string]any{ - "name": "Layer Feed", - "code": "LF2", - }) - if resp.StatusCode != fiber.StatusConflict { - t.Fatalf("expected 409 when creating duplicate name, got %d: %s", resp.StatusCode, string(body)) - } - }) - - t.Run("creating duplicate code fails", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodPost, "/api/master-data/product-categories", map[string]any{ - "name": "Layer Feed Premium", - "code": "LFD", - }) - if resp.StatusCode != fiber.StatusConflict { - t.Fatalf("expected 409 when creating duplicate code, got %d: %s", resp.StatusCode, string(body)) - } - }) - - t.Run("get product category detail", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodGet, fmt.Sprintf("/api/master-data/product-categories/%d", categoryID), nil) - if resp.StatusCode != fiber.StatusOK { - t.Fatalf("expected 200 when fetching product category, got %d: %s", resp.StatusCode, string(body)) - } - var payload struct { - Data struct { - Id uint `json:"id"` - Name string `json:"name"` - Code string `json:"code"` - } `json:"data"` - } - if err := json.Unmarshal(body, &payload); err != nil { - t.Fatalf("failed to parse response: %v", err) - } - if payload.Data.Id != categoryID { - t.Fatalf("expected id %d, got %d", categoryID, payload.Data.Id) - } - if payload.Data.Code != "LFD" { - t.Fatalf("expected code LFD, got %q", payload.Data.Code) - } - }) - - t.Run("update product category with duplicate name fails", func(t *testing.T) { - otherID := createProductCategory(t, app, "Layer Feed Alt", "LFA") - resp, body := doJSONRequest(t, app, http.MethodPatch, fmt.Sprintf("/api/master-data/product-categories/%d", otherID), map[string]any{ - "name": "Layer Feed", - }) - if resp.StatusCode != fiber.StatusConflict { - t.Fatalf("expected 409 when updating with duplicate name, got %d: %s", resp.StatusCode, string(body)) - } - }) - - t.Run("update product category succeeds", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodPatch, fmt.Sprintf("/api/master-data/product-categories/%d", categoryID), map[string]any{ - "name": "Layer Feed Updated", - "code": "LFU", - }) - if resp.StatusCode != fiber.StatusOK { - t.Fatalf("expected 200 when updating product category, got %d: %s", resp.StatusCode, string(body)) - } - var payload struct { - Data struct { - Name string `json:"name"` - Code string `json:"code"` - } `json:"data"` - } - if err := json.Unmarshal(body, &payload); err != nil { - t.Fatalf("failed to parse update response: %v", err) - } - if payload.Data.Name != "Layer Feed Updated" { - t.Fatalf("expected updated name, got %q", payload.Data.Name) - } - if payload.Data.Code != "LFU" { - t.Fatalf("expected code LFU, got %q", payload.Data.Code) - } - pc := fetchProductCategory(t, db, categoryID) - if pc.Code != "LFU" { - t.Fatalf("expected persisted code LFU, got %q", pc.Code) - } - }) - - t.Run("delete product category", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodDelete, fmt.Sprintf("/api/master-data/product-categories/%d", categoryID), nil) - if resp.StatusCode != fiber.StatusOK { - t.Fatalf("expected 200 when deleting product category, got %d: %s", resp.StatusCode, string(body)) - } - var pc entities.ProductCategory - if err := db.First(&pc, categoryID).Error; !errors.Is(err, gorm.ErrRecordNotFound) { - t.Fatalf("expected product category deleted, got error %v", err) - } - }) - - t.Run("delete non existing product category returns 404", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodDelete, fmt.Sprintf("/api/master-data/product-categories/%d", categoryID), nil) - if resp.StatusCode != fiber.StatusNotFound { - t.Fatalf("expected 404 when deleting missing product category, got %d: %s", resp.StatusCode, string(body)) - } - }) - - t.Run("get deleted product category returns 404", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodGet, fmt.Sprintf("/api/master-data/product-categories/%d", categoryID), nil) - if resp.StatusCode != fiber.StatusNotFound { - t.Fatalf("expected 404 when fetching deleted product category, got %d: %s", resp.StatusCode, string(body)) - } - }) -} diff --git a/test/integration/master_data/product_test.go b/test/integration/master_data/product_test.go deleted file mode 100644 index 4ffb1463..00000000 --- a/test/integration/master_data/product_test.go +++ /dev/null @@ -1,410 +0,0 @@ -package test - -import ( - "encoding/json" - "errors" - "fmt" - "net/http" - "strings" - "testing" - - "github.com/gofiber/fiber/v2" - "gorm.io/gorm" - - "gitlab.com/mbugroup/lti-api.git/internal/entities" - "gitlab.com/mbugroup/lti-api.git/internal/utils" -) - -func TestProductIntegration(t *testing.T) { - app, db := setupIntegrationApp(t) - - uomID := createUom(t, app, "Kilogram") - categoryID := createProductCategory(t, app, "Feed", "FED") - - sapSupplier1 := createSupplier(t, app, "Feed Supplier One", "fs1", string(utils.SupplierCategorySapronak)) - sapSupplier2 := createSupplier(t, app, "Feed Supplier Two", "fs2", string(utils.SupplierCategorySapronak)) - bopSupplier := createSupplier(t, app, "BOP Supplier", "bop1", string(utils.SupplierCategoryBOP)) - - productFlags := []string{string(utils.FlagDOC), string(utils.FlagPakan)} - updatedProductFlags := []string{string(utils.FlagFinisher), string(utils.FlagObat)} - - t.Run("create product without suppliers succeeds with empty relations", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodPost, "/api/master-data/products", map[string]any{ - "name": "Supplierless Product", - "brand": "Brand A", - "uom_id": uomID, - "product_category_id": categoryID, - "product_price": 12000, - }) - if resp.StatusCode != fiber.StatusCreated { - t.Fatalf("expected 201 when suppliers omitted, got %d: %s", resp.StatusCode, string(body)) - } - id := parseID(t, body) - product := fetchProduct(t, db, id) - if len(product.Suppliers) != 0 { - t.Fatalf("expected no suppliers persisted, found %d", len(product.Suppliers)) - } - if len(product.Flags) != 0 { - t.Fatalf("expected no flags persisted, found %d", len(product.Flags)) - } - resp, _ = doJSONRequest(t, app, http.MethodDelete, fmt.Sprintf("/api/master-data/products/%d", id), nil) - if resp.StatusCode != fiber.StatusOK { - t.Fatalf("expected cleanup delete to succeed, got %d", resp.StatusCode) - } - }) - - t.Run("create product with invalid uom fails", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodPost, "/api/master-data/products", map[string]any{ - "name": "Layer Feed Invalid UOM", - "brand": "Brand A", - "uom_id": 9999, - "product_category_id": categoryID, - "product_price": 12000, - "supplier_ids": []uint{sapSupplier1}, - }) - if resp.StatusCode != fiber.StatusNotFound { - t.Fatalf("expected 404 when uom missing, got %d: %s", resp.StatusCode, string(body)) - } - }) - - t.Run("create product with invalid category fails", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodPost, "/api/master-data/products", map[string]any{ - "name": "Layer Feed Invalid Category", - "brand": "Brand A", - "uom_id": uomID, - "product_category_id": 9999, - "product_price": 12000, - "supplier_ids": []uint{sapSupplier1}, - }) - if resp.StatusCode != fiber.StatusNotFound { - t.Fatalf("expected 404 when category missing, got %d: %s", resp.StatusCode, string(body)) - } - }) - - t.Run("create product with invalid supplier fails", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodPost, "/api/master-data/products", map[string]any{ - "name": "Layer Feed Missing Supplier", - "brand": "Brand A", - "uom_id": uomID, - "product_category_id": categoryID, - "product_price": 12000, - "supplier_ids": []uint{99999}, - }) - if resp.StatusCode != fiber.StatusNotFound { - t.Fatalf("expected 404 when supplier missing, got %d: %s", resp.StatusCode, string(body)) - } - }) - - t.Run("create product with BOP supplier fails", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodPost, "/api/master-data/products", map[string]any{ - "name": "Layer Feed Wrong Supplier", - "brand": "Brand A", - "uom_id": uomID, - "product_category_id": categoryID, - "product_price": 12000, - "supplier_ids": []uint{bopSupplier}, - }) - if resp.StatusCode != fiber.StatusBadRequest { - t.Fatalf("expected 400 when supplier category invalid, got %d: %s", resp.StatusCode, string(body)) - } - }) - - t.Run("create product with invalid flags fails", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodPost, "/api/master-data/products", map[string]any{ - "name": "Layer Feed Invalid Flags", - "brand": "Brand A", - "uom_id": uomID, - "product_category_id": categoryID, - "product_price": 12000, - "supplier_ids": []uint{sapSupplier1}, - "flags": []string{"INVALID"}, - }) - if resp.StatusCode != fiber.StatusBadRequest { - t.Fatalf("expected 400 when flags invalid, got %d: %s", resp.StatusCode, string(body)) - } - }) - - var productID uint - - t.Run("create product succeeds", func(t *testing.T) { - sku := "lfd-001" - productID = createProduct(t, app, "Layer Feed", "Brand A", &sku, uomID, categoryID, 15000, []uint{sapSupplier1, sapSupplier2}, productFlags) - product := fetchProduct(t, db, productID) - if product.Name != "Layer Feed" { - t.Fatalf("expected name Layer Feed, got %q", product.Name) - } - if product.Brand != "Brand A" { - t.Fatalf("expected brand Brand A, got %q", product.Brand) - } - if product.Sku == nil || *product.Sku != strings.ToUpper(sku) { - t.Fatalf("expected sku %q, got %+v", strings.ToUpper(sku), product.Sku) - } - if product.UomId != uomID { - t.Fatalf("expected uom_id %d, got %d", uomID, product.UomId) - } - if product.ProductCategoryId != categoryID { - t.Fatalf("expected product_category_id %d, got %d", categoryID, product.ProductCategoryId) - } - if product.CreatedBy != 1 { - t.Fatalf("expected created_by 1, got %d", product.CreatedBy) - } - if len(product.Suppliers) != 2 { - t.Fatalf("expected 2 suppliers, got %d", len(product.Suppliers)) - } - if len(product.Flags) != len(productFlags) { - t.Fatalf("expected %d flags, got %d", len(productFlags), len(product.Flags)) - } - expectedFlags := make(map[string]struct{}, len(productFlags)) - for _, flag := range productFlags { - expectedFlags[strings.ToUpper(flag)] = struct{}{} - } - for _, flag := range product.Flags { - if _, ok := expectedFlags[strings.ToUpper(flag.Name)]; !ok { - t.Fatalf("unexpected flag %s present", flag.Name) - } - delete(expectedFlags, strings.ToUpper(flag.Name)) - } - if len(expectedFlags) != 0 { - t.Fatalf("missing expected flags: %v", expectedFlags) - } - }) - - t.Run("creating duplicate name fails", func(t *testing.T) { - sku := "lfd-002" - resp, body := doJSONRequest(t, app, http.MethodPost, "/api/master-data/products", map[string]any{ - "name": "Layer Feed", - "brand": "Brand B", - "sku": sku, - "uom_id": uomID, - "product_category_id": categoryID, - "product_price": 16000, - "supplier_ids": []uint{sapSupplier1}, - }) - if resp.StatusCode != fiber.StatusConflict { - t.Fatalf("expected 409 when creating duplicate name, got %d: %s", resp.StatusCode, string(body)) - } - }) - - t.Run("creating duplicate sku fails", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodPost, "/api/master-data/products", map[string]any{ - "name": "Layer Feed Premium", - "brand": "Brand B", - "sku": "LFD-001", - "uom_id": uomID, - "product_category_id": categoryID, - "product_price": 17000, - "supplier_ids": []uint{sapSupplier1}, - }) - if resp.StatusCode != fiber.StatusConflict { - t.Fatalf("expected 409 when creating duplicate sku, got %d: %s", resp.StatusCode, string(body)) - } - }) - - t.Run("get product detail returns nested data", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodGet, fmt.Sprintf("/api/master-data/products/%d", productID), nil) - if resp.StatusCode != fiber.StatusOK { - t.Fatalf("expected 200 when fetching product, got %d: %s", resp.StatusCode, string(body)) - } - var payload struct { - Data struct { - Id uint `json:"id"` - Name string `json:"name"` - Brand string `json:"brand"` - Uom *struct { - Id uint `json:"id"` - } `json:"uom"` - Suppliers []map[string]any `json:"suppliers"` - Flags []string `json:"flags"` - } `json:"data"` - } - if err := json.Unmarshal(body, &payload); err != nil { - t.Fatalf("failed to parse product detail: %v", err) - } - if payload.Data.Id != productID { - t.Fatalf("expected id %d, got %d", productID, payload.Data.Id) - } - if payload.Data.Uom == nil || payload.Data.Uom.Id != uomID { - t.Fatalf("expected uom id %d, got %+v", uomID, payload.Data.Uom) - } - if len(payload.Data.Suppliers) != 2 { - t.Fatalf("expected 2 suppliers in response, got %d", len(payload.Data.Suppliers)) - } - if len(payload.Data.Flags) != len(productFlags) { - t.Fatalf("expected %d flags in response, got %d", len(productFlags), len(payload.Data.Flags)) - } - expected := make(map[string]struct{}, len(productFlags)) - for _, flag := range productFlags { - expected[strings.ToUpper(flag)] = struct{}{} - } - for _, flag := range payload.Data.Flags { - flag = strings.ToUpper(flag) - if _, ok := expected[flag]; !ok { - t.Fatalf("unexpected flag %s returned", flag) - } - delete(expected, flag) - } - if len(expected) != 0 { - t.Fatalf("missing expected flags in response: %v", expected) - } - }) - - t.Run("update product with invalid supplier category fails", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodPatch, fmt.Sprintf("/api/master-data/products/%d", productID), map[string]any{ - "supplier_ids": []uint{bopSupplier}, - }) - if resp.StatusCode != fiber.StatusBadRequest { - t.Fatalf("expected 400 when updating with non SAPRONAK supplier, got %d: %s", resp.StatusCode, string(body)) - } - }) - - t.Run("update product with invalid flags fails", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodPatch, fmt.Sprintf("/api/master-data/products/%d", productID), map[string]any{ - "flags": []string{"UNKNOWN"}, - }) - if resp.StatusCode != fiber.StatusBadRequest { - t.Fatalf("expected 400 when updating with invalid flags, got %d: %s", resp.StatusCode, string(body)) - } - }) - - t.Run("update product succeeds", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodPatch, fmt.Sprintf("/api/master-data/products/%d", productID), map[string]any{ - "name": "Layer Feed Updated", - "brand": "Brand C", - "sku": "lfd-100", - "product_price": 18000, - "selling_price": 19000, - "tax": 1000, - "expiry_period": 30, - "supplier_ids": []uint{sapSupplier1}, - "flags": updatedProductFlags, - }) - if resp.StatusCode != fiber.StatusOK { - t.Fatalf("expected 200 when updating product, got %d: %s", resp.StatusCode, string(body)) - } - var payload struct { - Data struct { - Name string `json:"name"` - Brand string `json:"brand"` - Sku *string `json:"sku"` - ProductPrice float64 `json:"product_price"` - SupplierIds []map[string]any `json:"suppliers"` - Flags []string `json:"flags"` - } `json:"data"` - } - if err := json.Unmarshal(body, &payload); err != nil { - t.Fatalf("failed to parse update response: %v", err) - } - if payload.Data.Name != "Layer Feed Updated" { - t.Fatalf("expected updated name, got %q", payload.Data.Name) - } - if len(payload.Data.Flags) != len(updatedProductFlags) { - t.Fatalf("expected %d flags in response, got %d", len(updatedProductFlags), len(payload.Data.Flags)) - } - respFlags := make(map[string]struct{}, len(payload.Data.Flags)) - for _, flag := range payload.Data.Flags { - respFlags[strings.ToUpper(flag)] = struct{}{} - } - for _, flag := range updatedProductFlags { - if _, ok := respFlags[strings.ToUpper(flag)]; !ok { - t.Fatalf("missing flag %s in response", flag) - } - } - product := fetchProduct(t, db, productID) - if product.Brand != "Brand C" { - t.Fatalf("expected persisted brand Brand C, got %q", product.Brand) - } - if product.Sku == nil || *product.Sku != "LFD-100" { - t.Fatalf("expected persisted sku LFD-100, got %+v", product.Sku) - } - if len(product.Suppliers) != 1 || product.Suppliers[0].Id != sapSupplier1 { - t.Fatalf("expected supplier to be %d", sapSupplier1) - } - if len(product.Flags) != len(updatedProductFlags) { - t.Fatalf("expected %d flags after update, got %d", len(updatedProductFlags), len(product.Flags)) - } - expectedFlags := make(map[string]struct{}, len(updatedProductFlags)) - for _, flag := range updatedProductFlags { - expectedFlags[strings.ToUpper(flag)] = struct{}{} - } - for _, flag := range product.Flags { - upper := strings.ToUpper(flag.Name) - if _, ok := expectedFlags[upper]; !ok { - t.Fatalf("unexpected flag after update: %s", upper) - } - delete(expectedFlags, upper) - } - if len(expectedFlags) != 0 { - t.Fatalf("missing flags after update: %v", expectedFlags) - } - }) - - t.Run("clear suppliers succeeds", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodPatch, fmt.Sprintf("/api/master-data/products/%d", productID), map[string]any{ - "supplier_ids": []uint{}, - }) - if resp.StatusCode != fiber.StatusOK { - t.Fatalf("expected 200 when clearing suppliers, got %d: %s", resp.StatusCode, string(body)) - } - product := fetchProduct(t, db, productID) - if len(product.Suppliers) != 0 { - t.Fatalf("expected no suppliers after clearing, got %d", len(product.Suppliers)) - } - if len(product.Flags) != len(updatedProductFlags) { - t.Fatalf("expected flags untouched after clearing suppliers, got %d", len(product.Flags)) - } - }) - - t.Run("clear flags succeeds", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodPatch, fmt.Sprintf("/api/master-data/products/%d", productID), map[string]any{ - "flags": []string{}, - }) - if resp.StatusCode != fiber.StatusOK { - t.Fatalf("expected 200 when clearing flags, got %d: %s", resp.StatusCode, string(body)) - } - product := fetchProduct(t, db, productID) - if len(product.Flags) != 0 { - t.Fatalf("expected all flags cleared, got %d", len(product.Flags)) - } - }) - - t.Run("delete product succeeds", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodDelete, fmt.Sprintf("/api/master-data/products/%d", productID), nil) - if resp.StatusCode != fiber.StatusOK { - t.Fatalf("expected 200 when deleting product, got %d: %s", resp.StatusCode, string(body)) - } - var product entities.Product - if err := db.First(&product, productID).Error; !errors.Is(err, gorm.ErrRecordNotFound) { - t.Fatalf("expected product deleted, got error %v", err) - } - var links int64 - if err := db.Model(&entities.ProductSupplier{}).Where("product_id = ?", productID).Count(&links).Error; err != nil { - t.Fatalf("failed counting product suppliers: %v", err) - } - if links != 0 { - t.Fatalf("expected pivot cleared, found %d rows", links) - } - var flagCount int64 - if err := db.Model(&entities.Flag{}). - Where("flagable_id = ? AND flagable_type = ?", productID, entities.FlagableTypeProduct). - Count(&flagCount).Error; err != nil { - t.Fatalf("failed counting product flags: %v", err) - } - if flagCount != 0 { - t.Fatalf("expected flags removed, found %d", flagCount) - } - }) - - t.Run("delete missing product returns 404", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodDelete, fmt.Sprintf("/api/master-data/products/%d", productID), nil) - if resp.StatusCode != fiber.StatusNotFound { - t.Fatalf("expected 404 when deleting missing product, got %d: %s", resp.StatusCode, string(body)) - } - }) - - t.Run("get deleted product returns 404", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodGet, fmt.Sprintf("/api/master-data/products/%d", productID), nil) - if resp.StatusCode != fiber.StatusNotFound { - t.Fatalf("expected 404 when fetching deleted product, got %d: %s", resp.StatusCode, string(body)) - } - }) -} diff --git a/test/integration/master_data/project_flock_test.go b/test/integration/master_data/project_flock_test.go deleted file mode 100644 index a7f8f3f8..00000000 --- a/test/integration/master_data/project_flock_test.go +++ /dev/null @@ -1,417 +0,0 @@ -package test - -// import ( -// "encoding/json" -// "fmt" -// "net/http" -// "net/url" -// "testing" - -// "github.com/gofiber/fiber/v2" - -// "gitlab.com/mbugroup/lti-api.git/internal/entities" -// "gitlab.com/mbugroup/lti-api.git/internal/utils" -// ) - -// func TestProjectFlockSummary(t *testing.T) { -// app, db := setupIntegrationApp(t) - -// areaID := createArea(t, app, "Area Project") -// locationID := createLocation(t, app, "Location Project", "Address", areaID) -// flockID := createFlock(t, app, "Flock Summary") -// fcrID := createFcr(t, app, "FCR Summary", []map[string]any{ -// {"weight": 1.0, "fcr_number": 1.5, "mortality": 2.0}, -// }) -// kandangID := createKandang(t, app, "Kandang Summary", locationID, 1) - -// createPayload := map[string]any{ -// "flock_id": flockID, -// "area_id": areaID, -// "category": "growing", -// "fcr_id": fcrID, -// "location_id": locationID, -// "kandang_ids": []uint{kandangID}, -// } -// resp, body := doJSONRequest(t, app, http.MethodPost, "/api/production/project_flocks", createPayload) -// if resp.StatusCode != fiber.StatusCreated { -// t.Fatalf("expected 201 when creating project flock, got %d: %s", resp.StatusCode, string(body)) -// } - -// var createResp struct { -// Data struct { -// Id uint `json:"id"` -// Period int `json:"period"` -// Category string `json:"category"` -// Flock struct { -// Id uint `json:"id"` -// Name string `json:"name"` -// } `json:"flock"` -// Area struct { -// Id uint `json:"id"` -// Name string `json:"name"` -// } `json:"area"` -// Fcr struct { -// Id uint `json:"id"` -// Name string `json:"name"` -// } `json:"fcr"` -// Location struct { -// Id uint `json:"id"` -// Name string `json:"name"` -// Address string `json:"address"` -// } `json:"location"` -// Kandangs []struct { -// Id uint `json:"id"` -// Name string `json:"name"` -// Status string `json:"status"` -// } `json:"kandangs"` -// CreatedUser struct { -// Id uint `json:"id"` -// IdUser uint `json:"id_user"` -// Email string `json:"email"` -// Name string `json:"name"` -// } `json:"created_user"` -// } `json:"data"` -// } -// if err := json.Unmarshal(body, &createResp); err != nil { -// t.Fatalf("failed to parse create response: %v", err) -// } -// if createResp.Data.Flock.Id != flockID || createResp.Data.Flock.Name == "" { -// t.Fatalf("expected flock detail to be present, got %+v", createResp.Data.Flock) -// } -// if createResp.Data.Area.Id != areaID || createResp.Data.Area.Name == "" { -// t.Fatalf("expected area detail to be present, got %+v", createResp.Data.Area) -// } -// if createResp.Data.Category != string(utils.ProjectFlockCategoryGrowing) { -// t.Fatalf("expected category to be %s, got %s", utils.ProjectFlockCategoryGrowing, createResp.Data.Category) -// } -// if createResp.Data.Location.Id != locationID || createResp.Data.Location.Name == "" { -// t.Fatalf("expected location detail to be present, got %+v", createResp.Data.Location) -// } -// if len(createResp.Data.Kandangs) != 1 || createResp.Data.Kandangs[0].Id != kandangID { -// t.Fatalf("expected kandang detail to be present, got %+v", createResp.Data.Kandangs) -// } -// if createResp.Data.Kandangs[0].Status != string(utils.KandangStatusPengajuan) { -// t.Fatalf("expected kandang status to be PENGAJUAN, got %s", createResp.Data.Kandangs[0].Status) -// } -// if createResp.Data.Period != 1 { -// t.Fatalf("expected period 1 to be assigned automatically, got %d", createResp.Data.Period) -// } - -// createdKandang := fetchKandang(t, db, kandangID) -// if createdKandang.Status != string(utils.KandangStatusPengajuan) { -// t.Fatalf("expected kandang status in DB to be PENGAJUAN, got %s", createdKandang.Status) -// } - -// var pivotRecords []entities.ProjectFlockKandang -// if err := db.Where("project_flock_id = ?", createResp.Data.Id).Find(&pivotRecords).Error; err != nil { -// t.Fatalf("failed to fetch pivot records: %v", err) -// } -// if len(pivotRecords) != 1 { -// t.Fatalf("expected 1 pivot record, got %d", len(pivotRecords)) -// } -// firstPivotRecord := pivotRecords[0] -// if firstPivotRecord.KandangId != kandangID { -// t.Fatalf("expected pivot kandang id %d, got %d", kandangID, firstPivotRecord.KandangId) -// } - -// secondKandangID := createKandang(t, app, "Kandang Summary 2", locationID, 1) -// secondPayload := map[string]any{ -// "flock_id": flockID, -// "area_id": areaID, -// "category": "laying", -// "fcr_id": fcrID, -// "location_id": locationID, -// "kandang_ids": []uint{secondKandangID}, -// } -// resp, body = doJSONRequest(t, app, http.MethodPost, "/api/production/project_flocks", secondPayload) -// if resp.StatusCode != fiber.StatusCreated { -// t.Fatalf("expected 201 when creating second project flock, got %d: %s", resp.StatusCode, string(body)) -// } -// var createRespSecond struct { -// Data struct { -// Id uint `json:"id"` -// Period int `json:"period"` -// Category string `json:"category"` -// } `json:"data"` -// } -// if err := json.Unmarshal(body, &createRespSecond); err != nil { -// t.Fatalf("failed to parse second create response: %v", err) -// } -// if createRespSecond.Data.Period != 2 { -// t.Fatalf("expected second period to be 2, got %d", createRespSecond.Data.Period) -// } -// if createRespSecond.Data.Category != string(utils.ProjectFlockCategoryLaying) { -// t.Fatalf("expected category to be %s, got %s", utils.ProjectFlockCategoryLaying, createRespSecond.Data.Category) -// } - -// pivotRecords = nil -// if err := db.Where("project_flock_id = ?", createRespSecond.Data.Id).Find(&pivotRecords).Error; err != nil { -// t.Fatalf("failed to fetch second pivot records: %v", err) -// } -// if len(pivotRecords) != 1 { -// t.Fatalf("expected 1 pivot record for second project, got %d", len(pivotRecords)) -// } -// secondPivotRecord := pivotRecords[0] -// if secondPivotRecord.KandangId != secondKandangID { -// t.Fatalf("expected second pivot kandang id %d, got %d", secondKandangID, secondPivotRecord.KandangId) -// } - -// secondKandang := fetchKandang(t, db, secondKandangID) -// if secondKandang.Status != string(utils.KandangStatusPengajuan) { -// t.Fatalf("expected second kandang status in DB to be PENGAJUAN, got %s", secondKandang.Status) -// } - -// resp, body = doJSONRequest(t, app, http.MethodGet, "/api/production/project_flocks/flocks/"+uintToString(flockID)+"/periods", nil) -// if resp.StatusCode != fiber.StatusOK { -// t.Fatalf("expected 200 when fetching summary, got %d: %s", resp.StatusCode, string(body)) -// } - -// var summary struct { -// Data struct { -// NextPeriod int `json:"next_period"` -// } `json:"data"` -// } -// if err := json.Unmarshal(body, &summary); err != nil { -// t.Fatalf("failed to parse summary response: %v", err) -// } - -// if summary.Data.NextPeriod != 3 { -// t.Fatalf("expected next_period 3, got %d", summary.Data.NextPeriod) -// } - -// resp, body = doJSONRequest(t, app, http.MethodDelete, "/api/production/project_flocks/"+uintToString(createResp.Data.Id), nil) -// if resp.StatusCode != fiber.StatusOK { -// t.Fatalf("expected 200 when deleting first project flock, got %d: %s", resp.StatusCode, string(body)) -// } - -// firstKandang := fetchKandang(t, db, kandangID) -// if firstKandang.ProjectFlockId != nil { -// t.Fatalf("expected project_flock_id to be nil after delete, got %v", *firstKandang.ProjectFlockId) -// } -// if firstKandang.Status != string(utils.KandangStatusNonActive) { -// t.Fatalf("expected kandang status to revert to NON_ACTIVE, got %s", firstKandang.Status) -// } - -// var remainingFirst int64 -// if err := db.Model(&entities.ProjectFlockKandang{}). -// Where("project_flock_id = ? AND kandang_id = ?", createResp.Data.Id, kandangID). -// Count(&remainingFirst).Error; err != nil { -// t.Fatalf("failed to count first pivot records after delete: %v", err) -// } -// if remainingFirst != 0 { -// t.Fatalf("expected no pivot records remaining after delete, found %d", remainingFirst) -// } - -// resp, body = doJSONRequest(t, app, http.MethodDelete, "/api/production/project_flocks/"+uintToString(createRespSecond.Data.Id), nil) -// if resp.StatusCode != fiber.StatusOK { -// t.Fatalf("expected 200 when deleting second project flock, got %d: %s", resp.StatusCode, string(body)) -// } - -// secondKandang = fetchKandang(t, db, secondKandangID) -// if secondKandang.ProjectFlockId != nil { -// t.Fatalf("expected second project_flock_id to be nil after delete, got %v", *secondKandang.ProjectFlockId) -// } -// if secondKandang.Status != string(utils.KandangStatusNonActive) { -// t.Fatalf("expected second kandang status to revert to NON_ACTIVE, got %s", secondKandang.Status) -// } - -// var remainingSecond int64 -// if err := db.Model(&entities.ProjectFlockKandang{}). -// Where("project_flock_id = ? AND kandang_id = ?", createRespSecond.Data.Id, secondKandangID). -// Count(&remainingSecond).Error; err != nil { -// t.Fatalf("failed to count second pivot records after delete: %v", err) -// } -// if remainingSecond != 0 { -// t.Fatalf("expected no second pivot records remaining after delete, found %d", remainingSecond) -// } - -// resp, body = doJSONRequest(t, app, http.MethodGet, "/api/production/project_flocks/flocks/"+uintToString(flockID)+"/periods", nil) -// if resp.StatusCode != fiber.StatusOK { -// t.Fatalf("expected 200 when fetching summary after delete, got %d: %s", resp.StatusCode, string(body)) -// } - -// if err := json.Unmarshal(body, &summary); err != nil { -// t.Fatalf("failed to parse summary response after delete: %v", err) -// } - -// if summary.Data.NextPeriod != 1 { -// t.Fatalf("expected next_period 1 after soft deletes, got %d", summary.Data.NextPeriod) -// } -// } - -// func uintToString(v uint) string { -// return fmt.Sprintf("%d", v) -// } - -// func TestProjectFlockSearchByRelatedFields(t *testing.T) { -// app, _ := setupIntegrationApp(t) - -// areaID := createArea(t, app, "Area Search Target") -// locationID := createLocation(t, app, "Location Search Target", "Location Address Target", areaID) -// flockID := createFlock(t, app, "Flock Search Target") -// fcrID := createFcr(t, app, "FCR Search Target", []map[string]any{ -// {"weight": 1.0, "fcr_number": 1.5, "mortality": 2.0}, -// }) -// kandangID := createKandang(t, app, "Kandang Search Target", locationID, 1) - -// createPayload := map[string]any{ -// "flock_id": flockID, -// "area_id": areaID, -// "category": "growing", -// "fcr_id": fcrID, -// "location_id": locationID, -// "kandang_ids": []uint{kandangID}, -// } - -// resp, body := doJSONRequest(t, app, http.MethodPost, "/api/production/project_flocks", createPayload) -// if resp.StatusCode != fiber.StatusCreated { -// t.Fatalf("expected 201 when creating project flock, got %d: %s", resp.StatusCode, string(body)) -// } - -// var createResp struct { -// Data struct { -// Id uint `json:"id"` -// } `json:"data"` -// } -// if err := json.Unmarshal(body, &createResp); err != nil { -// t.Fatalf("failed to parse create response: %v", err) -// } - -// searchTerms := []string{ -// "Flock Search Target", -// "Area Search Target", -// string(utils.ProjectFlockCategoryGrowing), -// "growing", -// "FCR Search Target", -// "Kandang Search Target", -// "Location Search Target", -// "Location Address Target", -// "Tester", -// "1", -// } - -// for _, term := range searchTerms { -// path := "/api/production/project_flocks?search=" + url.QueryEscape(term) -// resp, body := doJSONRequest(t, app, http.MethodGet, path, nil) -// if resp.StatusCode != fiber.StatusOK { -// t.Fatalf("expected 200 when searching for %q, got %d: %s", term, resp.StatusCode, string(body)) -// } - -// var listResp struct { -// Data []struct { -// Id uint `json:"id"` -// } `json:"data"` -// Meta struct { -// TotalResults int64 `json:"total_results"` -// } `json:"meta"` -// } -// if err := json.Unmarshal(body, &listResp); err != nil { -// t.Fatalf("failed to parse list response for %q: %v", term, err) -// } -// if listResp.Meta.TotalResults == 0 { -// t.Fatalf("expected at least one result when searching for %q", term) -// } -// if len(listResp.Data) == 0 { -// t.Fatalf("expected data when searching for %q", term) -// } -// if listResp.Data[0].Id != createResp.Data.Id { -// t.Fatalf("expected project flock id %d for search term %q, got %d", createResp.Data.Id, term, listResp.Data[0].Id) -// } -// } -// } - -// func TestProjectFlockSorting(t *testing.T) { -// app, _ := setupIntegrationApp(t) - -// areaA := createArea(t, app, "Area Alpha") -// areaB := createArea(t, app, "Area Beta") - -// locationA := createLocation(t, app, "Location Alpha", "Address Alpha", areaA) -// locationB := createLocation(t, app, "Location Beta", "Address Beta", areaB) - -// flockOne := createFlock(t, app, "Flock Sort One") -// flockTwo := createFlock(t, app, "Flock Sort Two") - -// fcrID := createFcr(t, app, "FCR Sort", []map[string]any{ -// {"weight": 1.0, "fcr_number": 1.5, "mortality": 2.0}, -// }) - -// kandangOne := createKandang(t, app, "Kandang Sort One", locationA, 1) -// kandangTwo := createKandang(t, app, "Kandang Sort Two", locationB, 1) -// kandangThree := createKandang(t, app, "Kandang Sort Three", locationB, 1) - -// projectOnePayload := map[string]any{ -// "flock_id": flockOne, -// "area_id": areaA, -// "category": "growing", -// "fcr_id": fcrID, -// "location_id": locationA, -// "kandang_ids": []uint{kandangOne}, -// } -// resp, body := doJSONRequest(t, app, http.MethodPost, "/api/production/project_flocks", projectOnePayload) -// if resp.StatusCode != fiber.StatusCreated { -// t.Fatalf("expected 201 for project one, got %d: %s", resp.StatusCode, string(body)) -// } -// projectOneID := parseProjectFlockID(t, body) - -// projectTwoPayload := map[string]any{ -// "flock_id": flockTwo, -// "area_id": areaB, -// "category": "laying", -// "fcr_id": fcrID, -// "location_id": locationB, -// "kandang_ids": []uint{kandangTwo, kandangThree}, -// } -// resp, body = doJSONRequest(t, app, http.MethodPost, "/api/production/project_flocks", projectTwoPayload) -// if resp.StatusCode != fiber.StatusCreated { -// t.Fatalf("expected 201 for project two, got %d: %s", resp.StatusCode, string(body)) -// } -// projectTwoID := parseProjectFlockID(t, body) - -// updatePeriodPayload := map[string]any{"period": 5} -// resp, body = doJSONRequest(t, app, http.MethodPatch, "/api/production/project_flocks/"+uintToString(projectTwoID), updatePeriodPayload) -// if resp.StatusCode != fiber.StatusOK { -// t.Fatalf("expected 200 when updating period, got %d: %s", resp.StatusCode, string(body)) -// } - -// assertOrder := func(t *testing.T, app *fiber.App, query string, expectedFirst uint) { -// t.Helper() -// resp, body := doJSONRequest(t, app, http.MethodGet, "/api/production/project_flocks?"+query, nil) -// if resp.StatusCode != fiber.StatusOK { -// t.Fatalf("expected 200 for query %q, got %d: %s", query, resp.StatusCode, string(body)) -// } -// var listResp struct { -// Data []struct { -// Id uint `json:"id"` -// } `json:"data"` -// } -// if err := json.Unmarshal(body, &listResp); err != nil { -// t.Fatalf("failed to parse list response for %q: %v", query, err) -// } -// if len(listResp.Data) == 0 { -// t.Fatalf("expected data for query %q", query) -// } -// if listResp.Data[0].Id != expectedFirst { -// t.Fatalf("expected first id %d for query %q, got %d", expectedFirst, query, listResp.Data[0].Id) -// } -// } - -// assertOrder(t, app, "sort_by=area&sort_order=asc", projectOneID) -// assertOrder(t, app, "sort_by=location&sort_order=desc", projectTwoID) -// assertOrder(t, app, "sort_by=period&sort_order=desc", projectTwoID) -// assertOrder(t, app, "sort_by=kandangs&sort_order=desc", projectTwoID) -// assertOrder(t, app, "sort_by=kandangs&sort_order=asc", projectOneID) -// } - -// func parseProjectFlockID(t *testing.T, body []byte) uint { -// t.Helper() -// var resp struct { -// Data struct { -// Id uint `json:"id"` -// } `json:"data"` -// } -// if err := json.Unmarshal(body, &resp); err != nil { -// t.Fatalf("failed to parse project flock response: %v", err) -// } -// return resp.Data.Id -// } diff --git a/test/integration/master_data/supplier_test.go b/test/integration/master_data/supplier_test.go deleted file mode 100644 index 2a53d9a5..00000000 --- a/test/integration/master_data/supplier_test.go +++ /dev/null @@ -1,238 +0,0 @@ -package test - -import ( - "encoding/json" - "errors" - "fmt" - "net/http" - "strings" - "testing" - - "github.com/gofiber/fiber/v2" - "gorm.io/gorm" - - "gitlab.com/mbugroup/lti-api.git/internal/entities" - "gitlab.com/mbugroup/lti-api.git/internal/utils" -) - -func TestSupplierIntegration(t *testing.T) { - app, db := setupIntegrationApp(t) - - t.Run("creating supplier with invalid type fails", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodPost, "/api/master-data/suppliers", map[string]any{ - "name": "Invalid Supplier", - "alias": "inv01", - "pic": "Jane Doe", - "type": "random-type", - "category": utils.SupplierCategoryBOP, - "hatchery": "Hatchery X", - "phone": "081234567891", - "email": "invalid@supplier.com", - "address": "Somewhere", - "npwp": "NPWP-INVALID", - "account_number": "ACC-INVALID", - "due_date": 30, - }) - if resp.StatusCode != fiber.StatusBadRequest { - t.Fatalf("expected 400 when type is invalid, got %d: %s", resp.StatusCode, string(body)) - } - }) - - t.Run("creating supplier with invalid category fails", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodPost, "/api/master-data/suppliers", map[string]any{ - "name": "Invalid Category Supplier", - "alias": "cat01", - "pic": "Jane Doe", - "type": utils.CustomerSupplierTypeBisnis, - "category": "invalid", - "phone": "081234567892", - "email": "invalid-category@supplier.com", - "address": "Somewhere", - "due_date": 30, - }) - if resp.StatusCode != fiber.StatusBadRequest { - t.Fatalf("expected 400 when category is invalid, got %d: %s", resp.StatusCode, string(body)) - } - }) - - const supplierName = "Supplier Alpha" - const alias = "al001" - var supplierID uint - - t.Run("creating supplier succeeds", func(t *testing.T) { - supplierID = createSupplier(t, app, supplierName, alias, string(utils.SupplierCategoryBOP)) - supplier := fetchSupplier(t, db, supplierID) - if supplier.Name != supplierName { - t.Fatalf("expected name %q, got %q", supplierName, supplier.Name) - } - if supplier.Alias != strings.ToUpper(alias) { - t.Fatalf("expected alias %q, got %q", strings.ToUpper(alias), supplier.Alias) - } - if supplier.Type != string(utils.CustomerSupplierTypeBisnis) { - t.Fatalf("expected type %q, got %q", utils.CustomerSupplierTypeBisnis, supplier.Type) - } - if supplier.Category != string(utils.SupplierCategoryBOP) { - t.Fatalf("expected category %q, got %q", utils.SupplierCategoryBOP, supplier.Category) - } - if supplier.DueDate != 30 { - t.Fatalf("expected due date 30, got %d", supplier.DueDate) - } - if supplier.CreatedUser.Id != 1 { - t.Fatalf("expected created user id 1, got %d", supplier.CreatedUser.Id) - } - }) - - t.Run("creating supplier with duplicate name fails", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodPost, "/api/master-data/suppliers", map[string]any{ - "name": supplierName, - "alias": "dup01", - "pic": "Jane Doe", - "type": utils.CustomerSupplierTypeBisnis, - "category": utils.SupplierCategoryBOP, - "phone": "0811111111", - "email": "duplicate@supplier.com", - "address": "Duplicate address", - "due_date": 15, - }) - if resp.StatusCode != fiber.StatusConflict { - t.Fatalf("expected 409 when creating duplicate supplier, got %d: %s", resp.StatusCode, string(body)) - } - }) - - t.Run("getting existing supplier succeeds", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodGet, fmt.Sprintf("/api/master-data/suppliers/%d", supplierID), nil) - if resp.StatusCode != fiber.StatusOK { - t.Fatalf("expected 200 when fetching supplier, got %d: %s", resp.StatusCode, string(body)) - } - var payload struct { - Data struct { - Id uint `json:"id"` - Name string `json:"name"` - Alias string `json:"alias"` - Type string `json:"type"` - Category string `json:"category"` - CreatedUser *struct { - Id uint `json:"id"` - } `json:"created_user"` - } `json:"data"` - } - if err := json.Unmarshal(body, &payload); err != nil { - t.Fatalf("failed to parse supplier response: %v", err) - } - if payload.Data.Id != supplierID { - t.Fatalf("expected id %d, got %d", supplierID, payload.Data.Id) - } - if payload.Data.Name != supplierName { - t.Fatalf("expected name %q, got %q", supplierName, payload.Data.Name) - } - if payload.Data.Alias != strings.ToUpper(alias) { - t.Fatalf("expected alias %q, got %q", strings.ToUpper(alias), payload.Data.Alias) - } - if payload.Data.Type != string(utils.CustomerSupplierTypeBisnis) { - t.Fatalf("expected type %q, got %q", utils.CustomerSupplierTypeBisnis, payload.Data.Type) - } - if payload.Data.Category != string(utils.SupplierCategoryBOP) { - t.Fatalf("expected category %q, got %q", utils.SupplierCategoryBOP, payload.Data.Category) - } - if payload.Data.CreatedUser == nil || payload.Data.CreatedUser.Id != 1 { - t.Fatalf("expected created_user id 1, got %+v", payload.Data.CreatedUser) - } - }) - - const updatedAlias = "beta1" - - t.Run("updating supplier fields succeeds", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodPatch, fmt.Sprintf("/api/master-data/suppliers/%d", supplierID), map[string]any{ - "alias": updatedAlias, - "type": utils.CustomerSupplierTypeIndividual, - "category": utils.SupplierCategorySapronak, - "due_date": 45, - }) - if resp.StatusCode != fiber.StatusOK { - t.Fatalf("expected 200 when updating supplier, got %d: %s", resp.StatusCode, string(body)) - } - var payload struct { - Data struct { - Alias string `json:"alias"` - Type string `json:"type"` - Category string `json:"category"` - } `json:"data"` - } - if err := json.Unmarshal(body, &payload); err != nil { - t.Fatalf("failed to parse update response: %v", err) - } - if payload.Data.Alias != strings.ToUpper(updatedAlias) { - t.Fatalf("expected alias %q, got %q", strings.ToUpper(updatedAlias), payload.Data.Alias) - } - if payload.Data.Type != string(utils.CustomerSupplierTypeIndividual) { - t.Fatalf("expected type %q, got %q", utils.CustomerSupplierTypeIndividual, payload.Data.Type) - } - if payload.Data.Category != string(utils.SupplierCategorySapronak) { - t.Fatalf("expected category %q, got %q", utils.SupplierCategorySapronak, payload.Data.Category) - } - supplier := fetchSupplier(t, db, supplierID) - if supplier.Alias != strings.ToUpper(updatedAlias) { - t.Fatalf("expected persisted alias %q, got %q", strings.ToUpper(updatedAlias), supplier.Alias) - } - if supplier.Type != string(utils.CustomerSupplierTypeIndividual) { - t.Fatalf("expected persisted type %q, got %q", utils.CustomerSupplierTypeIndividual, supplier.Type) - } - if supplier.Category != string(utils.SupplierCategorySapronak) { - t.Fatalf("expected persisted category %q, got %q", utils.SupplierCategorySapronak, supplier.Category) - } - if supplier.DueDate != 45 { - t.Fatalf("expected due date 45, got %d", supplier.DueDate) - } - }) - - t.Run("updating supplier with invalid type fails", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodPatch, fmt.Sprintf("/api/master-data/suppliers/%d", supplierID), map[string]any{ - "type": "invalid-type", - }) - if resp.StatusCode != fiber.StatusBadRequest { - t.Fatalf("expected 400 when updating with invalid type, got %d: %s", resp.StatusCode, string(body)) - } - supplier := fetchSupplier(t, db, supplierID) - if supplier.Type != string(utils.CustomerSupplierTypeIndividual) { - t.Fatalf("expected type to remain %q after invalid update, got %q", utils.CustomerSupplierTypeIndividual, supplier.Type) - } - }) - - t.Run("updating supplier with invalid category fails", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodPatch, fmt.Sprintf("/api/master-data/suppliers/%d", supplierID), map[string]any{ - "category": "invalid", - }) - if resp.StatusCode != fiber.StatusBadRequest { - t.Fatalf("expected 400 when updating with invalid category, got %d: %s", resp.StatusCode, string(body)) - } - supplier := fetchSupplier(t, db, supplierID) - if supplier.Category != string(utils.SupplierCategorySapronak) { - t.Fatalf("expected category to remain %q after invalid update, got %q", utils.SupplierCategorySapronak, supplier.Category) - } - }) - - t.Run("deleting supplier succeeds", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodDelete, fmt.Sprintf("/api/master-data/suppliers/%d", supplierID), nil) - if resp.StatusCode != fiber.StatusOK { - t.Fatalf("expected 200 when deleting supplier, got %d: %s", resp.StatusCode, string(body)) - } - var supplier entities.Supplier - if err := db.First(&supplier, supplierID).Error; !errors.Is(err, gorm.ErrRecordNotFound) { - t.Fatalf("expected supplier to be deleted, got error %v", err) - } - }) - - t.Run("deleting non existent supplier returns 404", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodDelete, fmt.Sprintf("/api/master-data/suppliers/%d", supplierID), nil) - if resp.StatusCode != fiber.StatusNotFound { - t.Fatalf("expected 404 when deleting missing supplier, got %d: %s", resp.StatusCode, string(body)) - } - }) - - t.Run("getting deleted supplier returns 404", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodGet, fmt.Sprintf("/api/master-data/suppliers/%d", supplierID), nil) - if resp.StatusCode != fiber.StatusNotFound { - t.Fatalf("expected 404 when fetching deleted supplier, got %d: %s", resp.StatusCode, string(body)) - } - }) -} diff --git a/test/integration/master_data/warehouse_test.go b/test/integration/master_data/warehouse_test.go deleted file mode 100644 index 72b267c3..00000000 --- a/test/integration/master_data/warehouse_test.go +++ /dev/null @@ -1,96 +0,0 @@ -package test - -import ( - "net/http" - "testing" - - "github.com/gofiber/fiber/v2" -) - -func TestWarehouseIntegration(t *testing.T) { - app, db := setupIntegrationApp(t) - areaID := createArea(t, app, "Warehouse Area") - locationID := createLocation(t, app, "Location WH", "Addr", areaID) - kandangID := createKandang(t, app, "Kandang WH", locationID, 1) - - t.Run("type AREA only needs area_id", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodPost, "/api/master-data/warehouses", map[string]any{ - "name": "WH Area", - "type": "AREA", - "area_id": areaID, - }) - if resp.StatusCode != fiber.StatusCreated { - t.Fatalf("expected 201, got %d: %s", resp.StatusCode, string(body)) - } - }) - - t.Run("type AREA rejects location_id", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodPost, "/api/master-data/warehouses", map[string]any{ - "name": "WH Area Invalid", - "type": "AREA", - "area_id": areaID, - "location_id": locationID, - }) - if resp.StatusCode != fiber.StatusBadRequest { - t.Fatalf("expected 400, got %d: %s", resp.StatusCode, string(body)) - } - }) - - t.Run("type LOKASI requires location_id", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodPost, "/api/master-data/warehouses", map[string]any{ - "name": "WH Lokasi Fail", - "type": "LOKASI", - "area_id": areaID, - }) - if resp.StatusCode != fiber.StatusBadRequest { - t.Fatalf("expected 400, got %d: %s", resp.StatusCode, string(body)) - } - }) - - t.Run("type LOKASI success", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodPost, "/api/master-data/warehouses", map[string]any{ - "name": "WH Lokasi", - "type": "LOKASI", - "area_id": areaID, - "location_id": locationID, - }) - if resp.StatusCode != fiber.StatusCreated { - t.Fatalf("expected 201, got %d: %s", resp.StatusCode, string(body)) - } - whID := parseID(t, body) - wh := fetchWarehouse(t, db, whID) - if wh.LocationId == nil || *wh.LocationId != locationID { - t.Fatalf("expected location_id %d, got %v", locationID, wh.LocationId) - } - }) - - t.Run("type KANDANG requires all ids", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodPost, "/api/master-data/warehouses", map[string]any{ - "name": "WH Kandang Fail", - "type": "KANDANG", - "area_id": areaID, - "location_id": locationID, - }) - if resp.StatusCode != fiber.StatusBadRequest { - t.Fatalf("expected 400, got %d: %s", resp.StatusCode, string(body)) - } - }) - - t.Run("type KANDANG success", func(t *testing.T) { - resp, body := doJSONRequest(t, app, http.MethodPost, "/api/master-data/warehouses", map[string]any{ - "name": "WH Kandang", - "type": "KANDANG", - "area_id": areaID, - "location_id": locationID, - "kandang_id": kandangID, - }) - if resp.StatusCode != fiber.StatusCreated { - t.Fatalf("expected 201, got %d: %s", resp.StatusCode, string(body)) - } - whID := parseID(t, body) - wh := fetchWarehouse(t, db, whID) - if wh.KandangId == nil || *wh.KandangId != kandangID { - t.Fatalf("expected kandang_id %d, got %v", kandangID, wh.KandangId) - } - }) -} diff --git a/tools/templates/dto.tmpl b/tools/templates/dto.tmpl index 39b92884..484ee0ae 100644 --- a/tools/templates/dto.tmpl +++ b/tools/templates/dto.tmpl @@ -9,7 +9,7 @@ import ( // === DTO Structs === -type {{Pascal .Entity}}BaseDTO struct { +type {{Pascal .Entity}}RelationDTO struct { Id uint `json:"id"` Name string `json:"name"` } @@ -17,7 +17,7 @@ type {{Pascal .Entity}}BaseDTO struct { type {{Pascal .Entity}}ListDTO struct { Id uint `json:"id"` Name string `json:"name"` - CreatedUser *userDTO.UserBaseDTO `json:"created_user"` + CreatedUser *userDTO.UserRelationDTO `json:"created_user"` CreatedAt time.Time `json:"created_at"` UpdatedAt time.Time `json:"updated_at"` } @@ -28,17 +28,17 @@ type {{Pascal .Entity}}DetailDTO struct { // === Mapper Functions === -func To{{Pascal .Entity}}BaseDTO(e entity.{{Pascal .Entity}}) {{Pascal .Entity}}BaseDTO { - return {{Pascal .Entity}}BaseDTO{ +func To{{Pascal .Entity}}RelationDTO(e entity.{{Pascal .Entity}}) {{Pascal .Entity}}RelationDTO { + return {{Pascal .Entity}}RelationDTO{ Id: e.Id, Name: e.Name, } } func To{{Pascal .Entity}}ListDTO(e entity.{{Pascal .Entity}}) {{Pascal .Entity}}ListDTO { - var createdUser *userDTO.UserBaseDTO + var createdUser *userDTO.UserRelationDTO if e.CreatedUser.Id != 0 { - mapped := userDTO.ToUserBaseDTO(e.CreatedUser) + mapped := userDTO.ToUserRelationDTO(e.CreatedUser) createdUser = &mapped }