mirror of
https://gitlab.com/mbugroup/lti-api.git
synced 2026-05-24 07:15:43 +00:00
Merge branch 'feat/BE/Sprint-8' into 'development'
[FEAT/BE] Partial Merge #3 See merge request mbugroup/lti-api!116
This commit is contained in:
+7
@@ -0,0 +1,7 @@
|
|||||||
|
DROP INDEX IF EXISTS idx_project_flocks_production_standard_id;
|
||||||
|
|
||||||
|
ALTER TABLE project_flocks
|
||||||
|
DROP CONSTRAINT IF EXISTS fk_project_flocks_production_standard_id;
|
||||||
|
|
||||||
|
ALTER TABLE project_flocks
|
||||||
|
DROP COLUMN IF EXISTS production_standard_id;
|
||||||
+15
@@ -0,0 +1,15 @@
|
|||||||
|
-- Add production_standard_id to project_flocks
|
||||||
|
ALTER TABLE project_flocks
|
||||||
|
ADD COLUMN IF NOT EXISTS production_standard_id BIGINT;
|
||||||
|
|
||||||
|
DO $$
|
||||||
|
BEGIN
|
||||||
|
IF EXISTS (SELECT 1 FROM pg_tables WHERE tablename = 'production_standards') THEN
|
||||||
|
ALTER TABLE project_flocks
|
||||||
|
ADD CONSTRAINT fk_project_flocks_production_standard_id
|
||||||
|
FOREIGN KEY (production_standard_id) REFERENCES production_standards (id) ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||||
|
END IF;
|
||||||
|
END $$;
|
||||||
|
|
||||||
|
CREATE INDEX IF NOT EXISTS idx_project_flocks_production_standard_id
|
||||||
|
ON project_flocks (production_standard_id);
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
-- Remove standard_fcr column from production_standard_details table
|
||||||
|
ALTER TABLE production_standard_details
|
||||||
|
DROP COLUMN IF EXISTS standard_fcr;
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
-- Add standard_fcr column to production_standard_details table
|
||||||
|
ALTER TABLE production_standard_details
|
||||||
|
ADD COLUMN standard_fcr NUMERIC(15, 3);
|
||||||
@@ -891,14 +891,14 @@ func seedProductWarehouse(tx *gorm.DB, createdBy uint) error {
|
|||||||
WarehouseName string
|
WarehouseName string
|
||||||
Quantity float64
|
Quantity float64
|
||||||
}{
|
}{
|
||||||
{ProductName: "DOC Broiler", WarehouseName: "Gudang Priangan", Quantity: 100},
|
{ProductName: "DOC Broiler", WarehouseName: "Gudang Priangan", Quantity: 0},
|
||||||
{ProductName: "281 SPECIAL STARTER", WarehouseName: "Gudang Singaparna", Quantity: 200},
|
{ProductName: "281 SPECIAL STARTER", WarehouseName: "Gudang Singaparna", Quantity: 0},
|
||||||
{ProductName: "281 SPECIAL STARTER", WarehouseName: "Gudang Banten", Quantity: 300},
|
{ProductName: "281 SPECIAL STARTER", WarehouseName: "Gudang Banten", Quantity: 0},
|
||||||
{ProductName: "DOC Broiler", WarehouseName: "Gudang Singaparna 1", Quantity: 5000},
|
{ProductName: "DOC Broiler", WarehouseName: "Gudang Singaparna 1", Quantity: 0},
|
||||||
{ProductName: "Telur Konsumsi Baik", WarehouseName: "Gudang Singaparna 1", Quantity: 600},
|
{ProductName: "Telur Konsumsi Baik", WarehouseName: "Gudang Singaparna 1", Quantity: 0},
|
||||||
{ProductName: "Telur Pecah", WarehouseName: "Gudang Singaparna 1", Quantity: 80},
|
{ProductName: "Telur Pecah", WarehouseName: "Gudang Singaparna 1", Quantity: 0},
|
||||||
{ProductName: "Telur Konsumsi Baik", WarehouseName: "Gudang Cikaum 1", Quantity: 450},
|
{ProductName: "Telur Konsumsi Baik", WarehouseName: "Gudang Cikaum 1", Quantity: 0},
|
||||||
{ProductName: "Telur Pecah", WarehouseName: "Gudang Cikaum 1", Quantity: 60},
|
{ProductName: "Telur Pecah", WarehouseName: "Gudang Cikaum 1", Quantity: 0},
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, seed := range seeds {
|
for _, seed := range seeds {
|
||||||
@@ -962,12 +962,24 @@ func seedTransferStock(tx *gorm.DB) error {
|
|||||||
{
|
{
|
||||||
StockTransferId: transfer.Id,
|
StockTransferId: transfer.Id,
|
||||||
ProductId: 1,
|
ProductId: 1,
|
||||||
Quantity: 10,
|
|
||||||
|
SourceProductWarehouseID: func() *uint64 { id := uint64(1); return &id }(),
|
||||||
|
DestProductWarehouseID: func() *uint64 { id := uint64(2); return &id }(),
|
||||||
|
UsageQty: 10,
|
||||||
|
PendingQty: 0,
|
||||||
|
TotalQty: 10,
|
||||||
|
TotalUsed: 0,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
StockTransferId: transfer.Id,
|
StockTransferId: transfer.Id,
|
||||||
ProductId: 2,
|
ProductId: 2,
|
||||||
Quantity: 5,
|
|
||||||
|
SourceProductWarehouseID: func() *uint64 { id := uint64(1); return &id }(),
|
||||||
|
DestProductWarehouseID: func() *uint64 { id := uint64(2); return &id }(),
|
||||||
|
UsageQty: 5,
|
||||||
|
PendingQty: 0,
|
||||||
|
TotalQty: 5,
|
||||||
|
TotalUsed: 0,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
for i := range details {
|
for i := range details {
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ type ProductionStandardDetail struct {
|
|||||||
TargetHenHouseProduction *float64 `gorm:"type:numeric(15,3)"`
|
TargetHenHouseProduction *float64 `gorm:"type:numeric(15,3)"`
|
||||||
TargetEggWeight *float64 `gorm:"type:numeric(15,3)"`
|
TargetEggWeight *float64 `gorm:"type:numeric(15,3)"`
|
||||||
TargetEggMass *float64 `gorm:"type:numeric(15,3)"`
|
TargetEggMass *float64 `gorm:"type:numeric(15,3)"`
|
||||||
|
StandardFCR *float64 `gorm:"type:numeric(15,3)"`
|
||||||
CreatedAt time.Time `gorm:"type:timestamptz;not null"`
|
CreatedAt time.Time `gorm:"type:timestamptz;not null"`
|
||||||
UpdatedAt time.Time `gorm:"type:timestamptz;not null"`
|
UpdatedAt time.Time `gorm:"type:timestamptz;not null"`
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ type ProjectFlock struct {
|
|||||||
AreaId uint `gorm:"not null"`
|
AreaId uint `gorm:"not null"`
|
||||||
Category string `gorm:"type:varchar(20);not null"`
|
Category string `gorm:"type:varchar(20);not null"`
|
||||||
FcrId uint `gorm:"not null"`
|
FcrId uint `gorm:"not null"`
|
||||||
|
ProductionStandardId uint `gorm:"column:production_standard_id"`
|
||||||
LocationId uint `gorm:"not null"`
|
LocationId uint `gorm:"not null"`
|
||||||
CreatedBy uint `gorm:"not null"`
|
CreatedBy uint `gorm:"not null"`
|
||||||
CreatedAt time.Time `gorm:"autoCreateTime"`
|
CreatedAt time.Time `gorm:"autoCreateTime"`
|
||||||
@@ -20,6 +21,7 @@ type ProjectFlock struct {
|
|||||||
|
|
||||||
Area Area `gorm:"foreignKey:AreaId;references:Id"`
|
Area Area `gorm:"foreignKey:AreaId;references:Id"`
|
||||||
Fcr Fcr `gorm:"foreignKey:FcrId;references:Id"`
|
Fcr Fcr `gorm:"foreignKey:FcrId;references:Id"`
|
||||||
|
ProductionStandard ProductionStandard `gorm:"foreignKey:ProductionStandardId;references:Id"`
|
||||||
Location Location `gorm:"foreignKey:LocationId;references:Id"`
|
Location Location `gorm:"foreignKey:LocationId;references:Id"`
|
||||||
CreatedUser User `gorm:"foreignKey:CreatedBy;references:Id"`
|
CreatedUser User `gorm:"foreignKey:CreatedBy;references:Id"`
|
||||||
Kandangs []Kandang `gorm:"many2many:project_flock_kandangs;joinTableForeignKey:project_flock_id;joinTableReferences:kandang_id" json:"kandangs,omitempty"`
|
Kandangs []Kandang `gorm:"many2many:project_flock_kandangs;joinTableForeignKey:project_flock_id;joinTableReferences:kandang_id" json:"kandangs,omitempty"`
|
||||||
|
|||||||
@@ -104,12 +104,11 @@ func AuthenticatedUser(c *fiber.Ctx) (*entity.User, bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func ActorIDFromContext(c *fiber.Ctx) (uint, error) {
|
func ActorIDFromContext(c *fiber.Ctx) (uint, error) {
|
||||||
// user, ok := AuthenticatedUser(c)
|
user, ok := AuthenticatedUser(c)
|
||||||
// if !ok || user == nil || user.Id == 0 {
|
if !ok || user == nil || user.Id == 0 {
|
||||||
// return 0, fiber.NewError(fiber.StatusUnauthorized, "Please authenticate")
|
return 0, fiber.NewError(fiber.StatusUnauthorized, "Please authenticate")
|
||||||
// }
|
}
|
||||||
// return user.Id, nil
|
return user.Id, nil
|
||||||
return 1, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// AuthDetails returns the full authentication context (token, claims, user).
|
// AuthDetails returns the full authentication context (token, claims, user).
|
||||||
|
|||||||
@@ -162,8 +162,32 @@ const (
|
|||||||
P_WarehousesCreateOne = "lti.master.warehouses.create"
|
P_WarehousesCreateOne = "lti.master.warehouses.create"
|
||||||
P_WarehousesUpdateOne = "lti.master.warehouses.update"
|
P_WarehousesUpdateOne = "lti.master.warehouses.update"
|
||||||
P_WarehousesDeleteOne = "lti.master.warehouses.delete"
|
P_WarehousesDeleteOne = "lti.master.warehouses.delete"
|
||||||
|
|
||||||
|
P_Production_Standart_GetAll = "lti.master.production_standards.list"
|
||||||
|
P_Production_Standart_CreateOne = "lti.master.production_standards.create"
|
||||||
|
P_Production_Standart_GetOne = "lti.master.production_standards.detail"
|
||||||
|
P_Production_Standart_UpdateOne = "lti.master.production_standards.update"
|
||||||
|
P_Production_Standart_DeleteOne = "lti.master.production_standards.delete"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
// finance
|
||||||
|
const (
|
||||||
|
P_Finances_Initial_Balances_CreateOne = "lti.finance.initial_balances.create"
|
||||||
|
P_Finances_Initial_Balances_GetOne = "lti.finance.initial_balances.detail"
|
||||||
|
P_Finances_Initial_Balances_UpdateOne = "lti.finance.initial_balances.update"
|
||||||
|
|
||||||
|
P_Finances_Injections_CreateOne = "lti.finance.injections.create"
|
||||||
|
P_Finances_Injections_GetOne = "lti.finance.injections.detail"
|
||||||
|
P_Finances_Injections_UpdateOne = "lti.finance.injections.update"
|
||||||
|
|
||||||
|
P_Finances_Payments_CreateOne = "lti.finance.payments.create"
|
||||||
|
P_Finances_Payments_UpdateOne = "lti.finance.payments.update"
|
||||||
|
P_Finances_Payments_GetOne = "lti.finance.payments.detail"
|
||||||
|
|
||||||
|
P_Finances_Transaction_GetAll = "lti.finance.transactions.list"
|
||||||
|
P_Finances_Transaction_GetOne = "lti.finance.transactions.detail"
|
||||||
|
P_Finances_Transaction_DeleteOne = "lti.finance.transactions.delete"
|
||||||
|
)
|
||||||
const (
|
const (
|
||||||
P_ChickinsCreateOne = "lti.production.chickins.create"
|
P_ChickinsCreateOne = "lti.production.chickins.create"
|
||||||
P_ChickinsGetOne = "lti.production.chickins.detail"
|
P_ChickinsGetOne = "lti.production.chickins.detail"
|
||||||
|
|||||||
@@ -28,18 +28,19 @@ type ClosingDetailDTO struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ClosingListItemDTO struct {
|
type ClosingListItemDTO struct {
|
||||||
Id uint `json:"id"`
|
Id uint `json:"id"`
|
||||||
LocationID uint `json:"location_id"`
|
ProjectName string `json:"project_name"`
|
||||||
LocationName string `json:"location_name"`
|
LocationID uint `json:"location_id"`
|
||||||
ProjectCategory string `json:"project_category"`
|
LocationName string `json:"location_name"`
|
||||||
Period int `json:"period"`
|
ProjectCategory string `json:"project_category"`
|
||||||
ClosingDate string `json:"closing_date"`
|
Period int `json:"period"`
|
||||||
ShedLabel string `json:"shed_label"`
|
ClosingDate string `json:"closing_date"`
|
||||||
ShedCount int `json:"shed_count"`
|
ShedLabel string `json:"shed_label"`
|
||||||
SalesPaidAmount int64 `json:"sales_paid_amount"`
|
ShedCount int `json:"shed_count"`
|
||||||
SalesRemainingAmount int64 `json:"sales_remaining_amount"`
|
// SalesPaidAmount int64 `json:"sales_paid_amount"`
|
||||||
SalesPaymentStatus string `json:"sales_payment_status"`
|
// SalesRemainingAmount int64 `json:"sales_remaining_amount"`
|
||||||
ProjectStatus string `json:"project_status"`
|
// SalesPaymentStatus string `json:"sales_payment_status"`
|
||||||
|
ProjectStatus string `json:"project_status"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type ClosingSummaryDTO struct {
|
type ClosingSummaryDTO struct {
|
||||||
@@ -133,18 +134,19 @@ func ToClosingListItemDTO(project entity.ProjectFlock, projectStatus string) Clo
|
|||||||
shedCount := len(project.KandangHistory)
|
shedCount := len(project.KandangHistory)
|
||||||
|
|
||||||
return ClosingListItemDTO{
|
return ClosingListItemDTO{
|
||||||
Id: project.Id,
|
Id: project.Id,
|
||||||
LocationID: project.LocationId,
|
ProjectName: project.FlockName,
|
||||||
LocationName: project.Location.Name,
|
LocationID: project.LocationId,
|
||||||
ProjectCategory: project.Category,
|
LocationName: project.Location.Name,
|
||||||
Period: maxPeriod(project.KandangHistory),
|
ProjectCategory: project.Category,
|
||||||
ClosingDate: "17-Nov-2025",
|
Period: maxPeriod(project.KandangHistory),
|
||||||
ShedLabel: fmt.Sprintf("%d Kandang", shedCount),
|
ClosingDate: "17-Nov-2025",
|
||||||
ShedCount: shedCount,
|
ShedLabel: fmt.Sprintf("%d Kandang", shedCount),
|
||||||
SalesPaidAmount: 21993726,
|
ShedCount: shedCount,
|
||||||
SalesRemainingAmount: 11075919,
|
// SalesPaidAmount: 21993726,
|
||||||
SalesPaymentStatus: "Lunas",
|
// SalesRemainingAmount: 11075919,
|
||||||
ProjectStatus: projectStatus,
|
// SalesPaymentStatus: "Lunas",
|
||||||
|
ProjectStatus: projectStatus,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -330,13 +330,33 @@ SELECT
|
|||||||
COALESCE(p.po_number, '') AS reference_number,
|
COALESCE(p.po_number, '') AS reference_number,
|
||||||
'Purchase' AS transaction_type,
|
'Purchase' AS transaction_type,
|
||||||
prod.name AS product_name,
|
prod.name AS product_name,
|
||||||
pc.name AS product_category,
|
|
||||||
COALESCE((
|
COALESCE((
|
||||||
SELECT string_agg(f.name, ' ')
|
SELECT string_agg(
|
||||||
|
f.name,
|
||||||
|
' ' ORDER BY
|
||||||
|
CASE
|
||||||
|
WHEN UPPER(f.name) IN ('DOC', 'PAKAN', 'OVK', 'PULLET') THEN 0
|
||||||
|
ELSE 1
|
||||||
|
END,
|
||||||
|
f.name
|
||||||
|
)
|
||||||
|
FROM flags f
|
||||||
|
WHERE f.flagable_type = 'products' AND f.flagable_id = prod.id
|
||||||
|
), '') AS product_category,
|
||||||
|
COALESCE((
|
||||||
|
SELECT string_agg(
|
||||||
|
f.name,
|
||||||
|
' ' ORDER BY
|
||||||
|
CASE
|
||||||
|
WHEN UPPER(f.name) IN ('DOC', 'PAKAN', 'OVK', 'PULLET') THEN 0
|
||||||
|
ELSE 1
|
||||||
|
END,
|
||||||
|
f.name
|
||||||
|
)
|
||||||
FROM flags f
|
FROM flags f
|
||||||
WHERE f.flagable_type = 'products' AND f.flagable_id = prod.id
|
WHERE f.flagable_type = 'products' AND f.flagable_id = prod.id
|
||||||
), '') AS product_sub_category,
|
), '') AS product_sub_category,
|
||||||
'External Supplier' AS source_warehouse,
|
'-' AS source_warehouse,
|
||||||
w.name AS destination_warehouse,
|
w.name AS destination_warehouse,
|
||||||
'' AS destination,
|
'' AS destination,
|
||||||
pi.total_qty AS quantity,
|
pi.total_qty AS quantity,
|
||||||
@@ -345,7 +365,6 @@ SELECT
|
|||||||
FROM purchase_items pi
|
FROM purchase_items pi
|
||||||
JOIN purchases p ON p.id = pi.purchase_id
|
JOIN purchases p ON p.id = pi.purchase_id
|
||||||
JOIN products prod ON prod.id = pi.product_id
|
JOIN products prod ON prod.id = pi.product_id
|
||||||
JOIN product_categories pc ON pc.id = prod.product_category_id
|
|
||||||
JOIN uoms u ON u.id = prod.uom_id
|
JOIN uoms u ON u.id = prod.uom_id
|
||||||
JOIN warehouses w ON w.id = pi.warehouse_id
|
JOIN warehouses w ON w.id = pi.warehouse_id
|
||||||
WHERE pi.warehouse_id IN ?
|
WHERE pi.warehouse_id IN ?
|
||||||
@@ -359,9 +378,29 @@ SELECT
|
|||||||
st.movement_number AS reference_number,
|
st.movement_number AS reference_number,
|
||||||
'Internal Transfer In' AS transaction_type,
|
'Internal Transfer In' AS transaction_type,
|
||||||
prod.name AS product_name,
|
prod.name AS product_name,
|
||||||
pc.name AS product_category,
|
|
||||||
COALESCE((
|
COALESCE((
|
||||||
SELECT string_agg(f.name, ' ')
|
SELECT string_agg(
|
||||||
|
f.name,
|
||||||
|
' ' ORDER BY
|
||||||
|
CASE
|
||||||
|
WHEN UPPER(f.name) IN ('DOC', 'PAKAN', 'OVK', 'PULLET') THEN 0
|
||||||
|
ELSE 1
|
||||||
|
END,
|
||||||
|
f.name
|
||||||
|
)
|
||||||
|
FROM flags f
|
||||||
|
WHERE f.flagable_type = 'products' AND f.flagable_id = prod.id
|
||||||
|
), '') AS product_category,
|
||||||
|
COALESCE((
|
||||||
|
SELECT string_agg(
|
||||||
|
f.name,
|
||||||
|
' ' ORDER BY
|
||||||
|
CASE
|
||||||
|
WHEN UPPER(f.name) IN ('DOC', 'PAKAN', 'OVK', 'PULLET') THEN 0
|
||||||
|
ELSE 1
|
||||||
|
END,
|
||||||
|
f.name
|
||||||
|
)
|
||||||
FROM flags f
|
FROM flags f
|
||||||
WHERE f.flagable_type = 'products' AND f.flagable_id = prod.id
|
WHERE f.flagable_type = 'products' AND f.flagable_id = prod.id
|
||||||
), '') AS product_sub_category,
|
), '') AS product_sub_category,
|
||||||
@@ -376,7 +415,6 @@ JOIN stock_transfers st ON st.id = std.stock_transfer_id
|
|||||||
LEFT JOIN warehouses fw ON fw.id = st.from_warehouse_id
|
LEFT JOIN warehouses fw ON fw.id = st.from_warehouse_id
|
||||||
LEFT JOIN warehouses tw ON tw.id = st.to_warehouse_id
|
LEFT JOIN warehouses tw ON tw.id = st.to_warehouse_id
|
||||||
JOIN products prod ON prod.id = std.product_id
|
JOIN products prod ON prod.id = std.product_id
|
||||||
JOIN product_categories pc ON pc.id = prod.product_category_id
|
|
||||||
JOIN uoms u ON u.id = prod.uom_id
|
JOIN uoms u ON u.id = prod.uom_id
|
||||||
WHERE st.to_warehouse_id IN ?
|
WHERE st.to_warehouse_id IN ?
|
||||||
`
|
`
|
||||||
@@ -389,9 +427,29 @@ SELECT
|
|||||||
st.movement_number AS reference_number,
|
st.movement_number AS reference_number,
|
||||||
'Internal Transfer Out' AS transaction_type,
|
'Internal Transfer Out' AS transaction_type,
|
||||||
prod.name AS product_name,
|
prod.name AS product_name,
|
||||||
pc.name AS product_category,
|
|
||||||
COALESCE((
|
COALESCE((
|
||||||
SELECT string_agg(f.name, ' ')
|
SELECT string_agg(
|
||||||
|
f.name,
|
||||||
|
' ' ORDER BY
|
||||||
|
CASE
|
||||||
|
WHEN UPPER(f.name) IN ('DOC', 'PAKAN', 'OVK', 'PULLET') THEN 0
|
||||||
|
ELSE 1
|
||||||
|
END,
|
||||||
|
f.name
|
||||||
|
)
|
||||||
|
FROM flags f
|
||||||
|
WHERE f.flagable_type = 'products' AND f.flagable_id = prod.id
|
||||||
|
), '') AS product_category,
|
||||||
|
COALESCE((
|
||||||
|
SELECT string_agg(
|
||||||
|
f.name,
|
||||||
|
' ' ORDER BY
|
||||||
|
CASE
|
||||||
|
WHEN UPPER(f.name) IN ('DOC', 'PAKAN', 'OVK', 'PULLET') THEN 0
|
||||||
|
ELSE 1
|
||||||
|
END,
|
||||||
|
f.name
|
||||||
|
)
|
||||||
FROM flags f
|
FROM flags f
|
||||||
WHERE f.flagable_type = 'products' AND f.flagable_id = prod.id
|
WHERE f.flagable_type = 'products' AND f.flagable_id = prod.id
|
||||||
), '') AS product_sub_category,
|
), '') AS product_sub_category,
|
||||||
@@ -406,7 +464,6 @@ JOIN stock_transfers st ON st.id = std.stock_transfer_id
|
|||||||
LEFT JOIN warehouses fw ON fw.id = st.from_warehouse_id
|
LEFT JOIN warehouses fw ON fw.id = st.from_warehouse_id
|
||||||
LEFT JOIN warehouses tw ON tw.id = st.to_warehouse_id
|
LEFT JOIN warehouses tw ON tw.id = st.to_warehouse_id
|
||||||
JOIN products prod ON prod.id = std.product_id
|
JOIN products prod ON prod.id = std.product_id
|
||||||
JOIN product_categories pc ON pc.id = prod.product_category_id
|
|
||||||
JOIN uoms u ON u.id = prod.uom_id
|
JOIN uoms u ON u.id = prod.uom_id
|
||||||
WHERE st.from_warehouse_id IN ?
|
WHERE st.from_warehouse_id IN ?
|
||||||
`
|
`
|
||||||
@@ -419,9 +476,29 @@ SELECT
|
|||||||
m.so_number AS reference_number,
|
m.so_number AS reference_number,
|
||||||
'Trading Sales' AS transaction_type,
|
'Trading Sales' AS transaction_type,
|
||||||
prod.name AS product_name,
|
prod.name AS product_name,
|
||||||
pc.name AS product_category,
|
|
||||||
COALESCE((
|
COALESCE((
|
||||||
SELECT string_agg(f.name, ' ')
|
SELECT string_agg(
|
||||||
|
f.name,
|
||||||
|
' ' ORDER BY
|
||||||
|
CASE
|
||||||
|
WHEN UPPER(f.name) IN ('DOC', 'PAKAN', 'OVK', 'PULLET') THEN 0
|
||||||
|
ELSE 1
|
||||||
|
END,
|
||||||
|
f.name
|
||||||
|
)
|
||||||
|
FROM flags f
|
||||||
|
WHERE f.flagable_type = 'products' AND f.flagable_id = prod.id
|
||||||
|
), '') AS product_category,
|
||||||
|
COALESCE((
|
||||||
|
SELECT string_agg(
|
||||||
|
f.name,
|
||||||
|
' ' ORDER BY
|
||||||
|
CASE
|
||||||
|
WHEN UPPER(f.name) IN ('DOC', 'PAKAN', 'OVK', 'PULLET') THEN 0
|
||||||
|
ELSE 1
|
||||||
|
END,
|
||||||
|
f.name
|
||||||
|
)
|
||||||
FROM flags f
|
FROM flags f
|
||||||
WHERE f.flagable_type = 'products' AND f.flagable_id = prod.id
|
WHERE f.flagable_type = 'products' AND f.flagable_id = prod.id
|
||||||
), '') AS product_sub_category,
|
), '') AS product_sub_category,
|
||||||
@@ -435,7 +512,6 @@ FROM marketing_products mp
|
|||||||
JOIN marketings m ON m.id = mp.marketing_id
|
JOIN marketings m ON m.id = mp.marketing_id
|
||||||
JOIN product_warehouses pw ON pw.id = mp.product_warehouse_id
|
JOIN product_warehouses pw ON pw.id = mp.product_warehouse_id
|
||||||
JOIN products prod ON prod.id = pw.product_id
|
JOIN products prod ON prod.id = pw.product_id
|
||||||
JOIN product_categories pc ON pc.id = prod.product_category_id
|
|
||||||
JOIN uoms u ON u.id = prod.uom_id
|
JOIN uoms u ON u.id = prod.uom_id
|
||||||
JOIN warehouses w ON w.id = pw.warehouse_id
|
JOIN warehouses w ON w.id = pw.warehouse_id
|
||||||
WHERE pw.project_flock_kandang_id IN ?
|
WHERE pw.project_flock_kandang_id IN ?
|
||||||
@@ -808,12 +884,12 @@ func (r *ClosingRepositoryImpl) FetchSapronakTransfers(ctx context.Context, kand
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ActualUsageCostRow struct {
|
type ActualUsageCostRow struct {
|
||||||
ProductID uint `gorm:"column:product_id"`
|
ProductID uint `gorm:"column:product_id"`
|
||||||
ProductName string `gorm:"column:product_name"`
|
ProductName string `gorm:"column:product_name"`
|
||||||
FlagName string `gorm:"column:flag_name"`
|
FlagName string `gorm:"column:flag_name"`
|
||||||
TotalQty float64 `gorm:"column:total_qty"`
|
TotalQty float64 `gorm:"column:total_qty"`
|
||||||
TotalPrice float64 `gorm:"column:total_price"`
|
TotalPrice float64 `gorm:"column:total_price"`
|
||||||
AveragePrice float64 `gorm:"column:average_price"`
|
AveragePrice float64 `gorm:"column:average_price"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *ClosingRepositoryImpl) GetActualUsageCostByProjectFlockID(ctx context.Context, projectFlockID uint) ([]ActualUsageCostRow, error) {
|
func (r *ClosingRepositoryImpl) GetActualUsageCostByProjectFlockID(ctx context.Context, projectFlockID uint) ([]ActualUsageCostRow, error) {
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import (
|
|||||||
"math"
|
"math"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
commonSvc "gitlab.com/mbugroup/lti-api.git/internal/common/service"
|
commonSvc "gitlab.com/mbugroup/lti-api.git/internal/common/service"
|
||||||
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
|
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
|
||||||
@@ -332,18 +333,20 @@ func (s closingService) getApprovalStatuses(ctx context.Context, projectFlockID
|
|||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
minStep uint16
|
minStep uint16
|
||||||
statusProject string
|
statusProject string
|
||||||
completed int
|
completed int
|
||||||
|
latestActionAt time.Time
|
||||||
)
|
)
|
||||||
|
|
||||||
for _, rec := range records {
|
for _, rec := range records {
|
||||||
if minStep == 0 || rec.StepNumber < minStep {
|
if minStep == 0 || rec.StepNumber < minStep {
|
||||||
minStep = rec.StepNumber
|
minStep = rec.StepNumber
|
||||||
statusProject = rec.StepName
|
|
||||||
}
|
}
|
||||||
if rec.StepNumber == uint16(utils.ProjectFlockStepAktif) {
|
|
||||||
completed++
|
if latestActionAt.IsZero() || rec.ActionAt.After(latestActionAt) {
|
||||||
|
latestActionAt = rec.ActionAt
|
||||||
|
statusProject = rec.StepName
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package initials
|
package initials
|
||||||
|
|
||||||
import (
|
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/finance/initials/controllers"
|
controller "gitlab.com/mbugroup/lti-api.git/internal/modules/finance/initials/controllers"
|
||||||
initial "gitlab.com/mbugroup/lti-api.git/internal/modules/finance/initials/services"
|
initial "gitlab.com/mbugroup/lti-api.git/internal/modules/finance/initials/services"
|
||||||
user "gitlab.com/mbugroup/lti-api.git/internal/modules/users/services"
|
user "gitlab.com/mbugroup/lti-api.git/internal/modules/users/services"
|
||||||
@@ -13,9 +13,9 @@ func InitialRoutes(v1 fiber.Router, u user.UserService, s initial.InitialService
|
|||||||
ctrl := controller.NewInitialController(s)
|
ctrl := controller.NewInitialController(s)
|
||||||
|
|
||||||
route := v1.Group("/initial-balances")
|
route := v1.Group("/initial-balances")
|
||||||
// route.Use(m.Auth(u))
|
route.Use(m.Auth(u))
|
||||||
|
|
||||||
route.Post("/", ctrl.CreateOne)
|
route.Post("/",m.RequirePermissions(m.P_Finances_Initial_Balances_CreateOne), ctrl.CreateOne)
|
||||||
route.Get("/:id", ctrl.GetOne)
|
route.Get("/:id",m.RequirePermissions(m.P_Finances_Initial_Balances_GetOne), ctrl.GetOne)
|
||||||
route.Patch("/:id", ctrl.UpdateOne)
|
route.Patch("/:id",m.RequirePermissions(m.P_Finances_Initial_Balances_UpdateOne), ctrl.UpdateOne)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package injections
|
package injections
|
||||||
|
|
||||||
import (
|
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/finance/injections/controllers"
|
controller "gitlab.com/mbugroup/lti-api.git/internal/modules/finance/injections/controllers"
|
||||||
injection "gitlab.com/mbugroup/lti-api.git/internal/modules/finance/injections/services"
|
injection "gitlab.com/mbugroup/lti-api.git/internal/modules/finance/injections/services"
|
||||||
user "gitlab.com/mbugroup/lti-api.git/internal/modules/users/services"
|
user "gitlab.com/mbugroup/lti-api.git/internal/modules/users/services"
|
||||||
@@ -13,9 +13,9 @@ func InjectionRoutes(v1 fiber.Router, u user.UserService, s injection.InjectionS
|
|||||||
ctrl := controller.NewInjectionController(s)
|
ctrl := controller.NewInjectionController(s)
|
||||||
|
|
||||||
route := v1.Group("/injections")
|
route := v1.Group("/injections")
|
||||||
// route.Use(m.Auth(u))
|
route.Use(m.Auth(u))
|
||||||
|
|
||||||
route.Post("/", ctrl.CreateOne)
|
route.Post("/", m.RequirePermissions(m.P_Finances_Injections_CreateOne), ctrl.CreateOne)
|
||||||
route.Get("/:id", ctrl.GetOne)
|
route.Get("/:id", m.RequirePermissions(m.P_Finances_Injections_GetOne), ctrl.GetOne)
|
||||||
route.Patch("/:id", ctrl.UpdateOne)
|
route.Patch("/:id", m.RequirePermissions(m.P_Finances_Injections_UpdateOne), ctrl.UpdateOne)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package payments
|
package payments
|
||||||
|
|
||||||
import (
|
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/finance/payments/controllers"
|
controller "gitlab.com/mbugroup/lti-api.git/internal/modules/finance/payments/controllers"
|
||||||
payment "gitlab.com/mbugroup/lti-api.git/internal/modules/finance/payments/services"
|
payment "gitlab.com/mbugroup/lti-api.git/internal/modules/finance/payments/services"
|
||||||
user "gitlab.com/mbugroup/lti-api.git/internal/modules/users/services"
|
user "gitlab.com/mbugroup/lti-api.git/internal/modules/users/services"
|
||||||
@@ -13,9 +13,9 @@ func PaymentRoutes(v1 fiber.Router, u user.UserService, s payment.PaymentService
|
|||||||
ctrl := controller.NewPaymentController(s)
|
ctrl := controller.NewPaymentController(s)
|
||||||
|
|
||||||
route := v1.Group("/payments")
|
route := v1.Group("/payments")
|
||||||
// route.Use(m.Auth(u))
|
route.Use(m.Auth(u))
|
||||||
|
|
||||||
route.Post("/", ctrl.CreateOne)
|
route.Post("/",m.RequirePermissions(m.P_Finances_Payments_CreateOne), ctrl.CreateOne)
|
||||||
route.Get("/:id", ctrl.GetOne)
|
route.Get("/:id",m.RequirePermissions(m.P_Finances_Payments_GetOne), ctrl.GetOne)
|
||||||
route.Patch("/:id", ctrl.UpdateOne)
|
route.Patch("/:id",m.RequirePermissions(m.P_Finances_Payments_UpdateOne), ctrl.UpdateOne)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
package transactions
|
package transactions
|
||||||
|
|
||||||
import (
|
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/finance/transactions/controllers"
|
controller "gitlab.com/mbugroup/lti-api.git/internal/modules/finance/transactions/controllers"
|
||||||
transaction "gitlab.com/mbugroup/lti-api.git/internal/modules/finance/transactions/services"
|
transaction "gitlab.com/mbugroup/lti-api.git/internal/modules/finance/transactions/services"
|
||||||
user "gitlab.com/mbugroup/lti-api.git/internal/modules/users/services"
|
user "gitlab.com/mbugroup/lti-api.git/internal/modules/users/services"
|
||||||
@@ -13,9 +13,9 @@ func TransactionRoutes(v1 fiber.Router, u user.UserService, s transaction.Transa
|
|||||||
ctrl := controller.NewTransactionController(s)
|
ctrl := controller.NewTransactionController(s)
|
||||||
|
|
||||||
route := v1.Group("/transactions")
|
route := v1.Group("/transactions")
|
||||||
// route.Use(m.Auth(u))
|
route.Use(m.Auth(u))
|
||||||
|
|
||||||
route.Get("/", ctrl.GetAll)
|
route.Get("/",m.RequirePermissions(m.P_Finances_Transaction_GetAll), ctrl.GetAll)
|
||||||
route.Get("/:id", ctrl.GetOne)
|
route.Get("/:id",m.RequirePermissions(m.P_Finances_Transaction_GetOne), ctrl.GetOne)
|
||||||
route.Delete("/:id", ctrl.DeleteOne)
|
route.Delete("/:id",m.RequirePermissions(m.P_Finances_Transaction_DeleteOne), ctrl.DeleteOne)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -117,39 +117,37 @@ func (s *adjustmentService) Adjustment(c *fiber.Ctx, req *validation.Create) (*e
|
|||||||
|
|
||||||
var createdLogId uint
|
var createdLogId uint
|
||||||
|
|
||||||
isProductWarehouseExist, err := s.ProductWarehouseRepo.ProductWarehouseExistByProductAndWarehouseID(ctx, uint(req.ProductID), uint(req.WarehouseID))
|
var projectFlockKandangID *uint
|
||||||
if err != nil {
|
pfk, err := s.ProjectFlockKandangRepo.GetActiveByKandangID(ctx, uint(req.WarehouseID))
|
||||||
s.Log.Errorf("Failed to check product warehouse existence: %+v", err)
|
if err == nil && pfk != nil {
|
||||||
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to validate product warehouse")
|
idCopy := uint(pfk.Id)
|
||||||
|
projectFlockKandangID = &idCopy
|
||||||
}
|
}
|
||||||
if !isProductWarehouseExist {
|
|
||||||
projectFlockKandangID, err := s.getActiveProjectFlockKandangID(ctx, uint(req.WarehouseID))
|
pw, err := s.ProductWarehouseRepo.FindByProductWarehouseAndPfk(
|
||||||
if err != nil {
|
ctx,
|
||||||
return nil, err
|
uint(req.ProductID),
|
||||||
|
uint(req.WarehouseID),
|
||||||
|
projectFlockKandangID,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
if !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
|
s.Log.Errorf("Failed to find product warehouse: %+v", err)
|
||||||
|
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to get product warehouse")
|
||||||
}
|
}
|
||||||
|
|
||||||
newPW := &entity.ProductWarehouse{
|
newPW := &entity.ProductWarehouse{
|
||||||
ProductId: uint(req.ProductID),
|
ProductId: uint(req.ProductID),
|
||||||
WarehouseId: uint(req.WarehouseID),
|
WarehouseId: uint(req.WarehouseID),
|
||||||
Quantity: 0,
|
Quantity: 0,
|
||||||
ProjectFlockKandangId: &projectFlockKandangID,
|
ProjectFlockKandangId: projectFlockKandangID,
|
||||||
// CreatedBy: 1, // TODO: should Get from auth middleware
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := s.ProductWarehouseRepo.CreateOne(ctx, newPW, nil); err != nil {
|
if err := s.ProductWarehouseRepo.CreateOne(ctx, newPW, nil); err != nil {
|
||||||
s.Log.Errorf("Failed to create product warehouse: %+v", err)
|
s.Log.Errorf("Failed to create product warehouse: %+v", err)
|
||||||
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to create product warehouse")
|
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to create product warehouse")
|
||||||
}
|
}
|
||||||
s.Log.Infof("Product warehouse created: %+v", newPW.Id)
|
pw = newPW
|
||||||
}
|
|
||||||
|
|
||||||
pw, err := s.ProductWarehouseRepo.GetProductWarehouseByProductAndWarehouseID(
|
|
||||||
ctx,
|
|
||||||
uint(req.ProductID),
|
|
||||||
uint(req.WarehouseID),
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
s.Log.Errorf("Failed to get product warehouse for project flock check: %+v", err)
|
|
||||||
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to validate product warehouse")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := common.EnsureProjectFlockNotClosedForProductWarehouses(
|
if err := common.EnsureProjectFlockNotClosedForProductWarehouses(
|
||||||
|
|||||||
+15
@@ -18,6 +18,7 @@ type ProductWarehouseRepository interface {
|
|||||||
ProductWarehouseExistByProductAndWarehouseID(ctx context.Context, productId, warehouseId uint) (bool, error)
|
ProductWarehouseExistByProductAndWarehouseID(ctx context.Context, productId, warehouseId uint) (bool, error)
|
||||||
ExistsByID(ctx context.Context, id uint) (bool, error)
|
ExistsByID(ctx context.Context, id uint) (bool, error)
|
||||||
GetProductWarehouseByProductAndWarehouseID(ctx context.Context, productId, warehouseId uint) (*entity.ProductWarehouse, error)
|
GetProductWarehouseByProductAndWarehouseID(ctx context.Context, productId, warehouseId uint) (*entity.ProductWarehouse, error)
|
||||||
|
FindByProductWarehouseAndPfk(ctx context.Context, productID uint, warehouseID uint, projectFlockKandangID *uint) (*entity.ProductWarehouse, error)
|
||||||
GetByCategoryCodeAndWarehouseID(ctx context.Context, categoryCode string, warehouseId uint) ([]entity.ProductWarehouse, error)
|
GetByCategoryCodeAndWarehouseID(ctx context.Context, categoryCode string, warehouseId uint) ([]entity.ProductWarehouse, error)
|
||||||
GetLatestByCategoryCodeAndWarehouseID(ctx context.Context, categoryCode string, warehouseId uint, db *gorm.DB) (*entity.ProductWarehouse, error)
|
GetLatestByCategoryCodeAndWarehouseID(ctx context.Context, categoryCode string, warehouseId uint, db *gorm.DB) (*entity.ProductWarehouse, error)
|
||||||
GetByFlagAndWarehouseID(ctx context.Context, flagName string, warehouseId uint) ([]entity.ProductWarehouse, error)
|
GetByFlagAndWarehouseID(ctx context.Context, flagName string, warehouseId uint) ([]entity.ProductWarehouse, error)
|
||||||
@@ -107,6 +108,20 @@ func (r *ProductWarehouseRepositoryImpl) GetProductWarehouseByProductAndWarehous
|
|||||||
return &productWarehouse, nil
|
return &productWarehouse, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *ProductWarehouseRepositoryImpl) FindByProductWarehouseAndPfk(ctx context.Context, productID uint, warehouseID uint, projectFlockKandangID *uint) (*entity.ProductWarehouse, error) {
|
||||||
|
var productWarehouse entity.ProductWarehouse
|
||||||
|
|
||||||
|
err := r.DB().WithContext(ctx).
|
||||||
|
Where("product_id = ? AND warehouse_id = ? AND project_flock_kandang_id IS NOT DISTINCT FROM ?", productID, warehouseID, projectFlockKandangID).
|
||||||
|
First(&productWarehouse).Error
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &productWarehouse, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (r *ProductWarehouseRepositoryImpl) GetByCategoryCodeAndWarehouseID(ctx context.Context, categoryCode string, warehouseId uint) ([]entity.ProductWarehouse, error) {
|
func (r *ProductWarehouseRepositoryImpl) GetByCategoryCodeAndWarehouseID(ctx context.Context, categoryCode string, warehouseId uint) ([]entity.ProductWarehouse, error) {
|
||||||
var productWarehouses []entity.ProductWarehouse
|
var productWarehouses []entity.ProductWarehouse
|
||||||
q := r.DB().WithContext(ctx).Model(&entity.ProductWarehouse{}).
|
q := r.DB().WithContext(ctx).Model(&entity.ProductWarehouse{}).
|
||||||
|
|||||||
@@ -106,23 +106,17 @@ func (s transferService) GetAll(c *fiber.Ctx, params *validation.Query) ([]entit
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s transferService) GetOne(c *fiber.Ctx, id uint) (*entity.StockTransfer, error) {
|
func (s transferService) GetOne(c *fiber.Ctx, id uint) (*entity.StockTransfer, error) {
|
||||||
s.Log.Infof("Attempting to get StockTransfer with ID: %d", id)
|
|
||||||
|
|
||||||
transferPtr, err := s.StockTransferRepo.GetByID(c.Context(), id, func(db *gorm.DB) *gorm.DB {
|
transferPtr, err := s.StockTransferRepo.GetByID(c.Context(), id, func(db *gorm.DB) *gorm.DB {
|
||||||
return s.withRelations(db)
|
return s.withRelations(db)
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.Log.Errorf("Error getting StockTransfer ID %d: %+v", id, err)
|
|
||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
return nil, fiber.NewError(fiber.StatusNotFound, "Transfer not found")
|
return nil, fiber.NewError(fiber.StatusNotFound, "Transfer not found")
|
||||||
}
|
}
|
||||||
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to get transfer")
|
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to get transfer")
|
||||||
}
|
}
|
||||||
|
|
||||||
if transferPtr != nil {
|
|
||||||
s.Log.Infof("StockTransfer %d has %d documents", transferPtr.Id, len(transferPtr.Documents))
|
|
||||||
}
|
|
||||||
|
|
||||||
return transferPtr, nil
|
return transferPtr, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -336,7 +330,9 @@ func (s *transferService) CreateOne(c *fiber.Ctx, req *validation.TransferReques
|
|||||||
Files: documentFiles,
|
Files: documentFiles,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fiber.NewError(fiber.StatusInternalServerError, fmt.Sprintf("Failed to upload document for delivery %d", idx+1))
|
s.Log.WithError(err).Errorf("Failed to upload document for delivery %d (delivery_id: %d, filename: %s)",
|
||||||
|
idx+1, deliveries[idx].Id, file.Filename)
|
||||||
|
return fiber.NewError(fiber.StatusInternalServerError, fmt.Sprintf("Failed to upload document for delivery %d: %v", idx+1, err))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -396,7 +392,6 @@ func (s *transferService) CreateOne(c *fiber.Ctx, req *validation.TransferReques
|
|||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.Log.Errorf("Transaction failed in CreateOne: %+v", err)
|
|
||||||
return nil, fiber.NewError(fiber.StatusInternalServerError, fmt.Sprintf("Failed to process transfer transaction: %v", err))
|
return nil, fiber.NewError(fiber.StatusInternalServerError, fmt.Sprintf("Failed to process transfer transaction: %v", err))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -247,11 +247,15 @@ func (s *deliveryOrdersService) CreateOne(c *fiber.Ctx, req *validation.Delivery
|
|||||||
itemDeliveryDate = &parsedDate
|
itemDeliveryDate = &parsedDate
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Hitung total_weight dan total_price otomatis
|
||||||
|
totalWeight := requestedProduct.Qty * requestedProduct.AvgWeight
|
||||||
|
totalPrice := requestedProduct.UnitPrice * requestedProduct.Qty
|
||||||
|
|
||||||
deliveryProduct.ProductWarehouseId = foundMarketingProduct.ProductWarehouseId
|
deliveryProduct.ProductWarehouseId = foundMarketingProduct.ProductWarehouseId
|
||||||
deliveryProduct.UnitPrice = requestedProduct.UnitPrice
|
deliveryProduct.UnitPrice = requestedProduct.UnitPrice
|
||||||
deliveryProduct.AvgWeight = requestedProduct.AvgWeight
|
deliveryProduct.AvgWeight = requestedProduct.AvgWeight
|
||||||
deliveryProduct.TotalWeight = requestedProduct.TotalWeight
|
deliveryProduct.TotalWeight = totalWeight
|
||||||
deliveryProduct.TotalPrice = requestedProduct.TotalPrice
|
deliveryProduct.TotalPrice = totalPrice
|
||||||
deliveryProduct.DeliveryDate = itemDeliveryDate
|
deliveryProduct.DeliveryDate = itemDeliveryDate
|
||||||
deliveryProduct.VehicleNumber = requestedProduct.VehicleNumber
|
deliveryProduct.VehicleNumber = requestedProduct.VehicleNumber
|
||||||
|
|
||||||
@@ -357,11 +361,15 @@ func (s deliveryOrdersService) UpdateOne(c *fiber.Ctx, req *validation.DeliveryO
|
|||||||
|
|
||||||
oldRequestedQty := deliveryProduct.UsageQty + deliveryProduct.PendingQty
|
oldRequestedQty := deliveryProduct.UsageQty + deliveryProduct.PendingQty
|
||||||
|
|
||||||
|
// Hitung total_weight dan total_price otomatis
|
||||||
|
totalWeight := requestedProduct.Qty * requestedProduct.AvgWeight
|
||||||
|
totalPrice := requestedProduct.UnitPrice * requestedProduct.Qty
|
||||||
|
|
||||||
deliveryProduct.ProductWarehouseId = foundMarketingProduct.ProductWarehouseId
|
deliveryProduct.ProductWarehouseId = foundMarketingProduct.ProductWarehouseId
|
||||||
deliveryProduct.UnitPrice = requestedProduct.UnitPrice
|
deliveryProduct.UnitPrice = requestedProduct.UnitPrice
|
||||||
deliveryProduct.AvgWeight = requestedProduct.AvgWeight
|
deliveryProduct.AvgWeight = requestedProduct.AvgWeight
|
||||||
deliveryProduct.TotalWeight = requestedProduct.TotalWeight
|
deliveryProduct.TotalWeight = totalWeight
|
||||||
deliveryProduct.TotalPrice = requestedProduct.TotalPrice
|
deliveryProduct.TotalPrice = totalPrice
|
||||||
deliveryProduct.DeliveryDate = itemDeliveryDate
|
deliveryProduct.DeliveryDate = itemDeliveryDate
|
||||||
deliveryProduct.VehicleNumber = requestedProduct.VehicleNumber
|
deliveryProduct.VehicleNumber = requestedProduct.VehicleNumber
|
||||||
|
|
||||||
|
|||||||
@@ -75,7 +75,6 @@ func (s salesOrdersService) getOne(c *fiber.Ctx, id uint) (*entity.Marketing, er
|
|||||||
return nil, fiber.NewError(fiber.StatusNotFound, "SalesOrders not found")
|
return nil, fiber.NewError(fiber.StatusNotFound, "SalesOrders not found")
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.Log.Errorf("Failed get marketing by id: %+v", err)
|
|
||||||
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch sales order")
|
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to fetch sales order")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -293,13 +292,17 @@ func (s salesOrdersService) UpdateOne(c *fiber.Ctx, req *validation.Update, id u
|
|||||||
for _, rp := range req.MarketingProducts {
|
for _, rp := range req.MarketingProducts {
|
||||||
if old, ok := oldByPW[rp.ProductWarehouseId]; ok {
|
if old, ok := oldByPW[rp.ProductWarehouseId]; ok {
|
||||||
|
|
||||||
|
// Hitung total_weight dan total_price otomatis
|
||||||
|
totalWeight := rp.Qty * rp.AvgWeight
|
||||||
|
totalPrice := rp.UnitPrice * rp.Qty
|
||||||
|
|
||||||
updateBody := map[string]any{
|
updateBody := map[string]any{
|
||||||
"product_warehouse_id": rp.ProductWarehouseId,
|
"product_warehouse_id": rp.ProductWarehouseId,
|
||||||
"qty": rp.Qty,
|
"qty": rp.Qty,
|
||||||
"unit_price": rp.UnitPrice,
|
"unit_price": rp.UnitPrice,
|
||||||
"avg_weight": rp.AvgWeight,
|
"avg_weight": rp.AvgWeight,
|
||||||
"total_weight": rp.TotalWeight,
|
"total_weight": totalWeight,
|
||||||
"total_price": rp.TotalPrice,
|
"total_price": totalPrice,
|
||||||
}
|
}
|
||||||
if err := marketingProductRepoTx.PatchOne(c.Context(), old.Id, updateBody, nil); err != nil {
|
if err := marketingProductRepoTx.PatchOne(c.Context(), old.Id, updateBody, nil); err != nil {
|
||||||
return fiber.NewError(fiber.StatusInternalServerError, "Failed to update marketing product")
|
return fiber.NewError(fiber.StatusInternalServerError, "Failed to update marketing product")
|
||||||
@@ -589,30 +592,34 @@ func (s salesOrdersService) Approval(c *fiber.Ctx, req *validation.Approve) ([]e
|
|||||||
|
|
||||||
func (s *salesOrdersService) createMarketingProductWithDelivery(ctx context.Context, marketingId uint, rp validation.CreateMarketingProduct, marketingProductRepo repository.MarketingProductRepository, invDeliveryRepo repository.MarketingDeliveryProductRepository) error {
|
func (s *salesOrdersService) createMarketingProductWithDelivery(ctx context.Context, marketingId uint, rp validation.CreateMarketingProduct, marketingProductRepo repository.MarketingProductRepository, invDeliveryRepo repository.MarketingDeliveryProductRepository) error {
|
||||||
|
|
||||||
|
// Hitung total_weight dan total_price otomatis
|
||||||
|
totalWeight := rp.Qty * rp.AvgWeight
|
||||||
|
totalPrice := rp.UnitPrice * rp.Qty
|
||||||
|
|
||||||
marketingProduct := &entity.MarketingProduct{
|
marketingProduct := &entity.MarketingProduct{
|
||||||
MarketingId: marketingId,
|
MarketingId: marketingId,
|
||||||
ProductWarehouseId: rp.ProductWarehouseId,
|
ProductWarehouseId: rp.ProductWarehouseId,
|
||||||
Qty: rp.Qty,
|
Qty: rp.Qty,
|
||||||
UnitPrice: rp.UnitPrice,
|
UnitPrice: rp.UnitPrice,
|
||||||
AvgWeight: rp.AvgWeight,
|
AvgWeight: rp.AvgWeight,
|
||||||
TotalWeight: rp.TotalWeight,
|
TotalWeight: totalWeight,
|
||||||
TotalPrice: rp.TotalPrice,
|
TotalPrice: totalPrice,
|
||||||
}
|
}
|
||||||
if err := marketingProductRepo.CreateOne(ctx, marketingProduct, nil); err != nil {
|
if err := marketingProductRepo.CreateOne(ctx, marketingProduct, nil); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
marketingDeliveryProduct := &entity.MarketingDeliveryProduct{
|
marketingDeliveryProduct := &entity.MarketingDeliveryProduct{
|
||||||
MarketingProductId: marketingProduct.Id,
|
MarketingProductId: marketingProduct.Id,
|
||||||
ProductWarehouseId: marketingProduct.ProductWarehouseId,
|
ProductWarehouseId: marketingProduct.ProductWarehouseId,
|
||||||
UnitPrice: 0,
|
UnitPrice: 0,
|
||||||
TotalWeight: 0,
|
TotalWeight: 0,
|
||||||
AvgWeight: 0,
|
AvgWeight: 0,
|
||||||
TotalPrice: 0,
|
TotalPrice: 0,
|
||||||
DeliveryDate: nil,
|
DeliveryDate: nil,
|
||||||
VehicleNumber: rp.VehicleNumber,
|
VehicleNumber: rp.VehicleNumber,
|
||||||
UsageQty: 0,
|
UsageQty: 0,
|
||||||
PendingQty: 0,
|
PendingQty: 0,
|
||||||
}
|
}
|
||||||
if err := invDeliveryRepo.CreateOne(ctx, marketingDeliveryProduct, nil); err != nil {
|
if err := invDeliveryRepo.CreateOne(ctx, marketingDeliveryProduct, nil); err != nil {
|
||||||
return err
|
return err
|
||||||
|
|||||||
@@ -5,8 +5,6 @@ type DeliveryProduct struct {
|
|||||||
Qty float64 `json:"qty" validate:"omitempty,gte=0"`
|
Qty float64 `json:"qty" validate:"omitempty,gte=0"`
|
||||||
UnitPrice float64 `json:"unit_price" validate:"omitempty,gte=0"`
|
UnitPrice float64 `json:"unit_price" validate:"omitempty,gte=0"`
|
||||||
AvgWeight float64 `json:"avg_weight" validate:"omitempty,gte=0"`
|
AvgWeight float64 `json:"avg_weight" validate:"omitempty,gte=0"`
|
||||||
TotalWeight float64 `json:"total_weight" validate:"omitempty,gte=0"`
|
|
||||||
TotalPrice float64 `json:"total_price" validate:"omitempty,gte=0"`
|
|
||||||
DeliveryDate string `json:"delivery_date" validate:"omitempty,datetime=2006-01-02"`
|
DeliveryDate string `json:"delivery_date" validate:"omitempty,datetime=2006-01-02"`
|
||||||
VehicleNumber string `json:"vehicle_number" validate:"omitempty,max=50"`
|
VehicleNumber string `json:"vehicle_number" validate:"omitempty,max=50"`
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,10 +12,8 @@ type CreateMarketingProduct struct {
|
|||||||
VehicleNumber string `json:"vehicle_number" validate:"required,min=1,max=50"`
|
VehicleNumber string `json:"vehicle_number" validate:"required,min=1,max=50"`
|
||||||
ProductWarehouseId uint `json:"product_warehouse_id" validate:"required,gt=0"`
|
ProductWarehouseId uint `json:"product_warehouse_id" validate:"required,gt=0"`
|
||||||
UnitPrice float64 `json:"unit_price" validate:"required,gt=0"`
|
UnitPrice float64 `json:"unit_price" validate:"required,gt=0"`
|
||||||
TotalWeight float64 `json:"total_weight" validate:"required,gt=0"`
|
|
||||||
Qty float64 `json:"qty" validate:"required,gt=0"`
|
Qty float64 `json:"qty" validate:"required,gt=0"`
|
||||||
AvgWeight float64 `json:"avg_weight" validate:"required,gt=0"`
|
AvgWeight float64 `json:"avg_weight" validate:"required,gt=0"`
|
||||||
TotalPrice float64 `json:"total_price" validate:"required,gt=0"`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Update struct {
|
type Update struct {
|
||||||
|
|||||||
+1
-1
@@ -40,7 +40,7 @@ func (u *ProductionStandardController) GetAll(c *fiber.Ctx) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return c.Status(fiber.StatusOK).
|
return c.Status(fiber.StatusOK).
|
||||||
JSON(response.SuccessWithPaginate[dto.ProductionStandardListDTO]{
|
JSON(response.SuccessWithPaginate[dto.ProductionStandardRelationDTO]{
|
||||||
Code: fiber.StatusOK,
|
Code: fiber.StatusOK,
|
||||||
Status: "success",
|
Status: "success",
|
||||||
Message: "Get all productionStandards successfully",
|
Message: "Get all productionStandards successfully",
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import (
|
|||||||
|
|
||||||
// === DTO Structs ===
|
// === DTO Structs ===
|
||||||
|
|
||||||
type ProductionStandardListDTO struct {
|
type ProductionStandardRelationDTO struct {
|
||||||
Id uint `json:"id"`
|
Id uint `json:"id"`
|
||||||
Name string `json:"name"`
|
Name string `json:"name"`
|
||||||
ProjectCategory string `json:"project_category"`
|
ProjectCategory string `json:"project_category"`
|
||||||
@@ -15,7 +15,7 @@ type ProductionStandardListDTO struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type ProductionStandardDetailDTO struct {
|
type ProductionStandardDetailDTO struct {
|
||||||
ProductionStandardListDTO
|
ProductionStandardRelationDTO
|
||||||
Details []WeeklyProductionStandardDTO `json:"details"`
|
Details []WeeklyProductionStandardDTO `json:"details"`
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -33,6 +33,7 @@ type EggProductionStandardDetailDTO struct {
|
|||||||
TargetHenHouseProduction *float64 `json:"target_hen_house_production"`
|
TargetHenHouseProduction *float64 `json:"target_hen_house_production"`
|
||||||
TargetEggWeight *float64 `json:"target_egg_weight"`
|
TargetEggWeight *float64 `json:"target_egg_weight"`
|
||||||
TargetEggMass *float64 `json:"target_egg_mass"`
|
TargetEggMass *float64 `json:"target_egg_mass"`
|
||||||
|
StandardFCR *float64 `json:"standard_fcr"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type WeeklyProductionStandardDTO struct {
|
type WeeklyProductionStandardDTO struct {
|
||||||
@@ -43,14 +44,14 @@ type WeeklyProductionStandardDTO struct {
|
|||||||
|
|
||||||
// === Mapper Functions ===
|
// === Mapper Functions ===
|
||||||
|
|
||||||
func ToProductionStandardListDTO(e entity.ProductionStandard) ProductionStandardListDTO {
|
func ToProductionStandardListDTO(e entity.ProductionStandard) ProductionStandardRelationDTO {
|
||||||
var createdUser *userDTO.UserRelationDTO
|
var createdUser *userDTO.UserRelationDTO
|
||||||
if e.CreatedUser.Id != 0 {
|
if e.CreatedUser.Id != 0 {
|
||||||
mapped := userDTO.ToUserRelationDTO(e.CreatedUser)
|
mapped := userDTO.ToUserRelationDTO(e.CreatedUser)
|
||||||
createdUser = &mapped
|
createdUser = &mapped
|
||||||
}
|
}
|
||||||
|
|
||||||
return ProductionStandardListDTO{
|
return ProductionStandardRelationDTO{
|
||||||
Id: e.Id,
|
Id: e.Id,
|
||||||
Name: e.Name,
|
Name: e.Name,
|
||||||
ProjectCategory: e.ProjectCategory,
|
ProjectCategory: e.ProjectCategory,
|
||||||
@@ -58,8 +59,16 @@ func ToProductionStandardListDTO(e entity.ProductionStandard) ProductionStandard
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func ToProductionStandardListDTOs(e []entity.ProductionStandard) []ProductionStandardListDTO {
|
func ToProductionStandardRelationDTO(e entity.ProductionStandard) ProductionStandardRelationDTO {
|
||||||
result := make([]ProductionStandardListDTO, len(e))
|
return ProductionStandardRelationDTO{
|
||||||
|
Id: e.Id,
|
||||||
|
Name: e.Name,
|
||||||
|
ProjectCategory: e.ProjectCategory,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func ToProductionStandardListDTOs(e []entity.ProductionStandard) []ProductionStandardRelationDTO {
|
||||||
|
result := make([]ProductionStandardRelationDTO, len(e))
|
||||||
for i, r := range e {
|
for i, r := range e {
|
||||||
result[i] = ToProductionStandardListDTO(r)
|
result[i] = ToProductionStandardListDTO(r)
|
||||||
}
|
}
|
||||||
@@ -87,6 +96,7 @@ func ToWeeklyProductionStandardDTOWithDetails(growth entity.StandardGrowthDetail
|
|||||||
TargetHenHouseProduction: detail.TargetHenHouseProduction,
|
TargetHenHouseProduction: detail.TargetHenHouseProduction,
|
||||||
TargetEggWeight: detail.TargetEggWeight,
|
TargetEggWeight: detail.TargetEggWeight,
|
||||||
TargetEggMass: detail.TargetEggMass,
|
TargetEggMass: detail.TargetEggMass,
|
||||||
|
StandardFCR: detail.StandardFCR,
|
||||||
}
|
}
|
||||||
|
|
||||||
return WeeklyProductionStandardDTO{
|
return WeeklyProductionStandardDTO{
|
||||||
@@ -140,6 +150,7 @@ func ToEggProductionStandardDetailDTO(e entity.ProductionStandardDetail) EggProd
|
|||||||
TargetHenHouseProduction: e.TargetHenHouseProduction,
|
TargetHenHouseProduction: e.TargetHenHouseProduction,
|
||||||
TargetEggWeight: e.TargetEggWeight,
|
TargetEggWeight: e.TargetEggWeight,
|
||||||
TargetEggMass: e.TargetEggMass,
|
TargetEggMass: e.TargetEggMass,
|
||||||
|
StandardFCR: e.StandardFCR,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -149,7 +160,7 @@ func ToProductionStandardDetailDTO(
|
|||||||
productionStandardDetails []entity.ProductionStandardDetail,
|
productionStandardDetails []entity.ProductionStandardDetail,
|
||||||
) ProductionStandardDetailDTO {
|
) ProductionStandardDetailDTO {
|
||||||
return ProductionStandardDetailDTO{
|
return ProductionStandardDetailDTO{
|
||||||
ProductionStandardListDTO: ToProductionStandardListDTO(standard),
|
ProductionStandardRelationDTO: ToProductionStandardRelationDTO(standard),
|
||||||
Details: ToWeeklyProductionStandardDTOsWithDetails(growthDetails, productionStandardDetails),
|
Details: ToWeeklyProductionStandardDTOsWithDetails(growthDetails, productionStandardDetails),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,9 +15,9 @@ func ProductionStandardRoutes(v1 fiber.Router, u user.UserService, s productionS
|
|||||||
route := v1.Group("/production-standards")
|
route := v1.Group("/production-standards")
|
||||||
route.Use(m.Auth(u))
|
route.Use(m.Auth(u))
|
||||||
|
|
||||||
route.Get("/", ctrl.GetAll)
|
route.Get("/", m.RequirePermissions(m.P_Production_Standart_GetAll), ctrl.GetAll)
|
||||||
route.Post("/", ctrl.CreateOne)
|
route.Post("/", m.RequirePermissions(m.P_Production_Standart_CreateOne), ctrl.CreateOne)
|
||||||
route.Get("/:id", ctrl.GetOne)
|
route.Get("/:id", m.RequirePermissions(m.P_Production_Standart_GetOne), ctrl.GetOne)
|
||||||
route.Patch("/:id", ctrl.UpdateOne)
|
route.Patch("/:id", m.RequirePermissions(m.P_Production_Standart_UpdateOne), ctrl.UpdateOne)
|
||||||
route.Delete("/:id", ctrl.DeleteOne)
|
route.Delete("/:id", m.RequirePermissions(m.P_Production_Standart_DeleteOne), ctrl.DeleteOne)
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-4
@@ -84,7 +84,6 @@ func (s productionStandardService) GetOne(c *fiber.Ctx, id uint) (*entity.Produc
|
|||||||
return nil, fiber.NewError(fiber.StatusNotFound, "ProductionStandard not found")
|
return nil, fiber.NewError(fiber.StatusNotFound, "ProductionStandard not found")
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.Log.Errorf("Failed get productionStandard by id: %+v", err)
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return productionStandard, nil
|
return productionStandard, nil
|
||||||
@@ -111,6 +110,7 @@ func (s *productionStandardService) CreateOne(c *fiber.Ctx, req *validation.Crea
|
|||||||
var createdStandard *entity.ProductionStandard
|
var createdStandard *entity.ProductionStandard
|
||||||
|
|
||||||
err = s.Repository.DB().WithContext(c.Context()).Transaction(func(tx *gorm.DB) error {
|
err = s.Repository.DB().WithContext(c.Context()).Transaction(func(tx *gorm.DB) error {
|
||||||
|
|
||||||
standardRepoTx := repository.NewProductionStandardRepository(tx)
|
standardRepoTx := repository.NewProductionStandardRepository(tx)
|
||||||
productionStandardDetailRepoTx := repository.NewProductionStandardDetailRepository(tx)
|
productionStandardDetailRepoTx := repository.NewProductionStandardDetailRepository(tx)
|
||||||
standardGrowthDetailRepoTx := repository.NewStandardGrowthDetailRepository(tx)
|
standardGrowthDetailRepoTx := repository.NewStandardGrowthDetailRepository(tx)
|
||||||
@@ -142,6 +142,7 @@ func (s *productionStandardService) CreateOne(c *fiber.Ctx, req *validation.Crea
|
|||||||
TargetHenHouseProduction: detailReq.ProductionStandardDetails.TargetHenHouseProduction,
|
TargetHenHouseProduction: detailReq.ProductionStandardDetails.TargetHenHouseProduction,
|
||||||
TargetEggWeight: detailReq.ProductionStandardDetails.TargetEggWeight,
|
TargetEggWeight: detailReq.ProductionStandardDetails.TargetEggWeight,
|
||||||
TargetEggMass: detailReq.ProductionStandardDetails.TargetEggMass,
|
TargetEggMass: detailReq.ProductionStandardDetails.TargetEggMass,
|
||||||
|
StandardFCR: detailReq.ProductionStandardDetails.StandardFCR,
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := productionStandardDetailRepoTx.CreateOne(c.Context(), productionStandardDetail, nil); err != nil {
|
if err := productionStandardDetailRepoTx.CreateOne(c.Context(), productionStandardDetail, nil); err != nil {
|
||||||
@@ -206,7 +207,6 @@ func (s productionStandardService) UpdateOne(c *fiber.Ctx, req *validation.Updat
|
|||||||
|
|
||||||
nameExists, err := s.Repository.NameExists(c.Context(), *req.Name, &id)
|
nameExists, err := s.Repository.NameExists(c.Context(), *req.Name, &id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.Log.Errorf("Failed to check existing production standard: %+v", err)
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if nameExists {
|
if nameExists {
|
||||||
@@ -255,6 +255,7 @@ func (s productionStandardService) UpdateOne(c *fiber.Ctx, req *validation.Updat
|
|||||||
TargetHenHouseProduction: detailReq.ProductionStandardDetails.TargetHenHouseProduction,
|
TargetHenHouseProduction: detailReq.ProductionStandardDetails.TargetHenHouseProduction,
|
||||||
TargetEggWeight: detailReq.ProductionStandardDetails.TargetEggWeight,
|
TargetEggWeight: detailReq.ProductionStandardDetails.TargetEggWeight,
|
||||||
TargetEggMass: detailReq.ProductionStandardDetails.TargetEggMass,
|
TargetEggMass: detailReq.ProductionStandardDetails.TargetEggMass,
|
||||||
|
StandardFCR: detailReq.ProductionStandardDetails.StandardFCR,
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := productionStandardDetailRepoTx.CreateOne(c.Context(), productionStandardDetail, nil); err != nil {
|
if err := productionStandardDetailRepoTx.CreateOne(c.Context(), productionStandardDetail, nil); err != nil {
|
||||||
@@ -283,7 +284,6 @@ func (s productionStandardService) UpdateOne(c *fiber.Ctx, req *validation.Updat
|
|||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
s.Log.Errorf("Failed to update production standard: %+v", err)
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -295,7 +295,6 @@ func (s productionStandardService) DeleteOne(c *fiber.Ctx, id uint) error {
|
|||||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
return fiber.NewError(fiber.StatusNotFound, "ProductionStandard not found")
|
return fiber.NewError(fiber.StatusNotFound, "ProductionStandard not found")
|
||||||
}
|
}
|
||||||
s.Log.Errorf("Failed to delete productionStandard: %+v", err)
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
+1
@@ -5,6 +5,7 @@ type ProductionStandardDetailItem struct {
|
|||||||
TargetHenHouseProduction *float64 `json:"target_hen_house_production" validate:"omitempty,gte=0"`
|
TargetHenHouseProduction *float64 `json:"target_hen_house_production" validate:"omitempty,gte=0"`
|
||||||
TargetEggWeight *float64 `json:"target_egg_weight" validate:"omitempty,gte=0"`
|
TargetEggWeight *float64 `json:"target_egg_weight" validate:"omitempty,gte=0"`
|
||||||
TargetEggMass *float64 `json:"target_egg_mass" validate:"omitempty,gte=0"`
|
TargetEggMass *float64 `json:"target_egg_mass" validate:"omitempty,gte=0"`
|
||||||
|
StandardFCR *float64 `json:"standard_fcr" validate:"omitempty,gte=0"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type StandardGrowthDetailItem struct {
|
type StandardGrowthDetailItem struct {
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ func (s productService) GetAll(c *fiber.Ctx, params *validation.Query) ([]entity
|
|||||||
|
|
||||||
products, total, err := s.Repository.GetAll(c.Context(), offset, params.Limit, func(db *gorm.DB) *gorm.DB {
|
products, total, err := s.Repository.GetAll(c.Context(), offset, params.Limit, func(db *gorm.DB) *gorm.DB {
|
||||||
db = s.withRelations(db)
|
db = s.withRelations(db)
|
||||||
|
db = db.Where("is_visible = ?", true)
|
||||||
if params.Search != "" {
|
if params.Search != "" {
|
||||||
return db.Where("name LIKE ?", "%"+params.Search+"%")
|
return db.Where("name LIKE ?", "%"+params.Search+"%")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import (
|
|||||||
fcrDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/fcrs/dto"
|
fcrDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/fcrs/dto"
|
||||||
kandangDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/kandangs/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"
|
locationDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/locations/dto"
|
||||||
|
productionStandardDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/production-standards/dto"
|
||||||
productDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/products/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"
|
warehouseDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/warehouses/dto"
|
||||||
chickinDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/production/chickins/dto"
|
chickinDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/production/chickins/dto"
|
||||||
@@ -30,6 +31,7 @@ type ProjectFlockDTO struct {
|
|||||||
Area *areaDTO.AreaRelationDTO `json:"area,omitempty"`
|
Area *areaDTO.AreaRelationDTO `json:"area,omitempty"`
|
||||||
Category string `json:"category"`
|
Category string `json:"category"`
|
||||||
Fcr *fcrDTO.FcrRelationDTO `json:"fcr,omitempty"`
|
Fcr *fcrDTO.FcrRelationDTO `json:"fcr,omitempty"`
|
||||||
|
ProductionStandard *productionStandardDTO.ProductionStandardRelationDTO `json:"production_standard,omitempty"`
|
||||||
Location *locationDTO.LocationRelationDTO `json:"location,omitempty"`
|
Location *locationDTO.LocationRelationDTO `json:"location,omitempty"`
|
||||||
CreatedUser *userDTO.UserRelationDTO `json:"created_user,omitempty"`
|
CreatedUser *userDTO.UserRelationDTO `json:"created_user,omitempty"`
|
||||||
CreatedAt time.Time `json:"created_at"`
|
CreatedAt time.Time `json:"created_at"`
|
||||||
@@ -82,6 +84,7 @@ func toProjectFlockDTO(pf *projectFlockDTO.ProjectFlockListDTO) *ProjectFlockDTO
|
|||||||
Area: pf.Area,
|
Area: pf.Area,
|
||||||
Category: pf.Category,
|
Category: pf.Category,
|
||||||
Fcr: pf.Fcr,
|
Fcr: pf.Fcr,
|
||||||
|
ProductionStandard: pf.ProductionStandard,
|
||||||
Location: pf.Location,
|
Location: pf.Location,
|
||||||
CreatedUser: pf.CreatedUser,
|
CreatedUser: pf.CreatedUser,
|
||||||
CreatedAt: pf.CreatedAt,
|
CreatedAt: pf.CreatedAt,
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import (
|
|||||||
kandangDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/kandangs/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"
|
locationDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/locations/dto"
|
||||||
nonstockDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/nonstocks/dto"
|
nonstockDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/nonstocks/dto"
|
||||||
|
productionStandardDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/production-standards/dto"
|
||||||
|
|
||||||
// pfutils "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/utils"
|
// pfutils "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/utils"
|
||||||
userDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/users/dto"
|
userDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/users/dto"
|
||||||
@@ -28,6 +29,7 @@ type ProjectFlockListDTO struct {
|
|||||||
Area *areaDTO.AreaRelationDTO `json:"area,omitempty"`
|
Area *areaDTO.AreaRelationDTO `json:"area,omitempty"`
|
||||||
Category string `json:"category"`
|
Category string `json:"category"`
|
||||||
Fcr *fcrDTO.FcrRelationDTO `json:"fcr,omitempty"`
|
Fcr *fcrDTO.FcrRelationDTO `json:"fcr,omitempty"`
|
||||||
|
ProductionStandard *productionStandardDTO.ProductionStandardRelationDTO `json:"production_standard,omitempty"`
|
||||||
Location *locationDTO.LocationRelationDTO `json:"location,omitempty"`
|
Location *locationDTO.LocationRelationDTO `json:"location,omitempty"`
|
||||||
Kandangs []KandangWithProjectFlockIdDTO `json:"kandangs,omitempty"`
|
Kandangs []KandangWithProjectFlockIdDTO `json:"kandangs,omitempty"`
|
||||||
ProjectBudgets []ProjectBudgetDTO `json:"project_budgets,omitempty"`
|
ProjectBudgets []ProjectBudgetDTO `json:"project_budgets,omitempty"`
|
||||||
@@ -103,6 +105,12 @@ func ToProjectFlockListDTOWithPeriod(e entity.ProjectFlock, period int) ProjectF
|
|||||||
fcrSummary = &mapped
|
fcrSummary = &mapped
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var productionStandardSummary *productionStandardDTO.ProductionStandardRelationDTO
|
||||||
|
if e.ProductionStandard.Id != 0 {
|
||||||
|
mapped := productionStandardDTO.ToProductionStandardRelationDTO(e.ProductionStandard)
|
||||||
|
productionStandardSummary = &mapped
|
||||||
|
}
|
||||||
|
|
||||||
var locationSummary *locationDTO.LocationRelationDTO
|
var locationSummary *locationDTO.LocationRelationDTO
|
||||||
if e.Location.Id != 0 {
|
if e.Location.Id != 0 {
|
||||||
mapped := locationDTO.ToLocationRelationDTO(e.Location)
|
mapped := locationDTO.ToLocationRelationDTO(e.Location)
|
||||||
@@ -122,6 +130,7 @@ func ToProjectFlockListDTOWithPeriod(e entity.ProjectFlock, period int) ProjectF
|
|||||||
ProjectBudgets: ToProjectBudgetDTOs(e.Budgets),
|
ProjectBudgets: ToProjectBudgetDTOs(e.Budgets),
|
||||||
Category: e.Category,
|
Category: e.Category,
|
||||||
Fcr: fcrSummary,
|
Fcr: fcrSummary,
|
||||||
|
ProductionStandard: productionStandardSummary,
|
||||||
Location: locationSummary,
|
Location: locationSummary,
|
||||||
CreatedAt: e.CreatedAt,
|
CreatedAt: e.CreatedAt,
|
||||||
UpdatedAt: e.UpdatedAt,
|
UpdatedAt: e.UpdatedAt,
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ import (
|
|||||||
fcrDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/fcrs/dto"
|
fcrDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/fcrs/dto"
|
||||||
kandangDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/kandangs/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"
|
locationDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/locations/dto"
|
||||||
|
productionStandardDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/master/production-standards/dto"
|
||||||
userDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/users/dto"
|
userDTO "gitlab.com/mbugroup/lti-api.git/internal/modules/users/dto"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -19,6 +20,7 @@ type ProjectFlockWithPivotDTO struct {
|
|||||||
Area *areaDTO.AreaRelationDTO `json:"area,omitempty"`
|
Area *areaDTO.AreaRelationDTO `json:"area,omitempty"`
|
||||||
Category string `json:"category"`
|
Category string `json:"category"`
|
||||||
Fcr *fcrDTO.FcrRelationDTO `json:"fcr,omitempty"`
|
Fcr *fcrDTO.FcrRelationDTO `json:"fcr,omitempty"`
|
||||||
|
ProductionStandard *productionStandardDTO.ProductionStandardRelationDTO `json:"production_standard,omitempty"`
|
||||||
Location *locationDTO.LocationRelationDTO `json:"location,omitempty"`
|
Location *locationDTO.LocationRelationDTO `json:"location,omitempty"`
|
||||||
Kandangs []KandangWithPivotDTO `json:"kandangs,omitempty"`
|
Kandangs []KandangWithPivotDTO `json:"kandangs,omitempty"`
|
||||||
CreatedUser *userDTO.UserRelationDTO `json:"created_user,omitempty"`
|
CreatedUser *userDTO.UserRelationDTO `json:"created_user,omitempty"`
|
||||||
@@ -61,6 +63,10 @@ func ToProjectFlockKandangDTO(e entity.ProjectFlockKandang) ProjectFlockKandangD
|
|||||||
mapped := fcrDTO.ToFcrRelationDTO(e.ProjectFlock.Fcr)
|
mapped := fcrDTO.ToFcrRelationDTO(e.ProjectFlock.Fcr)
|
||||||
pfLocal.Fcr = &mapped
|
pfLocal.Fcr = &mapped
|
||||||
}
|
}
|
||||||
|
if e.ProjectFlock.ProductionStandard.Id != 0 {
|
||||||
|
mapped := productionStandardDTO.ToProductionStandardRelationDTO(e.ProjectFlock.ProductionStandard)
|
||||||
|
pfLocal.ProductionStandard = &mapped
|
||||||
|
}
|
||||||
if e.ProjectFlock.Location.Id != 0 {
|
if e.ProjectFlock.Location.Id != 0 {
|
||||||
mapped := locationDTO.ToLocationRelationDTO(e.ProjectFlock.Location)
|
mapped := locationDTO.ToLocationRelationDTO(e.ProjectFlock.Location)
|
||||||
pfLocal.Location = &mapped
|
pfLocal.Location = &mapped
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ type ProjectflockRepository interface {
|
|||||||
GetActiveByLocationID(ctx context.Context, locationID uint64) ([]entity.ProjectFlock, error)
|
GetActiveByLocationID(ctx context.Context, locationID uint64) ([]entity.ProjectFlock, error)
|
||||||
AreaExists(ctx context.Context, id uint) (bool, error)
|
AreaExists(ctx context.Context, id uint) (bool, error)
|
||||||
FcrExists(ctx context.Context, id uint) (bool, error)
|
FcrExists(ctx context.Context, id uint) (bool, error)
|
||||||
|
ProductionStandardExists(ctx context.Context, id uint) (bool, error)
|
||||||
LocationExists(ctx context.Context, id uint) (bool, error)
|
LocationExists(ctx context.Context, id uint) (bool, error)
|
||||||
}
|
}
|
||||||
type KandangPeriodRow struct {
|
type KandangPeriodRow struct {
|
||||||
@@ -52,6 +53,7 @@ func (r *ProjectflockRepositoryImpl) WithDefaultRelations() func(*gorm.DB) *gorm
|
|||||||
Preload("CreatedUser").
|
Preload("CreatedUser").
|
||||||
Preload("Area").
|
Preload("Area").
|
||||||
Preload("Fcr").
|
Preload("Fcr").
|
||||||
|
Preload("ProductionStandard").
|
||||||
Preload("Location").
|
Preload("Location").
|
||||||
Preload("Kandangs").
|
Preload("Kandangs").
|
||||||
Preload("KandangHistory").
|
Preload("KandangHistory").
|
||||||
@@ -118,12 +120,14 @@ func (r *ProjectflockRepositoryImpl) applySearchFilters(db *gorm.DB, rawSearch s
|
|||||||
return db.
|
return db.
|
||||||
Joins("LEFT JOIN areas ON areas.id = project_flocks.area_id").
|
Joins("LEFT JOIN areas ON areas.id = project_flocks.area_id").
|
||||||
Joins("LEFT JOIN fcrs ON fcrs.id = project_flocks.fcr_id").
|
Joins("LEFT JOIN fcrs ON fcrs.id = project_flocks.fcr_id").
|
||||||
|
Joins("LEFT JOIN production_standards ON production_standards.id = project_flocks.production_standard_id").
|
||||||
Joins("LEFT JOIN locations ON locations.id = project_flocks.location_id").
|
Joins("LEFT JOIN locations ON locations.id = project_flocks.location_id").
|
||||||
Joins("LEFT JOIN users AS created_users ON created_users.id = project_flocks.created_by").
|
Joins("LEFT JOIN users AS created_users ON created_users.id = project_flocks.created_by").
|
||||||
Where(`
|
Where(`
|
||||||
LOWER(areas.name) LIKE ?
|
LOWER(areas.name) LIKE ?
|
||||||
OR LOWER(project_flocks.category) LIKE ?
|
OR LOWER(project_flocks.category) LIKE ?
|
||||||
OR LOWER(fcrs.name) LIKE ?
|
OR LOWER(fcrs.name) LIKE ?
|
||||||
|
OR LOWER(production_standards.name) LIKE ?
|
||||||
OR LOWER(locations.name) LIKE ?
|
OR LOWER(locations.name) LIKE ?
|
||||||
OR LOWER(locations.address) LIKE ?
|
OR LOWER(locations.address) LIKE ?
|
||||||
OR LOWER(created_users.name) LIKE ?
|
OR LOWER(created_users.name) LIKE ?
|
||||||
@@ -153,6 +157,7 @@ func (r *ProjectflockRepositoryImpl) applySearchFilters(db *gorm.DB, rawSearch s
|
|||||||
likeQuery,
|
likeQuery,
|
||||||
likeQuery,
|
likeQuery,
|
||||||
likeQuery,
|
likeQuery,
|
||||||
|
likeQuery,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,6 +169,10 @@ func (r *ProjectflockRepositoryImpl) FcrExists(ctx context.Context, id uint) (bo
|
|||||||
return repository.Exists[entity.Fcr](ctx, r.DB(), id)
|
return repository.Exists[entity.Fcr](ctx, r.DB(), id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *ProjectflockRepositoryImpl) ProductionStandardExists(ctx context.Context, id uint) (bool, error) {
|
||||||
|
return repository.Exists[entity.ProductionStandard](ctx, r.DB(), id)
|
||||||
|
}
|
||||||
|
|
||||||
func (r *ProjectflockRepositoryImpl) LocationExists(ctx context.Context, id uint) (bool, error) {
|
func (r *ProjectflockRepositoryImpl) LocationExists(ctx context.Context, id uint) (bool, error) {
|
||||||
return repository.Exists[entity.Location](ctx, r.DB(), id)
|
return repository.Exists[entity.Location](ctx, r.DB(), id)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -249,6 +249,7 @@ func (s *projectflockService) CreateOne(c *fiber.Ctx, req *validation.Create) (*
|
|||||||
if err := commonSvc.EnsureRelations(c.Context(),
|
if err := commonSvc.EnsureRelations(c.Context(),
|
||||||
commonSvc.RelationCheck{Name: "Area", ID: &req.AreaId, Exists: s.Repository.AreaExists},
|
commonSvc.RelationCheck{Name: "Area", ID: &req.AreaId, Exists: s.Repository.AreaExists},
|
||||||
commonSvc.RelationCheck{Name: "FCR", ID: &req.FcrId, Exists: s.Repository.FcrExists},
|
commonSvc.RelationCheck{Name: "FCR", ID: &req.FcrId, Exists: s.Repository.FcrExists},
|
||||||
|
commonSvc.RelationCheck{Name: "Production Standard", ID: &req.ProductionStandardId, Exists: s.Repository.ProductionStandardExists},
|
||||||
commonSvc.RelationCheck{Name: "Location", ID: &req.LocationId, Exists: s.Repository.LocationExists},
|
commonSvc.RelationCheck{Name: "Location", ID: &req.LocationId, Exists: s.Repository.LocationExists},
|
||||||
); err != nil {
|
); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@@ -300,6 +301,7 @@ func (s *projectflockService) CreateOne(c *fiber.Ctx, req *validation.Create) (*
|
|||||||
AreaId: req.AreaId,
|
AreaId: req.AreaId,
|
||||||
Category: cat,
|
Category: cat,
|
||||||
FcrId: req.FcrId,
|
FcrId: req.FcrId,
|
||||||
|
ProductionStandardId: req.ProductionStandardId,
|
||||||
LocationId: req.LocationId,
|
LocationId: req.LocationId,
|
||||||
CreatedBy: actorID,
|
CreatedBy: actorID,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
package validation
|
package validation
|
||||||
|
|
||||||
type Create struct {
|
type Create struct {
|
||||||
FlockName string `json:"flock_name" validate:"required_strict"`
|
FlockName string `json:"flock_name" validate:"required_strict"`
|
||||||
AreaId uint `json:"area_id" validate:"required_strict,number,gt=0"`
|
AreaId uint `json:"area_id" validate:"required_strict,number,gt=0"`
|
||||||
Category string `json:"category" validate:"required_strict"`
|
Category string `json:"category" validate:"required_strict"`
|
||||||
FcrId uint `json:"fcr_id" validate:"required_strict,number,gt=0"`
|
FcrId uint `json:"fcr_id" validate:"required_strict,number,gt=0"`
|
||||||
LocationId uint `json:"location_id" validate:"required_strict,number,gt=0"`
|
ProductionStandardId uint `json:"production_standard_id" validate:"required_strict,number,gt=0"`
|
||||||
KandangIds []uint `json:"kandang_ids" validate:"required,min=1,dive,gt=0"`
|
LocationId uint `json:"location_id" validate:"required_strict,number,gt=0"`
|
||||||
ProjectBudgets []ProjectBudget `json:"project_budgets" validate:"required,min=1,dive"`
|
KandangIds []uint `json:"kandang_ids" validate:"required,min=1,dive,gt=0"`
|
||||||
|
ProjectBudgets []ProjectBudget `json:"project_budgets" validate:"required,min=1,dive"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type Query struct {
|
type Query struct {
|
||||||
|
|||||||
Reference in New Issue
Block a user