feat(BE-117): implement CRUD endpoints for project

This commit is contained in:
aguhh18
2025-10-20 11:25:42 +07:00
parent 5c3787886b
commit 7b99b39529
14 changed files with 233 additions and 119 deletions
@@ -1,6 +1,6 @@
CREATE TABLE IF NOT EXISTS project_chickins ( CREATE TABLE IF NOT EXISTS project_chickins (
id BIGSERIAL PRIMARY KEY, id BIGSERIAL PRIMARY KEY,
project_floc_kandang_id BIGINT NOT NULL, project_flock_kandang_id BIGINT NOT NULL,
chick_in_date DATE NOT NULL, chick_in_date DATE NOT NULL,
quantity NUMERIC(15, 3) NOT NULL, quantity NUMERIC(15, 3) NOT NULL,
note TEXT, note TEXT,
@@ -15,8 +15,8 @@ DO $$
BEGIN BEGIN
IF EXISTS (SELECT 1 FROM pg_tables WHERE tablename = 'project_flock_kandangs') THEN IF EXISTS (SELECT 1 FROM pg_tables WHERE tablename = 'project_flock_kandangs') THEN
ALTER TABLE project_chickins ALTER TABLE project_chickins
ADD CONSTRAINT fk_project_floc_kandang_id ADD CONSTRAINT fk_project_flock_kandang_id
FOREIGN KEY (project_floc_kandang_id) FOREIGN KEY (project_flock_kandang_id)
REFERENCES project_flock_kandangs(id) REFERENCES project_flock_kandangs(id)
ON DELETE RESTRICT ON UPDATE CASCADE; ON DELETE RESTRICT ON UPDATE CASCADE;
END IF; END IF;
@@ -31,6 +31,6 @@ BEGIN
END $$; END $$;
-- INDEXES -- INDEXES
CREATE INDEX IF NOT EXISTS idx_project_chickins_project_floc_kandang_id ON project_chickins (project_floc_kandang_id); CREATE INDEX IF NOT EXISTS idx_project_chickins_project_flock_kandang_id ON project_chickins (project_flock_kandang_id);
CREATE INDEX IF NOT EXISTS idx_project_chickins_created_by ON project_chickins (created_by); CREATE INDEX IF NOT EXISTS idx_project_chickins_created_by ON project_chickins (created_by);
@@ -0,0 +1 @@
DROP TABLE IF EXISTS project_flock_populations;
@@ -0,0 +1,36 @@
CREATE TABLE IF NOT EXISTS project_flock_populations (
id BIGSERIAL PRIMARY KEY,
project_flock_kandang_id BIGINT NOT NULL,
initial_quantity NUMERIC(15, 3) NOT NULL,
current_quantity NUMERIC(15, 3) NOT NULL,
reserved_quantity NUMERIC(15, 3),
created_by BIGINT NOT NULL,
created_at TIMESTAMPTZ DEFAULT now(),
updated_at TIMESTAMPTZ DEFAULT now(),
deleted_at TIMESTAMPTZ
);
-- FOREIGN KEYS (dijalankan setelah semua tabel parent ada)
DO $$
BEGIN
IF EXISTS (SELECT 1 FROM pg_tables WHERE tablename = 'project_flock_kandangs') THEN
ALTER TABLE project_flock_populations
ADD CONSTRAINT fk_project_flock_kandang_id
FOREIGN KEY (project_flock_kandang_id)
REFERENCES project_flock_kandangs(id)
ON DELETE RESTRICT ON UPDATE CASCADE;
END IF;
IF EXISTS (SELECT 1 FROM pg_tables WHERE tablename = 'users') THEN
ALTER TABLE project_flock_populations
ADD CONSTRAINT fk_created_by
FOREIGN KEY (created_by)
REFERENCES users(id)
ON DELETE RESTRICT ON UPDATE CASCADE;
END IF;
END $$;
-- INDEXES
CREATE INDEX IF NOT EXISTS idx_project_flock_populations_project_flock_kandang_id ON project_flock_populations (project_flock_kandang_id);
CREATE INDEX IF NOT EXISTS idx_project_flock_populations_created_by ON project_flock_populations (created_by);
+10 -10
View File
@@ -9,16 +9,16 @@ import (
const () const ()
type ProjectChickin struct { type ProjectChickin struct {
Id uint `gorm:"primaryKey"` Id uint `gorm:"primaryKey"`
ProjectFlocKandangId uint `gorm:"not null"` ProjectFlockKandangId uint `gorm:"not null"`
ChickInDate time.Time `gorm:"not null"` ChickInDate time.Time `gorm:"not null"`
Quantity float64 `gorm:"not null"` Quantity float64 `gorm:"not null"`
Note string `gorm:"type:text"` Note string `gorm:"type:text"`
CreatedBy uint `gorm:"not null"` CreatedBy uint `gorm:"not null"`
CreatedAt time.Time `gorm:"autoCreateTime"` CreatedAt time.Time `gorm:"autoCreateTime"`
UpdatedAt time.Time `gorm:"autoUpdateTime"` UpdatedAt time.Time `gorm:"autoUpdateTime"`
DeletedAt gorm.DeletedAt `gorm:"index" json:"-"` DeletedAt gorm.DeletedAt `gorm:"index" json:"-"`
ProjectFlockKandang ProjectFlockKandang `gorm:"foreignKey:ProjectFlocKandangId;references:Id"` ProjectFlockKandang ProjectFlockKandang `gorm:"foreignKey:ProjectFlockKandangId;references:Id"`
CreatedUser User `gorm:"foreignKey:CreatedBy;references:Id"` CreatedUser User `gorm:"foreignKey:CreatedBy;references:Id"`
} }
@@ -0,0 +1,22 @@
package entities
import (
"time"
"gorm.io/gorm"
)
type ProjectFlockPopulation struct {
Id uint `gorm:"primaryKey"`
ProjectFlockKandangId uint `gorm:"not null"`
InitialQuantity float64 `gorm:"type:numeric(15,3);not null"`
CurrentQuantity float64 `gorm:"type:numeric(15,3);not null"`
ReservedQuantity float64 `gorm:"type:numeric(15,3)"`
CreatedBy uint `gorm:"not null"`
CreatedAt time.Time `gorm:"autoCreateTime"`
UpdatedAt time.Time `gorm:"autoUpdateTime"`
DeletedAt gorm.DeletedAt `gorm:"index"`
ProjectFlockKandang *ProjectFlockKandang `gorm:"foreignKey:ProjectFlockKandangId;references:Id"`
CreatedUser *User `gorm:"foreignKey:CreatedBy;references:Id"`
}
@@ -23,6 +23,11 @@ type WarehouseSimpleDTO struct {
Name string `json:"name"` Name string `json:"name"`
} }
type ProductSimpleDTO struct {
Id uint `json:"id"`
Name string `json:"name"`
}
type AreaDTO struct { type AreaDTO struct {
Id uint `json:"id"` Id uint `json:"id"`
Name string `json:"name"` Name string `json:"name"`
@@ -33,6 +38,11 @@ type LocationDTO struct {
Name string `json:"name"` Name string `json:"name"`
} }
type SuplierSimpleDTO struct {
Id uint `json:"id"`
Name string `json:"name"`
}
type WarehouseDetailDTO struct { type WarehouseDetailDTO struct {
Id uint `json:"id"` Id uint `json:"id"`
Name string `json:"name"` Name string `json:"name"`
@@ -57,17 +67,15 @@ type TransferDetailDTO struct {
// Detail produk // Detail produk
type TransferDetailItemDTO struct { type TransferDetailItemDTO struct {
Id uint64 `json:"id"` Id uint64 `json:"id"`
ProductId uint64 `json:"product_id"` Proudct ProductSimpleDTO `json:"product"`
Quantity float64 `json:"quantity"` Quantity float64 `json:"quantity"`
BeforeQuantity float64 `json:"before_quantity"`
AfterQuantity float64 `json:"after_quantity"`
} }
// Delivery ekspedisi // Delivery ekspedisi
type TransferDeliveryDTO struct { type TransferDeliveryDTO struct {
Id uint64 `json:"id"` Id uint64 `json:"id"`
SupplierId uint64 `json:"supplier_id"` Suplier SuplierSimpleDTO `json:"suplier"`
VehiclePlate string `json:"vehicle_plate"` VehiclePlate string `json:"vehicle_plate"`
DriverName string `json:"driver_name"` DriverName string `json:"driver_name"`
DocumentNumber string `json:"document_number"` DocumentNumber string `json:"document_number"`
@@ -146,9 +154,12 @@ func ToTransferListDTO(e entity.StockTransfer) TransferListDTO {
var details []TransferDetailItemDTO var details []TransferDetailItemDTO
for _, d := range e.Details { for _, d := range e.Details {
details = append(details, TransferDetailItemDTO{ details = append(details, TransferDetailItemDTO{
Id: d.Id, Id: d.Id,
ProductId: d.ProductId, Proudct: ProductSimpleDTO{
Quantity: d.Quantity, Id: d.Product.Id,
Name: d.Product.Name,
},
Quantity: d.Quantity,
}) })
} }
// Map deliveries // Map deliveries
@@ -164,8 +175,11 @@ func ToTransferListDTO(e entity.StockTransfer) TransferListDTO {
}) })
} }
deliveries = append(deliveries, TransferDeliveryDTO{ deliveries = append(deliveries, TransferDeliveryDTO{
Id: del.Id, Id: del.Id,
SupplierId: del.SupplierId, Suplier: SuplierSimpleDTO{
Id: del.Supplier.Id,
Name: del.Supplier.Name,
},
VehiclePlate: del.VehiclePlate, VehiclePlate: del.VehiclePlate,
DriverName: del.DriverName, DriverName: del.DriverName,
DocumentNumber: del.DocumentNumber, DocumentNumber: del.DocumentNumber,
@@ -198,17 +212,23 @@ func ToTransferDetailDTO(e entity.StockTransfer) TransferDetailDTO {
var details []TransferDetailItemDTO var details []TransferDetailItemDTO
for _, d := range e.Details { for _, d := range e.Details {
details = append(details, TransferDetailItemDTO{ details = append(details, TransferDetailItemDTO{
Id: d.Id, Id: d.Id,
ProductId: d.ProductId, Proudct: ProductSimpleDTO{
Quantity: d.Quantity, Id: d.Product.Id,
Name: d.Product.Name,
},
Quantity: d.Quantity,
}) })
} }
// Map deliveries // Map deliveries
var deliveries []TransferDeliveryDTO var deliveries []TransferDeliveryDTO
for _, del := range e.Deliveries { for _, del := range e.Deliveries {
deliveries = append(deliveries, TransferDeliveryDTO{ deliveries = append(deliveries, TransferDeliveryDTO{
Id: del.Id, Id: del.Id,
SupplierId: del.SupplierId, Suplier: SuplierSimpleDTO{
Id: del.Supplier.Id,
Name: del.Supplier.Name,
},
VehiclePlate: del.VehiclePlate, VehiclePlate: del.VehiclePlate,
DriverName: del.DriverName, DriverName: del.DriverName,
DocumentNumber: del.DocumentNumber, DocumentNumber: del.DocumentNumber,
@@ -60,7 +60,9 @@ func (s transferService) withRelations(db *gorm.DB) *gorm.DB {
Preload("ToWarehouse.Location"). Preload("ToWarehouse.Location").
Preload("ToWarehouse.Area"). Preload("ToWarehouse.Area").
Preload("Details"). Preload("Details").
Preload("Deliveries.Items") Preload("Details.Product").
Preload("Deliveries.Items").
Preload("Deliveries.Supplier")
} }
func (s transferService) GetAll(c *fiber.Ctx, params *validation.Query) ([]entity.StockTransfer, int64, error) { func (s transferService) GetAll(c *fiber.Ctx, params *validation.Query) ([]entity.StockTransfer, int64, error) {
@@ -24,9 +24,9 @@ func NewChickinController(chickinService service.ChickinService) *ChickinControl
func (u *ChickinController) GetAll(c *fiber.Ctx) error { func (u *ChickinController) GetAll(c *fiber.Ctx) error {
query := &validation.Query{ query := &validation.Query{
Page: c.QueryInt("page", 1), Page: c.QueryInt("page", 1),
Limit: c.QueryInt("limit", 10), Limit: c.QueryInt("limit", 10),
Search: c.Query("search", ""), ProjectFlockKandangId: uint(c.QueryInt("project_flock_kandang_id", 0)),
} }
result, totalResults, err := u.ChickinService.GetAll(c, query) result, totalResults, err := u.ChickinService.GetAll(c, query)
@@ -88,7 +88,7 @@ func (u *ChickinController) CreateOne(c *fiber.Ctx) error {
Code: fiber.StatusCreated, Code: fiber.StatusCreated,
Status: "success", Status: "success",
Message: "Create chickin successfully", Message: "Create chickin successfully",
Data: result, Data: dto.ToChickinListDTO(*result),
}) })
} }
@@ -68,12 +68,12 @@ type ChickinBaseDTO struct {
} }
type ChickinSimpleDTO struct { type ChickinSimpleDTO struct {
Id uint `json:"id"` Id uint `json:"id"`
ProjectFlocKandangId uint `json:"project_floc_kandang_id"` ProjectFlockKandangId uint `json:"project_flock_kandang_id"`
ChickInDate time.Time `json:"chick_in_date"` ChickInDate time.Time `json:"chick_in_date"`
Quantity float64 `json:"quantity"` Quantity float64 `json:"quantity"`
Note string `json:"note"` Note string `json:"note"`
CreatedBy uint `json:"created_by"` CreatedBy uint `json:"created_by"`
} }
type ChickinListDTO struct { type ChickinListDTO struct {
@@ -197,7 +197,7 @@ func ToUserBaseDTO(e entity.User) UserBaseDTO {
func ToChickinBaseDTO(e entity.ProjectChickin) ChickinBaseDTO { func ToChickinBaseDTO(e entity.ProjectChickin) ChickinBaseDTO {
return ChickinBaseDTO{ return ChickinBaseDTO{
Id: e.Id, Id: e.Id,
ProjectFlocKandangId: e.ProjectFlocKandangId, ProjectFlocKandangId: e.ProjectFlockKandangId,
ChickInDate: e.ChickInDate, ChickInDate: e.ChickInDate,
Quantity: e.Quantity, Quantity: e.Quantity,
Note: e.Note, Note: e.Note,
@@ -206,12 +206,12 @@ func ToChickinBaseDTO(e entity.ProjectChickin) ChickinBaseDTO {
func ToChickinSimpleDTO(e entity.ProjectChickin) ChickinSimpleDTO { func ToChickinSimpleDTO(e entity.ProjectChickin) ChickinSimpleDTO {
return ChickinSimpleDTO{ return ChickinSimpleDTO{
Id: e.Id, Id: e.Id,
ProjectFlocKandangId: e.ProjectFlocKandangId, ProjectFlockKandangId: e.ProjectFlockKandangId,
ChickInDate: e.ChickInDate, ChickInDate: e.ChickInDate,
Quantity: e.Quantity, Quantity: e.Quantity,
Note: e.Note, Note: e.Note,
CreatedBy: e.CreatedBy, CreatedBy: e.CreatedBy,
} }
} }
@@ -26,12 +26,13 @@ func (ChickinModule) RegisterRoutes(router fiber.Router, db *gorm.DB, validate *
auditlogrepo := rAuditLog.NewAuditLogRepository(db) auditlogrepo := rAuditLog.NewAuditLogRepository(db)
warehouseRepo := rWarehouse.NewWarehouseRepository(db) warehouseRepo := rWarehouse.NewWarehouseRepository(db)
projectflockkandangrepo := rProjectFlock.NewProjectFlockKandangRepository(db) projectflockkandangrepo := rProjectFlock.NewProjectFlockKandangRepository(db)
projectflockpopulationrepo := rProjectFlock.NewProjectFlockPopulationRepository(db)
projectFlockRepo := rProjectFlock.NewProjectflockRepository(db) projectFlockRepo := rProjectFlock.NewProjectflockRepository(db)
productWarehouseRepo := rProductWarehouse.NewProductWarehouseRepository(db) productWarehouseRepo := rProductWarehouse.NewProductWarehouseRepository(db)
userRepo := rUser.NewUserRepository(db) userRepo := rUser.NewUserRepository(db)
chickinService := sChickin.NewChickinService(chickinRepo, kandangRepo, warehouseRepo, productWarehouseRepo, projectFlockRepo, auditlogrepo, projectflockkandangrepo, validate) chickinService := sChickin.NewChickinService(chickinRepo, kandangRepo, warehouseRepo, productWarehouseRepo, projectFlockRepo, auditlogrepo, projectflockkandangrepo, projectflockpopulationrepo, validate)
userService := sUser.NewUserService(userRepo, validate) userService := sUser.NewUserService(userRepo, validate)
ChickinRoutes(router, userService, chickinService) ChickinRoutes(router, userService, chickinService)
@@ -31,28 +31,30 @@ type ChickinService interface {
} }
type chickinService struct { type chickinService struct {
Log *logrus.Logger Log *logrus.Logger
Validate *validator.Validate Validate *validator.Validate
Repository repository.ProjectChickinRepository Repository repository.ProjectChickinRepository
KandangRepo KandangRepo.KandangRepository KandangRepo KandangRepo.KandangRepository
WarehouseRepo rWarehouse.WarehouseRepository WarehouseRepo rWarehouse.WarehouseRepository
ProductWarehouseRepo rProductWarehouse.ProductWarehouseRepository ProductWarehouseRepo rProductWarehouse.ProductWarehouseRepository
ProjectFlockRepo rProjectFlock.ProjectflockRepository ProjectFlockRepo rProjectFlock.ProjectflockRepository
AuditLogRepo AuditLogRepo.AuditLogRepository AuditLogRepo AuditLogRepo.AuditLogRepository
ProjectflockKandangRepo rProjectFlockKandang.ProjectFlockKandangRepository ProjectflockKandangRepo rProjectFlockKandang.ProjectFlockKandangRepository
ProjectflockPopulationRepo rProjectFlock.ProjectFlockPopulationRepository
} }
func NewChickinService(repo repository.ProjectChickinRepository, kandangRepo KandangRepo.KandangRepository, warehouseRepo rWarehouse.WarehouseRepository, productWarehouseRepo rProductWarehouse.ProductWarehouseRepository, projectFlockRepo rProjectFlock.ProjectflockRepository, auditLogRepo AuditLogRepo.AuditLogRepository, projectflockkandangRepo rProjectFlockKandang.ProjectFlockKandangRepository, validate *validator.Validate) ChickinService { func NewChickinService(repo repository.ProjectChickinRepository, kandangRepo KandangRepo.KandangRepository, warehouseRepo rWarehouse.WarehouseRepository, productWarehouseRepo rProductWarehouse.ProductWarehouseRepository, projectFlockRepo rProjectFlock.ProjectflockRepository, auditLogRepo AuditLogRepo.AuditLogRepository, projectflockkandangRepo rProjectFlockKandang.ProjectFlockKandangRepository, projectflockpopulationRepo rProjectFlock.ProjectFlockPopulationRepository, validate *validator.Validate) ChickinService {
return &chickinService{ return &chickinService{
Log: utils.Log, Log: utils.Log,
Validate: validate, Validate: validate,
Repository: repo, Repository: repo,
KandangRepo: kandangRepo, KandangRepo: kandangRepo,
WarehouseRepo: warehouseRepo, WarehouseRepo: warehouseRepo,
ProductWarehouseRepo: productWarehouseRepo, ProductWarehouseRepo: productWarehouseRepo,
ProjectFlockRepo: projectFlockRepo, ProjectFlockRepo: projectFlockRepo,
AuditLogRepo: auditLogRepo, AuditLogRepo: auditLogRepo,
ProjectflockKandangRepo: projectflockkandangRepo, ProjectflockKandangRepo: projectflockkandangRepo,
ProjectflockPopulationRepo: projectflockpopulationRepo,
} }
} }
@@ -78,8 +80,9 @@ func (s chickinService) GetAll(c *fiber.Ctx, params *validation.Query) ([]entity
chickins, total, err := s.Repository.GetAll(c.Context(), offset, params.Limit, func(db *gorm.DB) *gorm.DB { chickins, total, err := s.Repository.GetAll(c.Context(), offset, params.Limit, func(db *gorm.DB) *gorm.DB {
db = s.withRelations(db) db = s.withRelations(db)
if params.Search != "" {
return db.Where("name LIKE ?", "%"+params.Search+"%") if params.ProjectFlockKandangId != 0 {
return db.Where("project_flock_kandang_id = ?", params.ProjectFlockKandangId)
} }
return db.Order("created_at DESC").Order("updated_at DESC") return db.Order("created_at DESC").Order("updated_at DESC")
}) })
@@ -163,11 +166,11 @@ func (s *chickinService) CreateOne(c *fiber.Ctx, req *validation.Create) (*entit
} }
newChickin := &entity.ProjectChickin{ newChickin := &entity.ProjectChickin{
ProjectFlocKandangId: projectflockkandang.ProjectFlockId, ProjectFlockKandangId: projectflockkandang.ProjectFlockId,
ChickInDate: chickinDate, ChickInDate: chickinDate,
Quantity: productWarehouse.Quantity, Quantity: productWarehouse.Quantity,
Note: "", Note: "",
CreatedBy: 1, //todo: ganti dengan CreatedBy: 1, //todo: ganti dengan
} }
err = s.Repository.CreateOne(c.Context(), newChickin, nil) err = s.Repository.CreateOne(c.Context(), newChickin, nil)
@@ -188,45 +191,37 @@ func (s *chickinService) CreateOne(c *fiber.Ctx, req *validation.Create) (*entit
s.Log.Errorf("Failed to update product warehouse quantity: %+v", err) s.Log.Errorf("Failed to update product warehouse quantity: %+v", err)
return nil, err return nil, err
} }
// masukan data nya ke project flock population
// masukan check apakah stock availability ada, jika ada update, jika tidak buat baru // check apakah sudah ada
stockAvailability := &entity.StockAvailability{ existingPopulation, err := s.ProjectflockPopulationRepo.GetByProjectFlockKandangID(c.Context(), req.ProjectFlockKandangId)
EntityType: entity.EntityTypeProjectFlockKandang, if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
ReservedQuantity: productWarehouse.Quantity, s.Log.Errorf("Failed to get project flock population: %+v", err)
EntityId: projectflockkandang.Id, return nil, err
ProductId: productWarehouse.ProductId,
} }
if existingPopulation != nil {
// update quantity
var existingStockAvailability entity.StockAvailability err = s.ProjectflockPopulationRepo.PatchOne(c.Context(), existingPopulation.Id, map[string]any{
err = s.ProductWarehouseRepo.DB().WithContext(c.Context()). "reserved_quantity": newChickin.Quantity + existingPopulation.ReservedQuantity,
Where("entity_type = ? AND entity_id = ? AND product_id = ?", stockAvailability.EntityType, stockAvailability.EntityId, stockAvailability.ProductId). }, nil)
First(&existingStockAvailability).Error if err != nil {
s.Log.Errorf("Failed to update project flock population: %+v", err)
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
// buat baru
stockAvailability.ReservedQuantity = newChickin.Quantity
stockAvailability.Quantity = 0
err = s.ProductWarehouseRepo.DB().WithContext(c.Context()).Create(stockAvailability).Error
if err != nil {
s.Log.Errorf("Failed to create stock availability: %+v", err)
return nil, err
}
} else {
s.Log.Errorf("Failed to get stock availability: %+v", err)
return nil, err return nil, err
} }
} else { } else {
// update existing // create new population
newQuantity := existingStockAvailability.ReservedQuantity + newChickin.Quantity newPopulation := &entity.ProjectFlockPopulation{
err = s.ProductWarehouseRepo.DB().WithContext(c.Context()). ProjectFlockKandangId: req.ProjectFlockKandangId,
Model(&existingStockAvailability). InitialQuantity: 0,
Update("reserved_quantity", newQuantity).Error CurrentQuantity: 0,
ReservedQuantity: newChickin.Quantity,
CreatedBy: 1, // todo: ganti dengan user login
}
err = s.ProjectflockPopulationRepo.CreateOne(c.Context(), newPopulation, nil)
if err != nil { if err != nil {
s.Log.Errorf("Failed to update stock availability: %+v", err) s.Log.Errorf("Failed to create project flock population: %+v", err)
return nil, err return nil, err
} }
} }
return s.GetOne(c, newChickin.Id) return s.GetOne(c, newChickin.Id)
@@ -283,20 +278,21 @@ func (s *chickinService) Approve(c *fiber.Ctx, id uint) error {
return err return err
} }
//pindahkan stock dari reserved ke actual stock //pindahkan stock dari reserved ke actual stock pada table project flock population
// get stock avaibility untuk di update population, err := s.ProjectflockPopulationRepo.GetByProjectFlockKandangID(c.Context(), chickin.ProjectFlockKandangId)
var stockAvailability entity.StockAvailability
err = s.ProductWarehouseRepo.DB().WithContext(c.Context()).
Where("entity_type = ? AND entity_id = ? ", entity.EntityTypeProjectFlockKandang, chickin.ProjectFlocKandangId).
First(&stockAvailability).Error
if err != nil { if err != nil {
s.Log.Errorf("Failed to get stock availability: %+v", err) s.Log.Errorf("Failed to get project flock population: %+v", err)
return err return err
} }
newReservedQuantity := stockAvailability.ReservedQuantity - chickin.Quantity err = s.ProjectflockPopulationRepo.PatchOne(c.Context(), population.Id, map[string]any{
if newReservedQuantity < 0 { "reserved_quantity": population.ReservedQuantity - chickin.Quantity,
newReservedQuantity = 0 "initial_quantity": population.InitialQuantity + chickin.Quantity,
"current_quantity": population.CurrentQuantity + chickin.Quantity,
}, nil)
if err != nil {
s.Log.Errorf("Failed to update project flock population: %+v", err)
return err
} }
return nil return nil
@@ -10,7 +10,7 @@ type Update struct {
} }
type Query struct { type Query struct {
Page int `query:"page" validate:"omitempty,number,min=1"` Page int `query:"page" validate:"omitempty,number,min=1"`
Limit int `query:"limit" validate:"omitempty,number,min=1,max=100"` Limit int `query:"limit" validate:"omitempty,number,min=1,max=100"`
Search string `query:"search" validate:"omitempty,max=50"` ProjectFlockKandangId uint `query:"project_flock_kandang_id" validate:"omitempty,number,min=1"`
} }
@@ -8,6 +8,7 @@ import (
rFlock "gitlab.com/mbugroup/lti-api.git/internal/modules/master/flocks/repositories" rFlock "gitlab.com/mbugroup/lti-api.git/internal/modules/master/flocks/repositories"
rKandang "gitlab.com/mbugroup/lti-api.git/internal/modules/master/kandangs/repositories" rKandang "gitlab.com/mbugroup/lti-api.git/internal/modules/master/kandangs/repositories"
rProjectflock "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/repositories" rProjectflock "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/repositories"
sProjectflock "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/services" sProjectflock "gitlab.com/mbugroup/lti-api.git/internal/modules/production/project_flocks/services"
rUser "gitlab.com/mbugroup/lti-api.git/internal/modules/users/repositories" rUser "gitlab.com/mbugroup/lti-api.git/internal/modules/users/repositories"
@@ -0,0 +1,35 @@
package repository
import (
"context"
"gitlab.com/mbugroup/lti-api.git/internal/common/repository"
entity "gitlab.com/mbugroup/lti-api.git/internal/entities"
"gorm.io/gorm"
)
type ProjectFlockPopulationRepository interface {
repository.BaseRepository[entity.ProjectFlockPopulation]
GetByProjectFlockKandangID(ctx context.Context, projectFlockKandangID uint) (*entity.ProjectFlockPopulation, error)
}
type projectFlockPopulationRepositoryImpl struct {
*repository.BaseRepositoryImpl[entity.ProjectFlockPopulation]
}
func NewProjectFlockPopulationRepository(db *gorm.DB) ProjectFlockPopulationRepository {
return &projectFlockPopulationRepositoryImpl{
BaseRepositoryImpl: repository.NewBaseRepository[entity.ProjectFlockPopulation](db),
}
}
func (r *projectFlockPopulationRepositoryImpl) GetByProjectFlockKandangID(ctx context.Context, projectFlockKandangID uint) (*entity.ProjectFlockPopulation, error) {
var record entity.ProjectFlockPopulation
err := r.DB().WithContext(ctx).
Where("project_flock_kandang_id = ?", projectFlockKandangID).
First(&record).Error
if err != nil {
return nil, err
}
return &record, nil
}