mirror of
https://gitlab.com/mbugroup/lti-api.git
synced 2026-05-20 13:31:56 +00:00
Merge branch 'feat/BE/Sprint-5' of https://gitlab.com/mbugroup/lti-api into dev/teguh
This commit is contained in:
@@ -0,0 +1,16 @@
|
||||
BEGIN;
|
||||
|
||||
ALTER TABLE project_flock_kandangs
|
||||
DROP COLUMN IF EXISTS period;
|
||||
|
||||
ALTER TABLE project_flocks
|
||||
ADD COLUMN IF NOT EXISTS period INT NOT NULL DEFAULT 0;
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS project_flocks_base_period_unique
|
||||
ON project_flocks (
|
||||
LOWER(TRIM(regexp_replace(flock_name, '\\s+\\d+(\\s+\\d+)*$', '', 'g'))),
|
||||
period
|
||||
)
|
||||
WHERE deleted_at IS NULL;
|
||||
|
||||
COMMIT;
|
||||
@@ -0,0 +1,29 @@
|
||||
BEGIN;
|
||||
|
||||
ALTER TABLE project_flock_kandangs
|
||||
ADD COLUMN IF NOT EXISTS period INT;
|
||||
|
||||
UPDATE project_flock_kandangs pfk
|
||||
SET period = pf.period
|
||||
FROM project_flocks pf
|
||||
WHERE pfk.project_flock_id = pf.id
|
||||
AND (pfk.period IS NULL OR pfk.period = 0)
|
||||
AND pf.period IS NOT NULL;
|
||||
|
||||
ALTER TABLE project_flock_kandangs
|
||||
ALTER COLUMN period SET DEFAULT 0;
|
||||
|
||||
UPDATE project_flock_kandangs
|
||||
SET period = 0
|
||||
WHERE period IS NULL;
|
||||
|
||||
ALTER TABLE project_flock_kandangs
|
||||
ALTER COLUMN period SET NOT NULL;
|
||||
|
||||
-- Drop period from project_flocks as the source of truth
|
||||
DROP INDEX IF EXISTS project_flocks_base_period_unique;
|
||||
|
||||
ALTER TABLE project_flocks
|
||||
DROP COLUMN IF EXISTS period;
|
||||
|
||||
COMMIT;
|
||||
@@ -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,
|
||||
|
||||
@@ -16,6 +16,7 @@ type Location struct {
|
||||
UpdatedAt time.Time `gorm:"autoUpdateTime"`
|
||||
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
|
||||
|
||||
CreatedUser User `gorm:"foreignKey:CreatedBy;references:Id"`
|
||||
Area Area `gorm:"foreignKey:AreaId;references:Id"`
|
||||
CreatedUser User `gorm:"foreignKey:CreatedBy;references:Id"`
|
||||
Area Area `gorm:"foreignKey:AreaId;references:Id"`
|
||||
Kandangs []Kandang `gorm:"foreignKey:LocationId;references:Id"`
|
||||
}
|
||||
|
||||
@@ -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"`
|
||||
}
|
||||
|
||||
@@ -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"`
|
||||
}
|
||||
|
||||
@@ -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"`
|
||||
}
|
||||
|
||||
@@ -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"`
|
||||
}
|
||||
|
||||
@@ -13,7 +13,6 @@ type ProjectFlock struct {
|
||||
Category string `gorm:"type:varchar(20);not null"`
|
||||
FcrId uint `gorm:"not null"`
|
||||
LocationId uint `gorm:"not null"`
|
||||
Period int `gorm:"not null"`
|
||||
CreatedBy uint `gorm:"not null"`
|
||||
CreatedAt time.Time `gorm:"autoCreateTime"`
|
||||
UpdatedAt time.Time `gorm:"autoUpdateTime"`
|
||||
@@ -28,4 +27,3 @@ type ProjectFlock struct {
|
||||
|
||||
LatestApproval *Approval `gorm:"-" json:"-"`
|
||||
}
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ type ProjectFlockKandang struct {
|
||||
Id uint `gorm:"primaryKey"`
|
||||
ProjectFlockId uint `gorm:"not null;index:idx_project_flock_kandangs_project;uniqueIndex:idx_project_flock_kandangs_unique"`
|
||||
KandangId uint `gorm:"not null;index:idx_project_flock_kandangs_kandang;uniqueIndex:idx_project_flock_kandangs_unique"`
|
||||
Period int `gorm:"not null"`
|
||||
CreatedAt time.Time `gorm:"autoCreateTime"`
|
||||
|
||||
ProjectFlock ProjectFlock `gorm:"foreignKey:ProjectFlockId;references:Id"`
|
||||
|
||||
@@ -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"`
|
||||
}
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -13,55 +13,68 @@ import (
|
||||
)
|
||||
|
||||
// === DTO Structs ===
|
||||
|
||||
type ExpenseRelationDTO struct {
|
||||
Id uint64 `json:"id"`
|
||||
PoNumber string `json:"po_number"`
|
||||
ExpenseDate time.Time `json:"expense_date"`
|
||||
GrandTotal float64 `json:"grand_total"`
|
||||
}
|
||||
|
||||
type ExpenseBaseDTO struct {
|
||||
Id uint64 `json:"id"`
|
||||
ReferenceNumber string `json:"reference_number"`
|
||||
PoNumber string `json:"po_number"`
|
||||
Category string `json:"category"`
|
||||
Supplier *supplierDTO.SupplierBaseDTO `json:"supplier,omitempty"`
|
||||
RealizationDate *time.Time `json:"realization_date,omitempty"`
|
||||
ExpenseDate time.Time `json:"expense_date"`
|
||||
GrandTotal float64 `json:"grand_total"`
|
||||
Location *locationDTO.LocationBaseDTO `json:"location,omitempty"`
|
||||
Id uint64 `json:"id"`
|
||||
ReferenceNumber string `json:"reference_number"`
|
||||
PoNumber string `json:"po_number"`
|
||||
Category string `json:"category"`
|
||||
Supplier *supplierDTO.SupplierRelationDTO `json:"supplier,omitempty"`
|
||||
RealizationDate *time.Time `json:"realization_date,omitempty"`
|
||||
ExpenseDate time.Time `json:"expense_date"`
|
||||
GrandTotal float64 `json:"grand_total"`
|
||||
Location *locationDTO.LocationRelationDTO `json:"location,omitempty"`
|
||||
}
|
||||
|
||||
type ExpenseListDTO struct {
|
||||
ExpenseBaseDTO
|
||||
CreatedUser *userDTO.UserBaseDTO `json:"created_user,omitempty"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
LatestApproval *approvalDTO.ApprovalBaseDTO `json:"latest_approval,omitempty"`
|
||||
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"`
|
||||
LatestApproval *approvalDTO.ApprovalRelationDTO `json:"latest_approval,omitempty"`
|
||||
}
|
||||
|
||||
type ExpenseDetailDTO struct {
|
||||
ExpenseBaseDTO
|
||||
Documents []DocumentDTO `json:"documents,omitempty"`
|
||||
RealizationDocs []DocumentDTO `json:"realization_docs,omitempty"`
|
||||
CreatedUser *userDTO.UserBaseDTO `json:"created_user,omitempty"`
|
||||
Kandangs []KandangGroupDTO `json:"kandangs,omitempty"`
|
||||
TotalPengajuan float64 `json:"total_pengajuan"`
|
||||
TotalRealisasi float64 `json:"total_realisasi"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
LatestApproval *approvalDTO.ApprovalBaseDTO `json:"latest_approval,omitempty"`
|
||||
Documents []DocumentDTO `json:"documents,omitempty"`
|
||||
RealizationDocs []DocumentDTO `json:"realization_docs,omitempty"`
|
||||
CreatedUser *userDTO.UserRelationDTO `json:"created_user,omitempty"`
|
||||
Kandangs []KandangGroupDTO `json:"kandangs,omitempty"`
|
||||
TotalPengajuan float64 `json:"total_pengajuan"`
|
||||
TotalRealisasi float64 `json:"total_realisasi"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
LatestApproval *approvalDTO.ApprovalRelationDTO `json:"latest_approval,omitempty"`
|
||||
}
|
||||
|
||||
type ExpenseNonstockDTO struct {
|
||||
Id uint64 `json:"id"`
|
||||
Qty float64 `json:"qty"`
|
||||
UnitPrice float64 `json:"unit_price"`
|
||||
TotalPrice float64 `json:"total_price"`
|
||||
Note *string `json:"note,omitempty"`
|
||||
Nonstock *nonstockDTO.NonstockBaseDTO `json:"nonstock,omitempty"`
|
||||
Id uint64 `json:"id"`
|
||||
Qty float64 `json:"qty"`
|
||||
UnitPrice float64 `json:"unit_price"`
|
||||
TotalPrice float64 `json:"total_price"`
|
||||
Note *string `json:"note,omitempty"`
|
||||
Nonstock *nonstockDTO.NonstockRelationDTO `json:"nonstock,omitempty"`
|
||||
}
|
||||
|
||||
type ExpenseRealizationDTO struct {
|
||||
Id uint64 `json:"id"`
|
||||
Qty float64 `json:"qty"`
|
||||
UnitPrice float64 `json:"unit_price"`
|
||||
TotalPrice float64 `json:"total_price"`
|
||||
Note *string `json:"note,omitempty"`
|
||||
Nonstock *nonstockDTO.NonstockBaseDTO `json:"nonstock,omitempty"`
|
||||
Id uint64 `json:"id"`
|
||||
Qty float64 `json:"qty"`
|
||||
UnitPrice float64 `json:"unit_price"`
|
||||
TotalPrice float64 `json:"total_price"`
|
||||
Note *string `json:"note,omitempty"`
|
||||
Nonstock *nonstockDTO.NonstockRelationDTO `json:"nonstock,omitempty"`
|
||||
}
|
||||
|
||||
type KandangGroupDTO struct {
|
||||
@@ -79,9 +92,18 @@ type DocumentDTO struct {
|
||||
|
||||
// === MAPPERS ===
|
||||
|
||||
func ToExpenseRelationDTO(e entity.Expense) ExpenseRelationDTO {
|
||||
return ExpenseRelationDTO{
|
||||
Id: e.Id,
|
||||
PoNumber: e.PoNumber,
|
||||
ExpenseDate: e.ExpenseDate,
|
||||
GrandTotal: e.GrandTotal,
|
||||
}
|
||||
}
|
||||
|
||||
func ToExpenseBaseDTO(e *entity.Expense) ExpenseBaseDTO {
|
||||
var location *locationDTO.LocationBaseDTO
|
||||
var supplier *supplierDTO.SupplierBaseDTO
|
||||
var location *locationDTO.LocationRelationDTO
|
||||
var supplier *supplierDTO.SupplierRelationDTO
|
||||
|
||||
var realizationDate *time.Time
|
||||
if !e.RealizationDate.IsZero() {
|
||||
@@ -90,13 +112,13 @@ func ToExpenseBaseDTO(e *entity.Expense) ExpenseBaseDTO {
|
||||
|
||||
if len(e.Nonstocks) > 0 && e.Nonstocks[0].Kandang != nil {
|
||||
if e.Nonstocks[0].Kandang.Location.Id != 0 {
|
||||
mapped := locationDTO.ToLocationBaseDTO(e.Nonstocks[0].Kandang.Location)
|
||||
mapped := locationDTO.ToLocationRelationDTO(e.Nonstocks[0].Kandang.Location)
|
||||
location = &mapped
|
||||
}
|
||||
}
|
||||
|
||||
if e.Supplier != nil && e.Supplier.Id != 0 {
|
||||
mapped := supplierDTO.ToSupplierBaseDTO(*e.Supplier)
|
||||
mapped := supplierDTO.ToSupplierRelationDTO(*e.Supplier)
|
||||
supplier = &mapped
|
||||
}
|
||||
|
||||
@@ -113,32 +135,37 @@ func ToExpenseBaseDTO(e *entity.Expense) ExpenseBaseDTO {
|
||||
}
|
||||
}
|
||||
|
||||
func ToExpenseListDTO(e *entity.Expense) ExpenseListDTO {
|
||||
var createdUser *userDTO.UserBaseDTO
|
||||
if e.CreatedUser != nil && e.CreatedUser.Id != 0 {
|
||||
mapped := userDTO.ToUserBaseDTO(*e.CreatedUser)
|
||||
func ToExpenseListDTO(e entity.Expense) ExpenseListDTO {
|
||||
var createdUser *userDTO.UserRelationDTO
|
||||
if e.CreatedUser.Id != 0 {
|
||||
mapped := userDTO.ToUserRelationDTO(*e.CreatedUser)
|
||||
createdUser = &mapped
|
||||
}
|
||||
|
||||
var latestApproval *approvalDTO.ApprovalBaseDTO
|
||||
var latestApproval *approvalDTO.ApprovalRelationDTO
|
||||
if e.LatestApproval != nil {
|
||||
mapped := approvalDTO.ToApprovalDTO(*e.LatestApproval)
|
||||
latestApproval = &mapped
|
||||
}
|
||||
|
||||
return ExpenseListDTO{
|
||||
ExpenseBaseDTO: ToExpenseBaseDTO(e),
|
||||
CreatedUser: createdUser,
|
||||
CreatedAt: e.CreatedAt,
|
||||
UpdatedAt: e.UpdatedAt,
|
||||
LatestApproval: latestApproval,
|
||||
Id: e.Id,
|
||||
ReferenceNumber: e.ReferenceNumber,
|
||||
PoNumber: e.PoNumber,
|
||||
Category: e.Category,
|
||||
ExpenseDate: e.ExpenseDate,
|
||||
GrandTotal: e.GrandTotal,
|
||||
CreatedUser: createdUser,
|
||||
CreatedAt: e.CreatedAt,
|
||||
UpdatedAt: e.UpdatedAt,
|
||||
LatestApproval: latestApproval,
|
||||
}
|
||||
}
|
||||
|
||||
func ToExpenseListDTOs(expenses []entity.Expense) []ExpenseListDTO {
|
||||
result := make([]ExpenseListDTO, len(expenses))
|
||||
for i, expense := range expenses {
|
||||
result[i] = ToExpenseListDTO(&expense)
|
||||
result[i] = ToExpenseListDTO(expense)
|
||||
}
|
||||
return result
|
||||
}
|
||||
@@ -146,13 +173,13 @@ func ToExpenseListDTOs(expenses []entity.Expense) []ExpenseListDTO {
|
||||
func ToExpenseDetailDTO(e *entity.Expense) ExpenseDetailDTO {
|
||||
var documents []DocumentDTO
|
||||
var realizationDocs []DocumentDTO
|
||||
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
|
||||
}
|
||||
|
||||
var latestApproval *approvalDTO.ApprovalBaseDTO
|
||||
var latestApproval *approvalDTO.ApprovalRelationDTO
|
||||
if e.LatestApproval != nil {
|
||||
mapped := approvalDTO.ToApprovalDTO(*e.LatestApproval)
|
||||
latestApproval = &mapped
|
||||
@@ -179,9 +206,9 @@ func ToExpenseDetailDTO(e *entity.Expense) ExpenseDetailDTO {
|
||||
pengajuans = append(pengajuans, pengajuanDTO)
|
||||
|
||||
if ns.Realization != nil && ns.Realization.Id != 0 {
|
||||
var nonstock *nonstockDTO.NonstockBaseDTO
|
||||
var nonstock *nonstockDTO.NonstockRelationDTO
|
||||
if ns.Nonstock != nil && ns.Nonstock.Id != 0 {
|
||||
mapped := nonstockDTO.ToNonstockBaseDTO(*ns.Nonstock)
|
||||
mapped := nonstockDTO.ToNonstockRelationDTO(*ns.Nonstock)
|
||||
nonstock = &mapped
|
||||
}
|
||||
|
||||
@@ -207,7 +234,6 @@ func ToExpenseDetailDTO(e *entity.Expense) ExpenseDetailDTO {
|
||||
for _, r := range realisasi {
|
||||
totalRealisasi += r.TotalPrice
|
||||
}
|
||||
|
||||
kandangs := ToKandangGroupDTO(pengajuans, realisasi, e.Nonstocks)
|
||||
|
||||
return ExpenseDetailDTO{
|
||||
@@ -225,9 +251,9 @@ func ToExpenseDetailDTO(e *entity.Expense) ExpenseDetailDTO {
|
||||
}
|
||||
|
||||
func ToExpenseNonstockDTO(ns entity.ExpenseNonstock) ExpenseNonstockDTO {
|
||||
var nonstock *nonstockDTO.NonstockBaseDTO
|
||||
var nonstock *nonstockDTO.NonstockRelationDTO
|
||||
if ns.Nonstock != nil && ns.Nonstock.Id != 0 {
|
||||
mapped := nonstockDTO.ToNonstockBaseDTO(*ns.Nonstock)
|
||||
mapped := nonstockDTO.ToNonstockRelationDTO(*ns.Nonstock)
|
||||
nonstock = &mapped
|
||||
}
|
||||
|
||||
|
||||
@@ -158,22 +158,13 @@ func (s *expenseService) CreateOne(c *fiber.Ctx, req *validation.Create) (*expen
|
||||
return nil, err
|
||||
}
|
||||
|
||||
nonstockEntity, err := s.NonstockRepo.GetByID(c.Context(), nonstockId, func(db *gorm.DB) *gorm.DB {
|
||||
return db.Preload("Suppliers")
|
||||
})
|
||||
// Periksa apakah nonstock terkait dengan supplier
|
||||
supplierFound, err := s.NonstockRepo.IsNonstockAssociatedWithSupplier(c.Context(), nonstockId, req.SupplierID)
|
||||
if err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, fiber.NewError(fiber.StatusNotFound, "Nonstock not found")
|
||||
}
|
||||
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to get nonstock")
|
||||
}
|
||||
|
||||
supplierFound := false
|
||||
for _, sn := range nonstockEntity.Suppliers {
|
||||
if uint64(sn.Id) == req.SupplierID {
|
||||
supplierFound = true
|
||||
break
|
||||
}
|
||||
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to check nonstock-supplier relation")
|
||||
}
|
||||
if !supplierFound {
|
||||
return nil, fiber.NewError(fiber.StatusBadRequest, fmt.Sprintf("Nonstock ID %d does not belong to supplier ID %d", nonstockId, req.SupplierID))
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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"`
|
||||
SalesPerson userDTO.UserRelationDTO `json:"sales_person"`
|
||||
SoDocs string `json:"so_docs"`
|
||||
SalesOrder []MarketingProductDTO `json:"sales_order"`
|
||||
CreatedUser userDTO.UserRelationDTO `json:"created_user"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
LatestApproval approvalDTO.ApprovalRelationDTO `json:"latest_approval"`
|
||||
}
|
||||
|
||||
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"`
|
||||
SalesPerson userDTO.UserRelationDTO `json:"sales_person"`
|
||||
SoDocs string `json:"so_docs"`
|
||||
SalesOrder []MarketingProductDTO `json:"sales_order"`
|
||||
DeliveryOrder []DeliveryGroupDTO `json:"delivery_order"`
|
||||
CreatedUser userDTO.UserRelationDTO `json:"created_user"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
LatestApproval approvalDTO.ApprovalRelationDTO `json:"latest_approval"`
|
||||
}
|
||||
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,28 +131,28 @@ 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)
|
||||
createdUser = &mapped
|
||||
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)
|
||||
customer = &mapped
|
||||
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)
|
||||
salesPerson = &mapped
|
||||
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
|
||||
latestApproval = mapped
|
||||
}
|
||||
|
||||
var salesOrderProducts []MarketingProductDTO
|
||||
@@ -164,35 +164,35 @@ 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)
|
||||
createdUser = &mapped
|
||||
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)
|
||||
customer = &mapped
|
||||
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)
|
||||
salesPerson = &mapped
|
||||
mapped := userDTO.ToUserRelationDTO(marketing.SalesPerson)
|
||||
salesPerson = mapped
|
||||
}
|
||||
|
||||
var salesOrderProducts []MarketingProductDTO
|
||||
@@ -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
|
||||
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,
|
||||
},
|
||||
|
||||
@@ -58,7 +58,7 @@ func (s salesOrdersService) withRelations(db *gorm.DB) *gorm.DB {
|
||||
Preload("CreatedUser").
|
||||
Preload("Customer").
|
||||
Preload("SalesPerson").
|
||||
Preload("Products.ProductWarehouse.Product").
|
||||
Preload("Products.ProductWarehouse.Product.Flags").
|
||||
Preload("Products.ProductWarehouse.Warehouse")
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,25 +9,29 @@ import (
|
||||
|
||||
// === DTO Structs ===
|
||||
|
||||
type CustomerBaseDTO struct {
|
||||
Id uint `json:"id"`
|
||||
Name string `json:"name"`
|
||||
PicId uint `json:"pic_id"`
|
||||
Type string `json:"type"`
|
||||
Address string `json:"address"`
|
||||
Phone string `json:"phone"`
|
||||
Email string `json:"email"`
|
||||
AccountNumber string `json:"account_number"`
|
||||
Balance float64 `json:"balance"`
|
||||
|
||||
Pic *userDTO.UserBaseDTO `json:"pic,omitempty"`
|
||||
type CustomerRelationDTO struct {
|
||||
Id uint `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Type string `json:"type"`
|
||||
AccountNumber string `json:"account_number"`
|
||||
Balance float64 `json:"balance"`
|
||||
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"`
|
||||
Id uint `json:"id"`
|
||||
Name string `json:"name"`
|
||||
PicId uint `json:"pic_id"`
|
||||
Type string `json:"type"`
|
||||
Address string `json:"address"`
|
||||
Phone string `json:"phone"`
|
||||
Email string `json:"email"`
|
||||
AccountNumber string `json:"account_number"`
|
||||
Balance float64 `json:"balance"`
|
||||
Pic userDTO.UserRelationDTO `json:"pic"`
|
||||
CreatedUser userDTO.UserRelationDTO `json:"created_user"`
|
||||
CreatedAt time.Time `json:"created_at"`
|
||||
UpdatedAt time.Time `json:"updated_at"`
|
||||
}
|
||||
|
||||
type CustomerDetailDTO struct {
|
||||
@@ -36,14 +40,36 @@ 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,
|
||||
Type: e.Type,
|
||||
AccountNumber: e.AccountNumber,
|
||||
Pic: pic,
|
||||
}
|
||||
}
|
||||
|
||||
func ToCustomerListDTO(e entity.Customer) CustomerListDTO {
|
||||
var createdUser userDTO.UserRelationDTO
|
||||
if e.CreatedUser.Id != 0 {
|
||||
mapped := userDTO.ToUserRelationDTO(e.CreatedUser)
|
||||
createdUser = mapped
|
||||
}
|
||||
|
||||
var pic userDTO.UserRelationDTO
|
||||
if e.Pic.Id != 0 {
|
||||
mapped := userDTO.ToUserRelationDTO(e.Pic)
|
||||
pic = mapped
|
||||
}
|
||||
|
||||
return CustomerListDTO{
|
||||
Id: e.Id,
|
||||
Name: e.Name,
|
||||
PicId: e.PicId,
|
||||
@@ -53,21 +79,9 @@ func ToCustomerBaseDTO(e entity.Customer) CustomerBaseDTO {
|
||||
Email: e.Email,
|
||||
AccountNumber: e.AccountNumber,
|
||||
Pic: pic,
|
||||
}
|
||||
}
|
||||
|
||||
func ToCustomerListDTO(e entity.Customer) CustomerListDTO {
|
||||
var createdUser *userDTO.UserBaseDTO
|
||||
if e.CreatedUser.Id != 0 {
|
||||
mapped := userDTO.ToUserBaseDTO(e.CreatedUser)
|
||||
createdUser = &mapped
|
||||
}
|
||||
|
||||
return CustomerListDTO{
|
||||
CustomerBaseDTO: ToCustomerBaseDTO(e),
|
||||
CreatedAt: e.CreatedAt,
|
||||
UpdatedAt: e.UpdatedAt,
|
||||
CreatedUser: createdUser,
|
||||
CreatedAt: e.CreatedAt,
|
||||
UpdatedAt: e.UpdatedAt,
|
||||
CreatedUser: createdUser,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
location = mapped
|
||||
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)
|
||||
pic = mapped
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@ import (
|
||||
"gitlab.com/mbugroup/lti-api.git/internal/common/repository"
|
||||
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
|
||||
"gitlab.com/mbugroup/lti-api.git/internal/utils"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"gorm.io/gorm"
|
||||
)
|
||||
|
||||
@@ -120,9 +121,41 @@ func (r *KandangRepositoryImpl) UpsertProjectFlockKandang(ctx context.Context, p
|
||||
Where("project_flock_id = ? AND kandang_id = ?", projectFlockID, kandangID).
|
||||
First(&link).Error
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
var project entity.ProjectFlock
|
||||
if err := r.db.WithContext(ctx).
|
||||
Select("id, location_id").
|
||||
First(&project, projectFlockID).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
var kandang entity.Kandang
|
||||
if err := r.db.WithContext(ctx).
|
||||
Select("id, location_id").
|
||||
First(&kandang, kandangID).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if kandang.LocationId != project.LocationId {
|
||||
return fiber.NewError(fiber.StatusBadRequest, "Kandang tidak berada pada lokasi yang sama dengan project flock")
|
||||
}
|
||||
|
||||
// Determine project's period from existing pivot rows so the new kandang
|
||||
// shares the same period.
|
||||
var period int
|
||||
if err := r.db.WithContext(ctx).
|
||||
Table("project_flock_kandangs").
|
||||
Where("project_flock_id = ?", projectFlockID).
|
||||
Select("COALESCE(MAX(period), 0)").
|
||||
Scan(&period).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if period <= 0 {
|
||||
period = 1
|
||||
}
|
||||
|
||||
link = entity.ProjectFlockKandang{
|
||||
ProjectFlockId: projectFlockID,
|
||||
KandangId: kandangID,
|
||||
Period: period,
|
||||
}
|
||||
return r.db.WithContext(ctx).Create(&link).Error
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ type NonstockRepository interface {
|
||||
DeleteFlags(ctx context.Context, tx *gorm.DB, nonstockID uint) error
|
||||
GetFlags(ctx context.Context, nonstockID uint) ([]entity.Flag, error)
|
||||
IdExists(ctx context.Context, id uint) (bool, error)
|
||||
IsNonstockAssociatedWithSupplier(ctx context.Context, nonstockID uint, supplierID uint64) (bool, error)
|
||||
}
|
||||
|
||||
type NonstockRepositoryImpl struct {
|
||||
@@ -62,7 +63,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))
|
||||
@@ -71,16 +72,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) {
|
||||
@@ -175,3 +176,15 @@ func (r *NonstockRepositoryImpl) GetFlags(ctx context.Context, nonstockID uint)
|
||||
}
|
||||
return flags, nil
|
||||
}
|
||||
|
||||
func (r *NonstockRepositoryImpl) IsNonstockAssociatedWithSupplier(ctx context.Context, nonstockID uint, supplierID uint64) (bool, error) {
|
||||
var count int64
|
||||
if err := r.DB().WithContext(ctx).
|
||||
Model(&entity.NonstockSupplier{}).
|
||||
Where("nonstock_id = ? AND supplier_id = ?", nonstockID, supplierID).
|
||||
Count(&count).
|
||||
Error; err != nil {
|
||||
return false, err
|
||||
}
|
||||
return count > 0, nil
|
||||
}
|
||||
|
||||
@@ -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")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -5,93 +5,105 @@ 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,omitempty"`
|
||||
}
|
||||
|
||||
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{
|
||||
Id: e.Id,
|
||||
Name: e.Name,
|
||||
Flags: flags,
|
||||
Uom: uomRef,
|
||||
return ProductRelationDTO{
|
||||
Id: e.Id,
|
||||
Name: e.Name,
|
||||
ProductPrice: e.ProductPrice,
|
||||
SellingPrice: e.SellingPrice,
|
||||
Flags: &flags,
|
||||
Uom: uomRef,
|
||||
}
|
||||
}
|
||||
|
||||
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 +116,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,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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")
|
||||
})
|
||||
}
|
||||
|
||||
@@ -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),
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -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),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -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")
|
||||
})
|
||||
|
||||
|
||||
@@ -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"`
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
|
||||
@@ -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,75 +64,76 @@ 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(e entity.ProjectFlock) ProjectFlockDTO {
|
||||
var flock *flockBaseDTO.FlockBaseDTO
|
||||
func ToProjectFlockDTO(pfk entity.ProjectFlockKandang) ProjectFlockDTO {
|
||||
e := pfk.ProjectFlock
|
||||
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{
|
||||
Id: e.Id,
|
||||
Period: e.Period,
|
||||
Period: pfk.Period,
|
||||
Category: e.Category,
|
||||
Flock: flock,
|
||||
Area: area,
|
||||
@@ -144,12 +145,12 @@ func ToProjectFlockDTO(e entity.ProjectFlock) ProjectFlockDTO {
|
||||
func ToProjectFlockKandangDTO(e entity.ProjectFlockKandang) ProjectFlockKandangDTO {
|
||||
var pf *ProjectFlockDTO
|
||||
if e.ProjectFlock.Id != 0 {
|
||||
mapped := ToProjectFlockDTO(e.ProjectFlock)
|
||||
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{
|
||||
@@ -159,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 {
|
||||
@@ -174,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,
|
||||
@@ -200,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,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -230,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
|
||||
}
|
||||
|
||||
@@ -267,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,
|
||||
|
||||
+6
-13
@@ -4,7 +4,6 @@ import (
|
||||
"math"
|
||||
"strconv"
|
||||
|
||||
flockDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/flocks/dto"
|
||||
"gitlab.com/mbugroup/lti-api.git/internal/modules/production/project-flock-kandangs/dto"
|
||||
service "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project-flock-kandangs/services"
|
||||
validation "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project-flock-kandangs/validations"
|
||||
@@ -41,18 +40,14 @@ func (u *ProjectFlockKandangController) GetAll(c *fiber.Ctx) error {
|
||||
return fiber.NewError(fiber.StatusBadRequest, "page and limit must be greater than 0")
|
||||
}
|
||||
|
||||
results, totalResults, flockMap, err := u.ProjectFlockKandangService.GetAll(c, query)
|
||||
results, totalResults, err := u.ProjectFlockKandangService.GetAll(c, query)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
data := make([]dto.ProjectFlockKandangListDTO, 0)
|
||||
data := make([]dto.ProjectFlockKandangListDTO, 0, len(results))
|
||||
for _, result := range results {
|
||||
var flock *flockDTO.FlockBaseDTO
|
||||
if flockMap != nil {
|
||||
flock = flockMap[result.ProjectFlock.Id]
|
||||
}
|
||||
data = append(data, dto.ToProjectFlockKandangListDTOWithFlock(result, flock))
|
||||
data = append(data, dto.ToProjectFlockKandangListDTO(result))
|
||||
}
|
||||
|
||||
return c.Status(fiber.StatusOK).
|
||||
@@ -71,14 +66,12 @@ func (u *ProjectFlockKandangController) GetAll(c *fiber.Ctx) error {
|
||||
}
|
||||
|
||||
func (u *ProjectFlockKandangController) GetOne(c *fiber.Ctx) error {
|
||||
param := c.Params("id")
|
||||
|
||||
id, err := strconv.Atoi(param)
|
||||
id, err := strconv.Atoi(c.Params("id"))
|
||||
if err != nil {
|
||||
return fiber.NewError(fiber.StatusBadRequest, "Invalid Id")
|
||||
}
|
||||
|
||||
result, availableQtys, productWarehouses, flock, err := u.ProjectFlockKandangService.GetOne(c, uint(id))
|
||||
result, availableQtys, productWarehouses, err := u.ProjectFlockKandangService.GetOne(c, uint(id))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -88,6 +81,6 @@ func (u *ProjectFlockKandangController) GetOne(c *fiber.Ctx) error {
|
||||
Code: fiber.StatusOK,
|
||||
Status: "success",
|
||||
Message: "Get projectFlockKandang successfully",
|
||||
Data: dto.ToProjectFlockKandangDetailDTOWithAvailableQtyAndFlock(*result, availableQtys, productWarehouses, flock),
|
||||
Data: dto.ToProjectFlockKandangDetailDTOWithAvailableQty(*result, availableQtys, productWarehouses),
|
||||
})
|
||||
}
|
||||
|
||||
+71
-95
@@ -5,9 +5,10 @@ import (
|
||||
|
||||
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
|
||||
approvalDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/approvals/dto"
|
||||
productWarehouseDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/inventory/product-warehouses/dto"
|
||||
areaDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/areas/dto"
|
||||
fcrDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/fcrs/dto"
|
||||
flockDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/flocks/dto"
|
||||
kandangDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/kandangs/dto"
|
||||
locationDTO "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"
|
||||
@@ -18,36 +19,27 @@ 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"`
|
||||
}
|
||||
|
||||
type KandangDTO struct {
|
||||
Id uint `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Status string `json:"status"`
|
||||
projectFlockDTO.ProjectFlockRelationDTO
|
||||
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 ProductWarehouseDTO struct {
|
||||
Id uint `json:"id"`
|
||||
Product *productDTO.ProductBaseDTO `json:"product,omitempty"`
|
||||
Warehouse *warehouseDTO.WarehouseBaseDTO `json:"warehouse,omitempty"`
|
||||
productWarehouseDTO.ProductWarehouseRelationDTO
|
||||
Product *productDTO.ProductRelationDTO `json:"product,omitempty"`
|
||||
Warehouse *warehouseDTO.WarehouseRelationDTO `json:"warehouse,omitempty"`
|
||||
}
|
||||
|
||||
type AvailableQtyDTO struct {
|
||||
@@ -56,24 +48,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.KandangRelationDTO `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,
|
||||
@@ -86,38 +78,31 @@ func toProjectFlockDTO(pf *projectFlockDTO.ProjectFlockListDTO) *ProjectFlockDTO
|
||||
}
|
||||
|
||||
return &ProjectFlockDTO{
|
||||
Id: pf.Id,
|
||||
Name: pf.FlockName,
|
||||
Period: pf.Period,
|
||||
Flock: pf.Flock,
|
||||
Area: pf.Area,
|
||||
Category: pf.Category,
|
||||
Fcr: pf.Fcr,
|
||||
Location: pf.Location,
|
||||
CreatedUser: pf.CreatedUser,
|
||||
CreatedAt: pf.CreatedAt,
|
||||
UpdatedAt: pf.UpdatedAt,
|
||||
ProjectFlockRelationDTO: pf.ProjectFlockRelationDTO,
|
||||
Area: pf.Area,
|
||||
Category: pf.Category,
|
||||
Fcr: pf.Fcr,
|
||||
Location: pf.Location,
|
||||
CreatedUser: pf.CreatedUser,
|
||||
CreatedAt: pf.CreatedAt,
|
||||
UpdatedAt: pf.UpdatedAt,
|
||||
}
|
||||
}
|
||||
|
||||
func ToProjectFlockKandangDetailDTOWithAvailableQty(e entity.ProjectFlockKandang, availableQtyMap map[uint]float64, productWarehouses []entity.ProductWarehouse) ProjectFlockKandangDetailDTO {
|
||||
return ToProjectFlockKandangDetailDTOWithAvailableQtyAndFlock(e, availableQtyMap, productWarehouses, nil)
|
||||
}
|
||||
|
||||
func ToProjectFlockKandangDetailDTOWithAvailableQtyAndFlock(e entity.ProjectFlockKandang, availableQtyMap map[uint]float64, productWarehouses []entity.ProductWarehouse, flock *flockDTO.FlockBaseDTO) 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: toKandangRelation(e.Kandang),
|
||||
CreatedAt: e.CreatedAt,
|
||||
CreatedUser: toCreatedUserDTO(e.ProjectFlock),
|
||||
Approval: toApprovalDTO(e),
|
||||
}
|
||||
|
||||
return ProjectFlockKandangDetailDTO{
|
||||
@@ -127,30 +112,16 @@ func ToProjectFlockKandangDetailDTOWithAvailableQtyAndFlock(e entity.ProjectFloc
|
||||
}
|
||||
}
|
||||
|
||||
func toKandangDTO(kandang entity.Kandang) *KandangDTO {
|
||||
func toKandangRelation(kandang entity.Kandang) *kandangDTO.KandangRelationDTO {
|
||||
if kandang.Id == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &KandangDTO{
|
||||
Id: kandang.Id,
|
||||
Name: kandang.Name,
|
||||
Status: kandang.Status,
|
||||
}
|
||||
mapped := kandangDTO.ToKandangRelationDTO(kandang)
|
||||
return &mapped
|
||||
}
|
||||
|
||||
func toFlockDTO(flock *entity.Flock) *flockDTO.FlockBaseDTO {
|
||||
if flock == nil || flock.Id == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return &flockDTO.FlockBaseDTO{
|
||||
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
|
||||
@@ -159,23 +130,19 @@ func toApprovalDTO(e entity.ProjectFlockKandang) *approvalDTO.ApprovalBaseDTO {
|
||||
}
|
||||
|
||||
func ToProjectFlockKandangListDTO(e entity.ProjectFlockKandang) ProjectFlockKandangListDTO {
|
||||
return ToProjectFlockKandangListDTOWithFlock(e, nil)
|
||||
}
|
||||
|
||||
func ToProjectFlockKandangListDTOWithFlock(e entity.ProjectFlockKandang, flock *flockDTO.FlockBaseDTO) ProjectFlockKandangListDTO {
|
||||
var projectFlockSummary *projectFlockDTO.ProjectFlockListDTO
|
||||
if e.ProjectFlock.Id != 0 {
|
||||
mapped := projectFlockDTO.ToProjectFlockListDTOWithFlock(e.ProjectFlock, flock)
|
||||
mapped := projectFlockDTO.ToProjectFlockListDTO(e.ProjectFlock)
|
||||
projectFlockSummary = &mapped
|
||||
}
|
||||
|
||||
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: toKandangRelation(e.Kandang),
|
||||
CreatedAt: e.CreatedAt,
|
||||
CreatedUser: toCreatedUserDTO(e.ProjectFlock),
|
||||
Approval: toApprovalDTO(e),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -187,12 +154,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 +167,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
|
||||
}
|
||||
@@ -255,14 +222,23 @@ func ToProductWarehouseDTO(pw *entity.ProductWarehouse) *ProductWarehouseDTO {
|
||||
return nil
|
||||
}
|
||||
|
||||
chickinPwDTO := chickinDTO.ToProductWarehouseDTO(pw)
|
||||
if chickinPwDTO == nil {
|
||||
return nil
|
||||
base := productWarehouseDTO.ToProductWarehouseRelationDTO(*pw)
|
||||
|
||||
var product *productDTO.ProductRelationDTO
|
||||
if pw.Product.Id != 0 {
|
||||
mapped := productDTO.ToProductRelationDTO(pw.Product)
|
||||
product = &mapped
|
||||
}
|
||||
|
||||
var warehouse *warehouseDTO.WarehouseRelationDTO
|
||||
if pw.Warehouse.Id != 0 {
|
||||
mapped := warehouseDTO.ToWarehouseRelationDTO(pw.Warehouse)
|
||||
warehouse = &mapped
|
||||
}
|
||||
|
||||
return &ProductWarehouseDTO{
|
||||
Id: chickinPwDTO.Id,
|
||||
Product: chickinPwDTO.Product,
|
||||
Warehouse: chickinPwDTO.Warehouse,
|
||||
ProductWarehouseRelationDTO: base,
|
||||
Product: product,
|
||||
Warehouse: warehouse,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,6 @@ import (
|
||||
commonRepo "gitlab.com/mbugroup/lti-api.git/internal/common/repository"
|
||||
commonSvc "gitlab.com/mbugroup/lti-api.git/internal/common/service"
|
||||
rProductWarehouse "gitlab.com/mbugroup/lti-api.git/internal/modules/inventory/product-warehouses/repositories"
|
||||
rFlock "gitlab.com/mbugroup/lti-api.git/internal/modules/master/flocks/repositories"
|
||||
rWarehouse "gitlab.com/mbugroup/lti-api.git/internal/modules/master/warehouses/repositories"
|
||||
"gitlab.com/mbugroup/lti-api.git/internal/utils"
|
||||
|
||||
@@ -29,7 +28,6 @@ func (ProjectFlockKandangModule) RegisterRoutes(router fiber.Router, db *gorm.DB
|
||||
userRepo := rUser.NewUserRepository(db)
|
||||
warehouseRepo := rWarehouse.NewWarehouseRepository(db)
|
||||
productWarehouseRepo := rProductWarehouse.NewProductWarehouseRepository(db)
|
||||
flockRepo := rFlock.NewFlockRepository(db)
|
||||
|
||||
approvalRepo := commonRepo.NewApprovalRepository(db)
|
||||
approvalService := commonSvc.NewApprovalService(approvalRepo)
|
||||
@@ -38,7 +36,7 @@ func (ProjectFlockKandangModule) RegisterRoutes(router fiber.Router, db *gorm.DB
|
||||
panic(fmt.Sprintf("failed to register project flock kandang approval workflow: %v", err))
|
||||
}
|
||||
|
||||
projectFlockKandangService := sProjectFlockKandang.NewProjectFlockKandangService(projectFlockKandangRepo, approvalService, warehouseRepo, productWarehouseRepo, projectFlockPopulationRepo, flockRepo, validate)
|
||||
projectFlockKandangService := sProjectFlockKandang.NewProjectFlockKandangService(projectFlockKandangRepo, approvalService, warehouseRepo, productWarehouseRepo, projectFlockPopulationRepo, validate)
|
||||
userService := sUser.NewUserService(userRepo, validate)
|
||||
|
||||
ProjectFlockKandangRoutes(router, userService, projectFlockKandangService)
|
||||
|
||||
+11
-50
@@ -6,12 +6,9 @@ import (
|
||||
commonSvc "gitlab.com/mbugroup/lti-api.git/internal/common/service"
|
||||
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
|
||||
rProductWarehouse "gitlab.com/mbugroup/lti-api.git/internal/modules/inventory/product-warehouses/repositories"
|
||||
flockDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/flocks/dto"
|
||||
flockRepository "gitlab.com/mbugroup/lti-api.git/internal/modules/master/flocks/repositories"
|
||||
rWarehouse "gitlab.com/mbugroup/lti-api.git/internal/modules/master/warehouses/repositories"
|
||||
validation "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project-flock-kandangs/validations"
|
||||
repository "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/repositories"
|
||||
pfutils "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/utils"
|
||||
"gitlab.com/mbugroup/lti-api.git/internal/utils"
|
||||
|
||||
"github.com/go-playground/validator/v10"
|
||||
@@ -21,8 +18,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, error)
|
||||
GetOne(ctx *fiber.Ctx, id uint) (*entity.ProjectFlockKandang, map[uint]float64, []entity.ProductWarehouse, error)
|
||||
}
|
||||
|
||||
// Note: map[uint]float64 adalah mapping dari ProductWarehouse ID ke calculated available quantity
|
||||
@@ -35,10 +32,9 @@ type projectFlockKandangService struct {
|
||||
WarehouseRepo rWarehouse.WarehouseRepository
|
||||
ProductWarehouseRepo rProductWarehouse.ProductWarehouseRepository
|
||||
PopulationRepo repository.ProjectFlockPopulationRepository
|
||||
FlockRepo flockRepository.FlockRepository
|
||||
}
|
||||
|
||||
func NewProjectFlockKandangService(repo repository.ProjectFlockKandangRepository, approvalSvc commonSvc.ApprovalService, warehouseRepo rWarehouse.WarehouseRepository, productWarehouseRepo rProductWarehouse.ProductWarehouseRepository, populationRepo repository.ProjectFlockPopulationRepository, flockRepo flockRepository.FlockRepository, validate *validator.Validate) ProjectFlockKandangService {
|
||||
func NewProjectFlockKandangService(repo repository.ProjectFlockKandangRepository, approvalSvc commonSvc.ApprovalService, warehouseRepo rWarehouse.WarehouseRepository, productWarehouseRepo rProductWarehouse.ProductWarehouseRepository, populationRepo repository.ProjectFlockPopulationRepository, validate *validator.Validate) ProjectFlockKandangService {
|
||||
return &projectFlockKandangService{
|
||||
Log: utils.Log,
|
||||
Validate: validate,
|
||||
@@ -47,13 +43,12 @@ func NewProjectFlockKandangService(repo repository.ProjectFlockKandangRepository
|
||||
WarehouseRepo: warehouseRepo,
|
||||
ProductWarehouseRepo: productWarehouseRepo,
|
||||
PopulationRepo: populationRepo,
|
||||
FlockRepo: flockRepo,
|
||||
}
|
||||
}
|
||||
|
||||
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, error) {
|
||||
if err := s.Validate.Struct(params); err != nil {
|
||||
return nil, 0, nil, err
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
offset := (params.Page - 1) * params.Limit
|
||||
@@ -62,7 +57,7 @@ func (s projectFlockKandangService) GetAll(c *fiber.Ctx, params *validation.Quer
|
||||
|
||||
if err != nil {
|
||||
s.Log.Errorf("Failed to get projectFlockKandangs: %+v", err)
|
||||
return nil, 0, nil, err
|
||||
return nil, 0, err
|
||||
}
|
||||
|
||||
if s.ApprovalSvc != nil {
|
||||
@@ -85,35 +80,16 @@ func (s projectFlockKandangService) GetAll(c *fiber.Ctx, params *validation.Quer
|
||||
}
|
||||
}
|
||||
|
||||
flockMap := make(map[uint]*flockDTO.FlockBaseDTO)
|
||||
for i := range projectFlockKandangs {
|
||||
if projectFlockKandangs[i].ProjectFlock.Id != 0 {
|
||||
baseName := pfutils.DeriveBaseName(projectFlockKandangs[i].ProjectFlock.FlockName)
|
||||
if baseName != "" {
|
||||
flock, err := s.FlockRepo.GetByName(c.Context(), baseName)
|
||||
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
s.Log.Warnf("Failed to fetch flock %q: %+v", baseName, err)
|
||||
} else if flock != nil {
|
||||
|
||||
flockMap[projectFlockKandangs[i].ProjectFlock.Id] = &flockDTO.FlockBaseDTO{
|
||||
Id: flock.Id,
|
||||
Name: flock.Name,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return projectFlockKandangs, total, flockMap, nil
|
||||
return projectFlockKandangs, total, 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, 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")
|
||||
return nil, nil, nil, fiber.NewError(fiber.StatusNotFound, "ProjectFlockKandang not found")
|
||||
}
|
||||
if err != nil {
|
||||
return nil, nil, nil, nil, err
|
||||
return nil, nil, nil, err
|
||||
}
|
||||
|
||||
if len(projectFlockKandang.Chickins) > 0 && s.ApprovalSvc != nil {
|
||||
@@ -147,23 +123,8 @@ func (s projectFlockKandangService) GetOne(c *fiber.Ctx, id uint) (*entity.Proje
|
||||
productWarehouses = []entity.ProductWarehouse{}
|
||||
}
|
||||
}
|
||||
var flockResult *flockDTO.FlockBaseDTO
|
||||
if projectFlockKandang.ProjectFlock.Id != 0 {
|
||||
baseName := pfutils.DeriveBaseName(projectFlockKandang.ProjectFlock.FlockName)
|
||||
if baseName != "" {
|
||||
flock, err := s.FlockRepo.GetByName(c.Context(), baseName)
|
||||
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{
|
||||
Id: flock.Id,
|
||||
Name: flock.Name,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return projectFlockKandang, availableQtyMap, productWarehouses, flockResult, nil
|
||||
return projectFlockKandang, availableQtyMap, productWarehouses, nil
|
||||
}
|
||||
|
||||
func (s projectFlockKandangService) getAvailableQuantities(c *fiber.Ctx, projectFlockKandang *entity.ProjectFlockKandang) (map[uint]float64, error) {
|
||||
|
||||
@@ -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,18 +84,20 @@ 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
|
||||
}
|
||||
|
||||
data := make([]dto.ProjectFlockListDTO, 0)
|
||||
for _, projectFlock := range result {
|
||||
var flock *flockDTO.FlockBaseDTO
|
||||
if flockMap != nil {
|
||||
flock = flockMap[projectFlock.Id]
|
||||
var periodMap map[uint]int
|
||||
if len(result) > 0 {
|
||||
ids := make([]uint, len(result))
|
||||
for i, item := range result {
|
||||
ids[i] = item.Id
|
||||
}
|
||||
if periods, err := u.ProjectflockService.GetProjectPeriods(c, ids); err == nil {
|
||||
periodMap = periods
|
||||
}
|
||||
data = append(data, dto.ToProjectFlockListDTO(projectFlock, flock))
|
||||
}
|
||||
|
||||
return c.Status(fiber.StatusOK).
|
||||
@@ -110,7 +111,7 @@ func (u *ProjectflockController) GetAll(c *fiber.Ctx) error {
|
||||
TotalPages: int64(math.Ceil(float64(totalResults) / float64(query.Limit))),
|
||||
TotalResults: totalResults,
|
||||
},
|
||||
Data: data,
|
||||
Data: dto.ToProjectFlockListDTOsWithPeriods(result, periodMap),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -122,17 +123,24 @@ 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
|
||||
}
|
||||
|
||||
var period int
|
||||
if periods, err := u.ProjectflockService.GetProjectPeriods(c, []uint{uint(id)}); err == nil {
|
||||
if p, ok := periods[uint(id)]; ok {
|
||||
period = p
|
||||
}
|
||||
}
|
||||
|
||||
return c.Status(fiber.StatusOK).
|
||||
JSON(response.Success{
|
||||
Code: fiber.StatusOK,
|
||||
Status: "success",
|
||||
Message: "Get projectflock successfully",
|
||||
Data: dto.ToProjectFlockListDTO(*result, flock),
|
||||
Data: dto.ToProjectFlockListDTOWithPeriod(*result, period),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -153,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),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -180,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),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -219,11 +227,29 @@ func (u *ProjectflockController) Approval(c *fiber.Ctx) error {
|
||||
data interface{}
|
||||
message = "Submit projectflock approval successfully"
|
||||
)
|
||||
|
||||
var periodMap map[uint]int
|
||||
if len(results) > 0 {
|
||||
ids := make([]uint, len(results))
|
||||
for i, item := range results {
|
||||
ids[i] = item.Id
|
||||
}
|
||||
if periods, err := u.ProjectflockService.GetProjectPeriods(c, ids); err == nil {
|
||||
periodMap = periods
|
||||
}
|
||||
}
|
||||
|
||||
if len(results) == 1 {
|
||||
data = dto.ToProjectFlockListDTO(results[0], nil)
|
||||
period := 0
|
||||
if periodMap != nil {
|
||||
if p, ok := periodMap[results[0].Id]; ok {
|
||||
period = p
|
||||
}
|
||||
}
|
||||
data = dto.ToProjectFlockListDTOWithPeriod(results[0], period)
|
||||
} else {
|
||||
message = "Submit projectflock approvals successfully"
|
||||
data = dto.ToProjectFlockListDTOs(results)
|
||||
data = dto.ToProjectFlockListDTOsWithPeriods(results, periodMap)
|
||||
}
|
||||
|
||||
return c.Status(fiber.StatusOK).
|
||||
@@ -236,25 +262,32 @@ func (u *ProjectflockController) Approval(c *fiber.Ctx) error {
|
||||
}
|
||||
|
||||
func (u *ProjectflockController) GetFlockPeriodSummary(c *fiber.Ctx) error {
|
||||
param := c.Params("project_flock_kandang_id")
|
||||
param := c.Params("location_id")
|
||||
|
||||
id, err := strconv.Atoi(param)
|
||||
if err != nil {
|
||||
return fiber.NewError(fiber.StatusBadRequest, "Invalid project_flock_kandang_id")
|
||||
return fiber.NewError(fiber.StatusBadRequest, "Invalid location_id")
|
||||
}
|
||||
|
||||
summary, err := u.ProjectflockService.GetFlockPeriodSummary(c, uint(id))
|
||||
summaries, err := u.ProjectflockService.GetFlockPeriodSummary(c, uint(id))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
responseBody := dto.ToFlockPeriodSummaryDTO(summary.Flock, summary.NextPeriod)
|
||||
responseBody := make([]dto.KandangPeriodSummaryDTO, 0, len(summaries))
|
||||
for _, item := range summaries {
|
||||
responseBody = append(responseBody, dto.KandangPeriodSummaryDTO{
|
||||
Id: item.Id,
|
||||
Name: item.Name,
|
||||
Period: item.Period,
|
||||
})
|
||||
}
|
||||
|
||||
return c.Status(fiber.StatusOK).
|
||||
JSON(response.Success{
|
||||
Code: fiber.StatusOK,
|
||||
Status: "success",
|
||||
Message: "Get flock period summary successfully",
|
||||
Message: "Get kandang period summary successfully",
|
||||
Data: responseBody,
|
||||
})
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ import (
|
||||
approvalDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/approvals/dto"
|
||||
areaDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/areas/dto"
|
||||
fcrDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/fcrs/dto"
|
||||
flockDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/flocks/dto"
|
||||
kandangDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/kandangs/dto"
|
||||
locationDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/locations/dto"
|
||||
|
||||
@@ -17,44 +16,45 @@ 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
|
||||
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"`
|
||||
Period int `json:"period"`
|
||||
}
|
||||
|
||||
type ProjectFlockDetailDTO struct {
|
||||
ProjectFlockListDTO
|
||||
}
|
||||
|
||||
type FlockPeriodDTO struct {
|
||||
Flock flockDTO.FlockBaseDTO `json:"flock"`
|
||||
NextPeriod int `json:"next_period"`
|
||||
type KandangPeriodSummaryDTO struct {
|
||||
Id uint `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Period int `json:"period"`
|
||||
}
|
||||
|
||||
func ToProjectFlockListDTO(e entity.ProjectFlock, flock *flockDTO.FlockBaseDTO) ProjectFlockListDTO {
|
||||
var createdUser *userDTO.UserBaseDTO
|
||||
func ToProjectFlockListDTOWithPeriod(e entity.ProjectFlock, period int) ProjectFlockListDTO {
|
||||
var createdUser *userDTO.UserRelationDTO
|
||||
if e.CreatedUser.Id != 0 {
|
||||
mapped := userDTO.ToUserBaseDTO(e.CreatedUser)
|
||||
mapped := userDTO.ToUserRelationDTO(e.CreatedUser)
|
||||
createdUser = &mapped
|
||||
}
|
||||
|
||||
@@ -63,43 +63,43 @@ func ToProjectFlockListDTO(e entity.ProjectFlock, flock *flockDTO.FlockBaseDTO)
|
||||
kandangSummaries = make([]KandangWithProjectFlockIdDTO, len(e.Kandangs))
|
||||
for i, kandang := range e.Kandangs {
|
||||
|
||||
var pfkId uint
|
||||
var (
|
||||
pfkId uint
|
||||
period int
|
||||
)
|
||||
for _, kh := range e.KandangHistory {
|
||||
if kh.KandangId == kandang.Id {
|
||||
pfkId = kh.Id
|
||||
period = kh.Period
|
||||
break
|
||||
}
|
||||
}
|
||||
kandangSummaries[i] = KandangWithProjectFlockIdDTO{
|
||||
KandangBaseDTO: kandangDTO.ToKandangBaseDTO(kandang),
|
||||
KandangRelationDTO: kandangDTO.ToKandangRelationDTO(kandang),
|
||||
ProjectFlockKandangId: pfkId,
|
||||
Period: period,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
latestApproval := defaultProjectFlockLatestApproval(e)
|
||||
if e.LatestApproval != nil {
|
||||
snapshot := approvalDTO.ToApprovalDTO(*e.LatestApproval)
|
||||
@@ -107,57 +107,53 @@ func ToProjectFlockListDTO(e entity.ProjectFlock, flock *flockDTO.FlockBaseDTO)
|
||||
}
|
||||
|
||||
return ProjectFlockListDTO{
|
||||
ProjectFlockBaseDTO: createProjectFlockBaseDTO(e),
|
||||
Flock: flockSummary,
|
||||
Area: areaSummary,
|
||||
Kandangs: kandangSummaries,
|
||||
Category: e.Category,
|
||||
Fcr: fcrSummary,
|
||||
Location: locationSummary,
|
||||
CreatedAt: e.CreatedAt,
|
||||
UpdatedAt: e.UpdatedAt,
|
||||
CreatedUser: createdUser,
|
||||
Approval: latestApproval,
|
||||
ProjectFlockRelationDTO: createProjectFlockRelationDTO(e, period),
|
||||
Area: areaSummary,
|
||||
Kandangs: kandangSummaries,
|
||||
Category: e.Category,
|
||||
Fcr: fcrSummary,
|
||||
Location: locationSummary,
|
||||
CreatedAt: e.CreatedAt,
|
||||
UpdatedAt: e.UpdatedAt,
|
||||
CreatedUser: createdUser,
|
||||
Approval: latestApproval,
|
||||
}
|
||||
}
|
||||
|
||||
func ToProjectFlockListDTOWithFlock(e entity.ProjectFlock, flock *flockDTO.FlockBaseDTO) ProjectFlockListDTO {
|
||||
return ToProjectFlockListDTO(e, flock)
|
||||
}
|
||||
|
||||
func ToProjectFlockListDTOs(items []entity.ProjectFlock) []ProjectFlockListDTO {
|
||||
result := make([]ProjectFlockListDTO, len(items))
|
||||
for i, item := range items {
|
||||
result[i] = ToProjectFlockListDTO(item, nil)
|
||||
result[i] = ToProjectFlockListDTOWithPeriod(item, 0)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func ToProjectFlockListDTOsWithFlocks(items []entity.ProjectFlock, flocks map[uint]*entity.Flock) []ProjectFlockListDTO {
|
||||
func ToProjectFlockListDTO(e entity.ProjectFlock) ProjectFlockListDTO {
|
||||
return ToProjectFlockListDTOWithPeriod(e, 0)
|
||||
}
|
||||
|
||||
func ToProjectFlockListDTOsWithPeriods(items []entity.ProjectFlock, periods map[uint]int) []ProjectFlockListDTO {
|
||||
result := make([]ProjectFlockListDTO, len(items))
|
||||
for i, item := range items {
|
||||
var flock *flockDTO.FlockBaseDTO
|
||||
if flocks != nil {
|
||||
if f := flocks[item.Id]; f != nil {
|
||||
flock = &flockDTO.FlockBaseDTO{
|
||||
Id: f.Id,
|
||||
Name: f.Name,
|
||||
}
|
||||
p := 0
|
||||
if periods != nil {
|
||||
if v, ok := periods[item.Id]; ok {
|
||||
p = v
|
||||
}
|
||||
}
|
||||
result[i] = ToProjectFlockListDTOWithFlock(item, flock)
|
||||
result[i] = ToProjectFlockListDTOWithPeriod(item, p)
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func ToProjectFlockDetailDTO(e entity.ProjectFlock, flock *flockDTO.FlockBaseDTO) ProjectFlockDetailDTO {
|
||||
func ToProjectFlockDetailDTO(e entity.ProjectFlock) ProjectFlockDetailDTO {
|
||||
return ProjectFlockDetailDTO{
|
||||
ProjectFlockListDTO: ToProjectFlockListDTO(e, flock),
|
||||
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 {
|
||||
@@ -170,9 +166,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),
|
||||
}
|
||||
@@ -181,24 +177,10 @@ func defaultProjectFlockLatestApproval(e entity.ProjectFlock) approvalDTO.Approv
|
||||
return result
|
||||
}
|
||||
|
||||
func createProjectFlockBaseDTO(e entity.ProjectFlock) ProjectFlockBaseDTO {
|
||||
return ProjectFlockBaseDTO{
|
||||
func createProjectFlockRelationDTO(e entity.ProjectFlock, period int) ProjectFlockRelationDTO {
|
||||
return ProjectFlockRelationDTO{
|
||||
Id: e.Id,
|
||||
Period: e.Period,
|
||||
Period: period,
|
||||
FlockName: e.FlockName,
|
||||
}
|
||||
}
|
||||
|
||||
func ToFlockSummaryDTO(e entity.Flock) flockDTO.FlockBaseDTO {
|
||||
return flockDTO.FlockBaseDTO{
|
||||
Id: e.Id,
|
||||
Name: e.Name,
|
||||
}
|
||||
}
|
||||
|
||||
func ToFlockPeriodSummaryDTO(flock entity.Flock, next int) FlockPeriodDTO {
|
||||
return FlockPeriodDTO{
|
||||
Flock: ToFlockSummaryDTO(flock),
|
||||
NextPeriod: next,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,43 +4,40 @@ import (
|
||||
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
|
||||
areaDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/areas/dto"
|
||||
fcrDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/fcrs/dto"
|
||||
flockDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/flocks/dto"
|
||||
kandangDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/kandangs/dto"
|
||||
locationDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/locations/dto"
|
||||
pfutils "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/utils"
|
||||
userDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/users/dto"
|
||||
)
|
||||
|
||||
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
|
||||
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,40 +45,36 @@ func ToProjectFlockKandangDTO(e entity.ProjectFlockKandang) ProjectFlockKandangD
|
||||
if e.ProjectFlock.Id != 0 {
|
||||
|
||||
pfLocal := ProjectFlockWithPivotDTO{
|
||||
ProjectFlockBaseDTO: ProjectFlockBaseDTO{
|
||||
ProjectFlockRelationDTO: ProjectFlockRelationDTO{
|
||||
Id: e.ProjectFlock.Id,
|
||||
Period: e.ProjectFlock.Period,
|
||||
Period: e.Period,
|
||||
FlockName: e.ProjectFlock.FlockName,
|
||||
},
|
||||
Category: e.ProjectFlock.Category,
|
||||
}
|
||||
|
||||
if base := pfutils.DeriveBaseName(e.ProjectFlock.FlockName); base != "" {
|
||||
summary := flockDTO.FlockBaseDTO{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,
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
+15
-69
@@ -2,7 +2,6 @@ package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
@@ -10,17 +9,12 @@ import (
|
||||
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
|
||||
validation "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/validations"
|
||||
"gorm.io/gorm"
|
||||
"gorm.io/gorm/clause"
|
||||
)
|
||||
|
||||
const baseNameExpression = "LOWER(TRIM(regexp_replace(flock_name, '\\\\s+\\\\d+(\\\\s+\\\\d+)*$', '', 'g')))"
|
||||
|
||||
type ProjectflockRepository interface {
|
||||
repository.BaseRepository[entity.ProjectFlock]
|
||||
GetAllByBaseName(ctx context.Context, baseName string) ([]entity.ProjectFlock, error)
|
||||
GetActiveByBaseName(ctx context.Context, baseName string) (*entity.ProjectFlock, error)
|
||||
GetMaxPeriodByBaseName(ctx context.Context, baseName string) (int, error)
|
||||
GetNextSequenceForBase(ctx context.Context, baseName string) (int, error)
|
||||
GetAllWithFilters(ctx context.Context, offset, limit int, params *validation.Query) ([]entity.ProjectFlock, int64, error)
|
||||
WithDefaultRelations() func(*gorm.DB) *gorm.DB
|
||||
ExistsByFlockName(ctx context.Context, flockName string, excludeID *uint) (bool, error)
|
||||
@@ -39,65 +33,6 @@ func NewProjectflockRepository(db *gorm.DB) ProjectflockRepository {
|
||||
}
|
||||
}
|
||||
|
||||
func (r *ProjectflockRepositoryImpl) GetAllByBaseName(ctx context.Context, baseName string) ([]entity.ProjectFlock, error) {
|
||||
var records []entity.ProjectFlock
|
||||
if err := r.DB().WithContext(ctx).
|
||||
Unscoped().
|
||||
Where(baseNameExpression+" = LOWER(?)", baseName).
|
||||
Order("period ASC").
|
||||
Find(&records).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return records, nil
|
||||
}
|
||||
|
||||
func (r *ProjectflockRepositoryImpl) GetActiveByBaseName(ctx context.Context, baseName string) (*entity.ProjectFlock, error) {
|
||||
var record entity.ProjectFlock
|
||||
err := r.DB().WithContext(ctx).
|
||||
Where(baseNameExpression+" = LOWER(?)", baseName).
|
||||
Order("period DESC").
|
||||
First(&record).Error
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, err
|
||||
}
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &record, nil
|
||||
}
|
||||
|
||||
func (r *ProjectflockRepositoryImpl) GetMaxPeriodByBaseName(ctx context.Context, baseName string) (int, error) {
|
||||
var max int
|
||||
if err := r.DB().WithContext(ctx).
|
||||
Model(&entity.ProjectFlock{}).
|
||||
Where(baseNameExpression+" = LOWER(?)", baseName).
|
||||
Select("COALESCE(MAX(period), 0)").
|
||||
Scan(&max).Error; err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return max, nil
|
||||
}
|
||||
|
||||
func (r *ProjectflockRepositoryImpl) GetNextSequenceForBase(ctx context.Context, baseName string) (int, error) {
|
||||
var payload struct {
|
||||
Period int
|
||||
}
|
||||
if err := r.DB().WithContext(ctx).
|
||||
Model(&entity.ProjectFlock{}).
|
||||
Where(baseNameExpression+" = LOWER(?)", baseName).
|
||||
Clauses(clause.Locking{Strength: "UPDATE"}).
|
||||
Order("period DESC").
|
||||
Limit(1).
|
||||
Select("period").
|
||||
Scan(&payload).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return 1, nil
|
||||
}
|
||||
return 0, err
|
||||
}
|
||||
return payload.Period + 1, nil
|
||||
}
|
||||
|
||||
func (r *ProjectflockRepositoryImpl) GetAllWithFilters(ctx context.Context, offset, limit int, params *validation.Query) ([]entity.ProjectFlock, int64, error) {
|
||||
return r.GetAll(ctx, offset, limit, func(db *gorm.DB) *gorm.DB {
|
||||
db = r.withDefaultRelations(db)
|
||||
@@ -137,7 +72,13 @@ func (r *ProjectflockRepositoryImpl) applyQueryFilters(db *gorm.DB, params *vali
|
||||
db = db.Where("project_flocks.location_id = ?", params.LocationId)
|
||||
}
|
||||
if params.Period > 0 {
|
||||
db = db.Where("project_flocks.period = ?", params.Period)
|
||||
db = db.Where(`
|
||||
EXISTS (
|
||||
SELECT 1
|
||||
FROM project_flock_kandangs pfk
|
||||
WHERE pfk.project_flock_id = project_flocks.id
|
||||
AND pfk.period = ?
|
||||
)`, params.Period)
|
||||
}
|
||||
if len(params.KandangIds) > 0 {
|
||||
db = db.Where(`
|
||||
@@ -184,10 +125,15 @@ func (r *ProjectflockRepositoryImpl) applySearchFilters(db *gorm.DB, rawSearch s
|
||||
OR LOWER(created_users.email) LIKE ?
|
||||
OR LOWER(project_flocks.flock_name) LIKE ?
|
||||
OR LOWER(TRIM(regexp_replace(project_flocks.flock_name, '\\s+\\d+(\\s+\\d+)*$', '', 'g'))) LIKE ?
|
||||
OR LOWER(CAST(project_flocks.period AS TEXT)) LIKE ?
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM project_flock_kandangs
|
||||
WHERE project_flock_kandangs.project_flock_id = project_flocks.id
|
||||
AND LOWER(CAST(project_flock_kandangs.period AS TEXT)) LIKE ?
|
||||
)
|
||||
OR EXISTS (
|
||||
SELECT 1 FROM kandangs
|
||||
WHERE kandangs.project_flock_id = project_flocks.id
|
||||
JOIN project_flock_kandangs pfk ON pfk.kandang_id = kandangs.id
|
||||
WHERE pfk.project_flock_id = project_flocks.id
|
||||
AND LOWER(kandangs.name) LIKE ?
|
||||
)
|
||||
`,
|
||||
@@ -241,7 +187,7 @@ func (r *ProjectflockRepositoryImpl) buildOrderExpressions(sortBy, sortOrder str
|
||||
}
|
||||
case "period":
|
||||
return []string{
|
||||
fmt.Sprintf("project_flocks.period %s", direction),
|
||||
fmt.Sprintf("(SELECT COALESCE(MAX(period), 0) FROM project_flock_kandangs pfk WHERE pfk.project_flock_id = project_flocks.id) %s", direction),
|
||||
fmt.Sprintf("project_flocks.id %s", direction),
|
||||
}
|
||||
default:
|
||||
|
||||
+28
-1
@@ -22,6 +22,7 @@ type ProjectFlockKandangRepository interface {
|
||||
HasKandangsLinkedToOtherProject(ctx context.Context, kandangIDs []uint, exceptProjectID *uint) (bool, error)
|
||||
FindKandangsWithRecordings(ctx context.Context, projectFlockID uint, kandangIDs []uint) ([]entity.Kandang, error)
|
||||
MaxPeriodByBaseName(ctx context.Context, baseName string) (int, error)
|
||||
ProjectPeriodsByProjectIDs(ctx context.Context, projectIDs []uint) (map[uint]int, error)
|
||||
WithTx(tx *gorm.DB) ProjectFlockKandangRepository
|
||||
IdExists(ctx context.Context, id uint) (bool, error)
|
||||
DB() *gorm.DB
|
||||
@@ -304,7 +305,33 @@ func (r *projectFlockKandangRepositoryImpl) MaxPeriodByBaseName(ctx context.Cont
|
||||
Table("project_flock_kandangs pfk").
|
||||
Joins("JOIN project_flocks pf ON pf.id = pfk.project_flock_id").
|
||||
Where(flockBaseNameExpression+" = LOWER(?)", baseName).
|
||||
Select("COALESCE(MAX(pf.period), 0)").
|
||||
Select("COALESCE(MAX(pfk.period), 0)").
|
||||
Scan(&max).Error
|
||||
return max, err
|
||||
}
|
||||
|
||||
func (r *projectFlockKandangRepositoryImpl) ProjectPeriodsByProjectIDs(ctx context.Context, projectIDs []uint) (map[uint]int, error) {
|
||||
result := make(map[uint]int)
|
||||
if len(projectIDs) == 0 {
|
||||
return result, nil
|
||||
}
|
||||
|
||||
type row struct {
|
||||
ProjectFlockID uint
|
||||
Period int
|
||||
}
|
||||
var rows []row
|
||||
if err := r.db.WithContext(ctx).
|
||||
Table("project_flock_kandangs").
|
||||
Where("project_flock_id IN ?", projectIDs).
|
||||
Select("project_flock_id, COALESCE(MAX(period), 0) AS period").
|
||||
Group("project_flock_id").
|
||||
Scan(&rows).Error; err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, item := range rows {
|
||||
result[item.ProjectFlockID] = item.Period
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package project_flocks
|
||||
|
||||
import (
|
||||
// m "gitlab.com/mbugroup/lti-api.git/internal/middleware"
|
||||
controller "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/controllers"
|
||||
projectflock "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/services"
|
||||
user "gitlab.com/mbugroup/lti-api.git/internal/modules/users/services"
|
||||
@@ -12,12 +13,6 @@ func ProjectflockRoutes(v1 fiber.Router, u user.UserService, s projectflock.Proj
|
||||
ctrl := controller.NewProjectflockController(s)
|
||||
|
||||
route := v1.Group("/project-flocks")
|
||||
|
||||
// route.Get("/", m.Auth(u), ctrl.GetAll)
|
||||
// route.Post("/", m.Auth(u), ctrl.CreateOne)
|
||||
// route.Get("/:id", m.Auth(u), ctrl.GetOne)
|
||||
// route.Patch("/:id", m.Auth(u), ctrl.UpdateOne)
|
||||
// route.Delete("/:id", m.Auth(u), ctrl.DeleteOne)
|
||||
// route.Use(m.Auth(u))
|
||||
|
||||
route.Get("/", ctrl.GetAll)
|
||||
@@ -28,6 +23,6 @@ func ProjectflockRoutes(v1 fiber.Router, u user.UserService, s projectflock.Proj
|
||||
route.Get("/kandangs/:project_flock_kandang_id/periods", ctrl.GetFlockPeriodSummary)
|
||||
route.Get("/kandangs/lookup", ctrl.LookupProjectFlockKandang)
|
||||
route.Post("/approvals", ctrl.Approval)
|
||||
route.Get("/kandangs/:project_flock_kandang_id/periods", ctrl.GetFlockPeriodSummary)
|
||||
route.Get("/kandangs/:location_id/periods", ctrl.GetFlockPeriodSummary)
|
||||
|
||||
}
|
||||
|
||||
@@ -10,6 +10,8 @@ import (
|
||||
commonRepo "gitlab.com/mbugroup/lti-api.git/internal/common/repository"
|
||||
commonSvc "gitlab.com/mbugroup/lti-api.git/internal/common/service"
|
||||
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
|
||||
|
||||
// authmiddleware "gitlab.com/mbugroup/lti-api.git/internal/middleware"
|
||||
productWarehouseRepository "gitlab.com/mbugroup/lti-api.git/internal/modules/inventory/product-warehouses/repositories"
|
||||
flockDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/flocks/dto"
|
||||
flockRepository "gitlab.com/mbugroup/lti-api.git/internal/modules/master/flocks/repositories"
|
||||
@@ -28,14 +30,15 @@ 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)
|
||||
DeleteOne(ctx *fiber.Ctx, id uint) error
|
||||
GetProjectFlockKandangByProjectAndKandang(ctx *fiber.Ctx, projectFlockID uint, kandangID uint) (*entity.ProjectFlockKandang, float64, error)
|
||||
GetFlockPeriodSummary(ctx *fiber.Ctx, flockID uint) (*FlockPeriodSummary, error)
|
||||
GetFlockPeriodSummary(ctx *fiber.Ctx, locationID uint) ([]KandangPeriodSummary, error)
|
||||
GetProjectPeriods(ctx *fiber.Ctx, projectIDs []uint) (map[uint]int, error)
|
||||
Approval(ctx *fiber.Ctx, req *validation.Approve) ([]entity.ProjectFlock, error)
|
||||
}
|
||||
|
||||
@@ -52,9 +55,10 @@ type projectflockService struct {
|
||||
approvalWorkflow approvalutils.ApprovalWorkflowKey
|
||||
}
|
||||
|
||||
type FlockPeriodSummary struct {
|
||||
Flock entity.Flock
|
||||
NextPeriod int
|
||||
type KandangPeriodSummary struct {
|
||||
Id uint
|
||||
Name string
|
||||
Period int
|
||||
}
|
||||
|
||||
func NewProjectflockService(
|
||||
@@ -93,7 +97,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
|
||||
}
|
||||
@@ -121,7 +125,7 @@ func (s projectflockService) GetAll(c *fiber.Ctx, params *validation.Query) ([]e
|
||||
}
|
||||
|
||||
latestMap, err := s.ApprovalSvc.LatestByTargets(c.Context(), s.approvalWorkflow, ids, func(db *gorm.DB) *gorm.DB {
|
||||
return db.Preload("ActionUser")
|
||||
return s.withRelations(db)
|
||||
})
|
||||
if err != nil {
|
||||
s.Log.Warnf("Unable to load latest approvals for projectflocks: %+v", err)
|
||||
@@ -134,7 +138,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)
|
||||
@@ -143,7 +147,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,
|
||||
}
|
||||
@@ -167,7 +171,7 @@ func (s projectflockService) getOneEntityOnly(c *fiber.Ctx, id uint) (*entity.Pr
|
||||
|
||||
if s.ApprovalSvc != nil {
|
||||
approvals, err := s.ApprovalSvc.ListByTarget(c.Context(), s.approvalWorkflow, id, func(db *gorm.DB) *gorm.DB {
|
||||
return db.Preload("ActionUser")
|
||||
return s.withRelations(db)
|
||||
})
|
||||
if err != nil {
|
||||
s.Log.Warnf("Unable to load approvals for projectflock %d: %+v", id, err)
|
||||
@@ -184,7 +188,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")
|
||||
@@ -196,7 +200,7 @@ func (s projectflockService) GetOne(c *fiber.Ctx, id uint) (*entity.ProjectFlock
|
||||
|
||||
if s.ApprovalSvc != nil {
|
||||
approvals, err := s.ApprovalSvc.ListByTarget(c.Context(), s.approvalWorkflow, id, func(db *gorm.DB) *gorm.DB {
|
||||
return db.Preload("ActionUser")
|
||||
return s.withRelations(db)
|
||||
})
|
||||
if err != nil {
|
||||
s.Log.Warnf("Unable to load approvals for projectflock %d: %+v", id, err)
|
||||
@@ -211,7 +215,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 != "" {
|
||||
@@ -219,7 +223,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,
|
||||
}
|
||||
@@ -282,6 +286,11 @@ func (s *projectflockService) CreateOne(c *fiber.Ctx, req *validation.Create) (*
|
||||
if len(kandangs) != len(kandangIDs) {
|
||||
return nil, fiber.NewError(fiber.StatusNotFound, "Some kandangs not found")
|
||||
}
|
||||
for _, kandang := range kandangs {
|
||||
if kandang.LocationId != req.LocationId {
|
||||
return nil, fiber.NewError(fiber.StatusBadRequest, fmt.Sprintf("Kandang %d tidak berada pada lokasi yang sama dengan project flock", kandang.Id))
|
||||
}
|
||||
}
|
||||
// larang kalau ada yg sudah terikat ke project lain
|
||||
if linked, err := s.pivotRepo().HasKandangsLinkedToOtherProject(c.Context(), kandangIDs, nil); err != nil {
|
||||
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to validate kandangs linkage")
|
||||
@@ -300,22 +309,24 @@ func (s *projectflockService) CreateOne(c *fiber.Ctx, req *validation.Create) (*
|
||||
err = s.Repository.DB().WithContext(c.Context()).Transaction(func(dbTransaction *gorm.DB) error {
|
||||
projectRepo := repository.NewProjectflockRepository(dbTransaction)
|
||||
|
||||
nextSeq, err := projectRepo.GetNextSequenceForBase(c.Context(), canonicalBase)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
generatedName, seq, err := s.generateSequentialFlockName(c.Context(), projectRepo, canonicalBase, nextSeq, nil)
|
||||
// Generate unique flock name (sequential per base name, starting from 1)
|
||||
generatedName, _, err := s.generateSequentialFlockName(c.Context(), projectRepo, canonicalBase, 1, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
createBody.FlockName = generatedName
|
||||
createBody.Period = seq
|
||||
|
||||
if err := projectRepo.CreateOne(c.Context(), createBody, nil); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := s.attachKandangs(c.Context(), dbTransaction, createBody.Id, kandangIDs); err != nil {
|
||||
// Compute period based on location history (max period in that location + 1),
|
||||
// and store it on project_flock_kandangs only.
|
||||
nextPeriod, err := s.nextLocationPeriod(c.Context(), dbTransaction, req.LocationId)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := s.attachKandangs(c.Context(), dbTransaction, createBody.Id, kandangIDs, nextPeriod); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -451,6 +462,15 @@ func (s projectflockService) UpdateOne(c *fiber.Ctx, req *validation.Update, id
|
||||
if len(kandangs) != len(newKandangIDs) {
|
||||
return nil, fiber.NewError(fiber.StatusNotFound, "Some kandangs not found")
|
||||
}
|
||||
targetLocationID := existing.LocationId
|
||||
if req.LocationId != nil && *req.LocationId > 0 {
|
||||
targetLocationID = *req.LocationId
|
||||
}
|
||||
for _, kandang := range kandangs {
|
||||
if kandang.LocationId != targetLocationID {
|
||||
return nil, fiber.NewError(fiber.StatusBadRequest, fmt.Sprintf("Kandang %d tidak berada pada lokasi yang sama dengan project flock", kandang.Id))
|
||||
}
|
||||
}
|
||||
if linked, err := s.pivotRepo().HasKandangsLinkedToOtherProject(c.Context(), newKandangIDs, &id); err != nil {
|
||||
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to validate kandangs linkage")
|
||||
} else if linked {
|
||||
@@ -476,18 +496,11 @@ func (s projectflockService) UpdateOne(c *fiber.Ctx, req *validation.Update, id
|
||||
}
|
||||
|
||||
if needFlockNameRegenerate {
|
||||
nextSeq, err := projectRepo.GetNextSequenceForBase(c.Context(), baseForGeneration)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
newName, seq, err := s.generateSequentialFlockName(c.Context(), projectRepo, baseForGeneration, nextSeq, &id)
|
||||
newName, _, err := s.generateSequentialFlockName(c.Context(), projectRepo, baseForGeneration, 1, &id)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
updateBody["flock_name"] = newName
|
||||
if seq != existing.Period {
|
||||
updateBody["period"] = seq
|
||||
}
|
||||
}
|
||||
|
||||
if len(updateBody) > 0 {
|
||||
@@ -531,7 +544,19 @@ func (s projectflockService) UpdateOne(c *fiber.Ctx, req *validation.Update, id
|
||||
}
|
||||
|
||||
if len(toAttach) > 0 {
|
||||
if err := s.attachKandangs(c.Context(), dbTransaction, id, toAttach); err != nil {
|
||||
var currentPeriod int
|
||||
if err := dbTransaction.WithContext(c.Context()).
|
||||
Table("project_flock_kandangs").
|
||||
Where("project_flock_id = ?", id).
|
||||
Select("COALESCE(MAX(period), 0)").
|
||||
Scan(¤tPeriod).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
if currentPeriod <= 0 {
|
||||
currentPeriod = 1
|
||||
}
|
||||
|
||||
if err := s.attachKandangs(c.Context(), dbTransaction, id, toAttach, currentPeriod); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
@@ -807,57 +832,90 @@ func (s projectflockService) GetAvailableDocQuantity(ctx *fiber.Ctx, kandangID u
|
||||
return total, nil
|
||||
}
|
||||
|
||||
func (s projectflockService) GetFlockPeriodSummary(c *fiber.Ctx, projectFlockKandangID uint) (*FlockPeriodSummary, error) {
|
||||
if projectFlockKandangID == 0 {
|
||||
return nil, fiber.NewError(fiber.StatusBadRequest, "project_flock_kandang_id is required")
|
||||
// nextLocationPeriod computes the next period number for a given location
|
||||
// based on the maximum period that has ever been used by any kandang in that location.
|
||||
func (s projectflockService) nextLocationPeriod(ctx context.Context, tx *gorm.DB, locationID uint) (int, error) {
|
||||
if locationID == 0 {
|
||||
return 0, fiber.NewError(fiber.StatusBadRequest, "location_id is required to compute period")
|
||||
}
|
||||
|
||||
pivot, err := s.pivotRepo().GetByID(c.Context(), projectFlockKandangID)
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
return nil, fiber.NewError(fiber.StatusNotFound, "Project flock kandang not found")
|
||||
db := s.Repository.DB()
|
||||
if tx != nil {
|
||||
db = tx
|
||||
}
|
||||
|
||||
var maxPeriod int
|
||||
if err := db.WithContext(ctx).
|
||||
Table("project_flock_kandangs pfk").
|
||||
Joins("JOIN kandangs k ON k.id = pfk.kandang_id").
|
||||
Where("k.location_id = ?", locationID).
|
||||
Select("COALESCE(MAX(pfk.period), 0)").
|
||||
Scan(&maxPeriod).Error; err != nil {
|
||||
s.Log.Errorf("Failed to compute max period for location %d: %+v", locationID, err)
|
||||
return 0, fiber.NewError(fiber.StatusInternalServerError, "Failed to compute period for location")
|
||||
}
|
||||
|
||||
return maxPeriod + 1, nil
|
||||
}
|
||||
|
||||
func (s projectflockService) GetProjectPeriods(c *fiber.Ctx, projectIDs []uint) (map[uint]int, error) {
|
||||
if len(projectIDs) == 0 {
|
||||
return map[uint]int{}, nil
|
||||
}
|
||||
return s.pivotRepo().ProjectPeriodsByProjectIDs(c.Context(), projectIDs)
|
||||
}
|
||||
|
||||
func (s projectflockService) GetFlockPeriodSummary(c *fiber.Ctx, locationID uint) ([]KandangPeriodSummary, error) {
|
||||
if locationID == 0 {
|
||||
return nil, fiber.NewError(fiber.StatusBadRequest, "location_id is required")
|
||||
}
|
||||
|
||||
exists, err := s.Repository.LocationExists(c.Context(), locationID)
|
||||
if err != nil {
|
||||
s.Log.Errorf("Failed to fetch project_flock_kandang %d: %+v", projectFlockKandangID, err)
|
||||
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch project flock kandang")
|
||||
s.Log.Errorf("Failed to validate location %d: %+v", locationID, err)
|
||||
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to validate location")
|
||||
}
|
||||
if !exists {
|
||||
return nil, fiber.NewError(fiber.StatusNotFound, "Location not found")
|
||||
}
|
||||
|
||||
var baseName string
|
||||
var referenceFlock *entity.Flock
|
||||
if pivot.ProjectFlock.Id != 0 {
|
||||
baseName = pfutils.DeriveBaseName(pivot.ProjectFlock.FlockName)
|
||||
type kandangPeriodRow struct {
|
||||
Id uint
|
||||
Name string
|
||||
LatestPeriod int
|
||||
}
|
||||
|
||||
if strings.TrimSpace(baseName) != "" {
|
||||
referenceFlock, err = s.FlockRepo.GetByName(c.Context(), baseName)
|
||||
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
s.Log.Errorf("Failed to fetch flock %q: %+v", baseName, err)
|
||||
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch flock")
|
||||
}
|
||||
var rows []kandangPeriodRow
|
||||
|
||||
db := s.Repository.DB().WithContext(c.Context())
|
||||
if err := db.
|
||||
Table("kandangs AS k").
|
||||
Select("k.id, k.name, COALESCE(MAX(pfk.period), 0) AS latest_period").
|
||||
Joins("LEFT JOIN project_flock_kandangs AS pfk ON pfk.kandang_id = k.id").
|
||||
Where("k.location_id = ?", locationID).
|
||||
Where("k.deleted_at IS NULL").
|
||||
Group("k.id, k.name").
|
||||
Order("k.id ASC").
|
||||
Scan(&rows).Error; err != nil {
|
||||
s.Log.Errorf("Failed to fetch kandang period summary for location %d: %+v", locationID, err)
|
||||
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch kandang period summary")
|
||||
}
|
||||
|
||||
if referenceFlock == nil {
|
||||
referenceFlock = &entity.Flock{Name: pivot.ProjectFlock.FlockName}
|
||||
}
|
||||
|
||||
maxPeriod := pivot.ProjectFlock.Period
|
||||
if strings.TrimSpace(baseName) != "" {
|
||||
if headerMax, err := s.Repository.GetMaxPeriodByBaseName(c.Context(), baseName); err != nil {
|
||||
s.Log.Warnf("Unable to compute header period for base %q: %+v", baseName, err)
|
||||
} else if headerMax > maxPeriod {
|
||||
maxPeriod = headerMax
|
||||
summaries := make([]KandangPeriodSummary, 0, len(rows))
|
||||
for _, row := range rows {
|
||||
nextPeriod := 0
|
||||
if row.LatestPeriod > 0 {
|
||||
nextPeriod = row.LatestPeriod + 1
|
||||
}
|
||||
|
||||
if pivotMax, err := s.pivotRepo().MaxPeriodByBaseName(c.Context(), baseName); err != nil {
|
||||
s.Log.Warnf("Unable to compute pivot period for base %q: %+v", baseName, err)
|
||||
} else if pivotMax > maxPeriod {
|
||||
maxPeriod = pivotMax
|
||||
}
|
||||
summaries = append(summaries, KandangPeriodSummary{
|
||||
Id: row.Id,
|
||||
Name: row.Name,
|
||||
Period: nextPeriod,
|
||||
})
|
||||
}
|
||||
|
||||
return &FlockPeriodSummary{
|
||||
Flock: *referenceFlock,
|
||||
NextPeriod: maxPeriod + 1,
|
||||
}, nil
|
||||
return summaries, nil
|
||||
}
|
||||
|
||||
func uniqueUintSlice(values []uint) []uint {
|
||||
@@ -933,7 +991,7 @@ func (s projectflockService) ensureFlockByName(ctx context.Context, actorID uint
|
||||
return newFlock, nil
|
||||
}
|
||||
|
||||
func (s projectflockService) attachKandangs(ctx context.Context, dbTransaction *gorm.DB, projectFlockID uint, kandangIDs []uint) error {
|
||||
func (s projectflockService) attachKandangs(ctx context.Context, dbTransaction *gorm.DB, projectFlockID uint, kandangIDs []uint, period int) error {
|
||||
if len(kandangIDs) == 0 {
|
||||
return nil
|
||||
}
|
||||
@@ -971,6 +1029,7 @@ func (s projectflockService) attachKandangs(ctx context.Context, dbTransaction *
|
||||
records = append(records, &entity.ProjectFlockKandang{
|
||||
ProjectFlockId: projectFlockID,
|
||||
KandangId: id,
|
||||
Period: period,
|
||||
})
|
||||
}
|
||||
if err := s.pivotRepoWithTx(dbTransaction).CreateMany(ctx, records); err != nil {
|
||||
@@ -1040,10 +1099,11 @@ func (s projectflockService) kandangRepoWithTx(tx *gorm.DB) kandangRepository.Ka
|
||||
return kandangRepository.NewKandangRepository(s.Repository.DB())
|
||||
}
|
||||
|
||||
func actorIDFromContext(c *fiber.Ctx) (uint, error) {
|
||||
func actorIDFromContext(_ *fiber.Ctx) (uint, error) {
|
||||
// user, ok := authmiddleware.AuthenticatedUser(c)
|
||||
// if !ok || user == nil || user.Id == 0 {
|
||||
// return 0, fiber.NewError(fiber.StatusUnauthorized, "Please authenticate")
|
||||
// }
|
||||
// return user.Id, nil
|
||||
return 1, nil
|
||||
}
|
||||
|
||||
@@ -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),
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
commonRepo "gitlab.com/mbugroup/lti-api.git/internal/common/repository"
|
||||
commonSvc "gitlab.com/mbugroup/lti-api.git/internal/common/service"
|
||||
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
|
||||
authmiddleware "gitlab.com/mbugroup/lti-api.git/internal/middleware"
|
||||
rProductWarehouse "gitlab.com/mbugroup/lti-api.git/internal/modules/inventory/product-warehouses/repositories"
|
||||
rProduct "gitlab.com/mbugroup/lti-api.git/internal/modules/master/products/repositories"
|
||||
rSupplier "gitlab.com/mbugroup/lti-api.git/internal/modules/master/suppliers/repositories"
|
||||
@@ -167,6 +168,11 @@ func (s *purchaseService) CreateOne(c *fiber.Ctx, req *validation.CreatePurchase
|
||||
return nil, err
|
||||
}
|
||||
|
||||
user, ok := authmiddleware.AuthenticatedUser(c)
|
||||
if !ok || user == nil || user.Id == 0 {
|
||||
return nil, fiber.NewError(fiber.StatusUnauthorized, "Please authenticate")
|
||||
}
|
||||
|
||||
ctx := c.Context()
|
||||
|
||||
if _, err := s.SupplierRepo.GetByID(ctx, req.SupplierID, nil); err != nil {
|
||||
@@ -257,7 +263,7 @@ func (s *purchaseService) CreateOne(c *fiber.Ctx, req *validation.CreatePurchase
|
||||
DueDate: dueDate,
|
||||
GrandTotal: 0,
|
||||
Notes: req.Notes,
|
||||
CreatedBy: 1, // TODO: replace with authenticated user id once available
|
||||
CreatedBy: uint64(user.Id),
|
||||
}
|
||||
|
||||
items := make([]*entity.PurchaseItem, 0, len(aggregated))
|
||||
|
||||
@@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user