mirror of
https://gitlab.com/mbugroup/lti-api.git
synced 2026-05-20 13:31:56 +00:00
Merge branch 'staging' into 'production'
Revert "Merge branch 'staging' into 'development'" See merge request mbugroup/lti-api!225
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
# .air.toml
|
||||
root = "."
|
||||
tmp_dir = "tmp"
|
||||
|
||||
[build]
|
||||
cmd = "go build -buildvcs=false -o ./tmp/main ./cmd/api"
|
||||
bin = "tmp/main"
|
||||
full_bin = "APP_ENV=dev ./tmp/main"
|
||||
include_ext = ["go", "tpl", "tmpl", "html"]
|
||||
exclude_dir = ["vendor", "tmp"]
|
||||
|
||||
[log]
|
||||
time = true
|
||||
@@ -237,6 +237,8 @@ func (u *ClosingController) GetClosingSapronak(c *fiber.Ctx) error {
|
||||
|
||||
query := &validation.ClosingSapronakQuery{
|
||||
Type: strings.ToLower(c.Query("type")),
|
||||
Page: c.QueryInt("page", 1),
|
||||
Limit: c.QueryInt("limit", 10),
|
||||
Search: c.Query("search"),
|
||||
}
|
||||
if raw := c.Query("kandang_id"); raw != "" {
|
||||
@@ -248,6 +250,10 @@ func (u *ClosingController) GetClosingSapronak(c *fiber.Ctx) error {
|
||||
query.KandangID = &kandangUint
|
||||
}
|
||||
|
||||
if query.Page < 1 || query.Limit < 1 {
|
||||
return fiber.NewError(fiber.StatusBadRequest, "page and limit must be greater than 0")
|
||||
}
|
||||
|
||||
if query.Type != validation.SapronakTypeIncoming && query.Type != validation.SapronakTypeOutgoing {
|
||||
return fiber.NewError(fiber.StatusBadRequest, "type must be either incoming or outgoing")
|
||||
}
|
||||
@@ -282,8 +288,6 @@ func (u *ClosingController) GetClosingSapronakSummary(c *fiber.Ctx) error {
|
||||
|
||||
query := &validation.ClosingSapronakQuery{
|
||||
Type: strings.ToLower(c.Query("type")),
|
||||
Page: c.QueryInt("page", 1),
|
||||
Limit: c.QueryInt("limit", 10),
|
||||
Search: c.Query("search"),
|
||||
}
|
||||
if raw := c.Query("kandang_id"); raw != "" {
|
||||
@@ -295,10 +299,6 @@ func (u *ClosingController) GetClosingSapronakSummary(c *fiber.Ctx) error {
|
||||
query.KandangID = &kandangUint
|
||||
}
|
||||
|
||||
if query.Page < 1 || query.Limit < 1 {
|
||||
return fiber.NewError(fiber.StatusBadRequest, "page and limit must be greater than 0")
|
||||
}
|
||||
|
||||
if query.Type != validation.SapronakTypeIncoming && query.Type != validation.SapronakTypeOutgoing {
|
||||
return fiber.NewError(fiber.StatusBadRequest, "type must be either incoming or outgoing")
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ func ClosingRoutes(v1 fiber.Router, u user.UserService, s closing.ClosingService
|
||||
route.Get("/:project_flock_id/:project_flock_kandang_id/perhitungan_sapronak", m.RequirePermissions(m.P_ClosingDetail), ctrl.GetSapronakByKandang)
|
||||
route.Get("/:project_flock_id/perhitungan_sapronak", m.RequirePermissions(m.P_ClosingDetail), ctrl.GetSapronakByProject)
|
||||
route.Get("/:projectFlockId/sapronak", m.RequirePermissions(m.P_ClosingDetail), ctrl.GetClosingSapronak)
|
||||
route.Get("/:projectFlockId/sapronak/summary", m.RequirePermissions(m.P_ClosingDetail), ctrl.GetClosingSapronakSummary)
|
||||
route.Get("/:project_flock_id/expedition-hpp", m.RequirePermissions(m.P_ClosingDetail), ctrl.GetExpeditionHPP)
|
||||
route.Get("/:project_flock_id/:project_flock_kandang_id/expedition-hpp", m.RequirePermissions(m.P_ClosingDetail), ctrl.GetExpeditionHPPByKandang)
|
||||
route.Get("/:projectFlockId/production-data", m.RequirePermissions(m.P_ClosingDetail), ctrl.GetClosingDataProduksi)
|
||||
|
||||
@@ -52,7 +52,7 @@ type SummaryQuery struct {
|
||||
|
||||
type ReportQuery struct {
|
||||
Page int `query:"page" validate:"required,number,min=1,gt=0"`
|
||||
Limit int `query:"limit" validate:"required,number,min=1,max=100,gt=0"`
|
||||
Limit int `query:"limit" validate:"required,number,min=1,gt=0"`
|
||||
Month int `query:"bulan" validate:"required,number,min=1,max=12"`
|
||||
Year int `query:"tahun" validate:"required,number,min=1900"`
|
||||
AreaID *uint `query:"area_id" validate:"omitempty"`
|
||||
|
||||
@@ -76,6 +76,9 @@ func (s *configChecklistService) CreateOne(c *fiber.Ctx, req *validation.Create)
|
||||
if err := s.Validate.Struct(req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if req.PercentageThresholdBad > req.PercentageThresholdEnough {
|
||||
return nil, fiber.NewError(fiber.StatusBadRequest, "percentage_threshold_bad cannot be greater than percentage_threshold_enough")
|
||||
}
|
||||
|
||||
date, err := time.Parse("2006-01-02", req.Date)
|
||||
if err != nil {
|
||||
@@ -100,6 +103,11 @@ func (s configChecklistService) UpdateOne(c *fiber.Ctx, req *validation.Update,
|
||||
if err := s.Validate.Struct(req); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if req.PercentageThresholdBad != nil && req.PercentageThresholdEnough != nil {
|
||||
if *req.PercentageThresholdBad > *req.PercentageThresholdEnough {
|
||||
return nil, fiber.NewError(fiber.StatusBadRequest, "percentage_threshold_bad cannot be greater than percentage_threshold_enough")
|
||||
}
|
||||
}
|
||||
|
||||
updateBody := make(map[string]any)
|
||||
|
||||
|
||||
@@ -110,6 +110,17 @@ func (s *phaseActivityService) CreateOne(c *fiber.Ctx, req *validation.Create) (
|
||||
return nil, fiber.NewError(fiber.StatusBadRequest, "time_type cannot be empty")
|
||||
}
|
||||
|
||||
existing, err := s.Repository.First(c.Context(), func(db *gorm.DB) *gorm.DB {
|
||||
return db.Where("phase_id = ? AND name = ? AND time_type = ?", phase.Id, name, timeType)
|
||||
})
|
||||
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
s.Log.Errorf("Failed to check phaseActivity uniqueness: %+v", err)
|
||||
return nil, err
|
||||
}
|
||||
if existing != nil {
|
||||
return nil, fiber.NewError(fiber.StatusBadRequest, "phase activity with same name and time_type already exists")
|
||||
}
|
||||
|
||||
createBody := &entity.PhaseActivity{
|
||||
PhaseId: phase.Id,
|
||||
Name: name,
|
||||
|
||||
@@ -751,6 +751,9 @@ func (s *purchaseService) ReceiveProducts(c *fiber.Ctx, id uint, req *validation
|
||||
if receivedQty > item.SubQty {
|
||||
return nil, utils.BadRequest(fmt.Sprintf("Received quantity for item %d cannot exceed ordered quantity (%.3f)", payload.PurchaseItemID, item.SubQty))
|
||||
}
|
||||
if receivedQty < item.TotalUsed {
|
||||
return nil, utils.BadRequest(fmt.Sprintf("Received quantity for item %d cannot be lower than used amount (%.3f)", payload.PurchaseItemID, item.TotalUsed))
|
||||
}
|
||||
|
||||
if _, dup := visitedItems[payload.PurchaseItemID]; dup {
|
||||
return nil, utils.BadRequest(fmt.Sprintf("Duplicate receiving data for item %d", payload.PurchaseItemID))
|
||||
@@ -835,6 +838,7 @@ func (s *purchaseService) ReceiveProducts(c *fiber.Ctx, id uint, req *validation
|
||||
affected := make(map[uint]struct{})
|
||||
updates := make([]rPurchase.PurchaseReceivingUpdate, 0, len(prepared))
|
||||
priceUpdates := make([]rPurchase.PurchasePricingUpdate, 0, len(prepared))
|
||||
totalQtyDeltas := make(map[uint]float64)
|
||||
fifoAdds := make([]struct {
|
||||
itemID uint
|
||||
pwID uint
|
||||
@@ -862,14 +866,20 @@ func (s *purchaseService) ReceiveProducts(c *fiber.Ctx, id uint, req *validation
|
||||
deltaQty := prep.receivedQty - item.TotalQty
|
||||
switch {
|
||||
case deltaQty > 0 && newPWID != nil:
|
||||
fifoAdds = append(fifoAdds, struct {
|
||||
itemID uint
|
||||
pwID uint
|
||||
qty float64
|
||||
}{itemID: item.Id, pwID: *newPWID, qty: deltaQty})
|
||||
if s.FifoSvc != nil {
|
||||
fifoAdds = append(fifoAdds, struct {
|
||||
itemID uint
|
||||
pwID uint
|
||||
qty float64
|
||||
}{itemID: item.Id, pwID: *newPWID, qty: deltaQty})
|
||||
} else {
|
||||
deltas[*newPWID] += deltaQty
|
||||
totalQtyDeltas[item.Id] += deltaQty
|
||||
}
|
||||
case deltaQty < 0 && newPWID != nil:
|
||||
deltas[*newPWID] += deltaQty // negative
|
||||
affected[*newPWID] = struct{}{}
|
||||
totalQtyDeltas[item.Id] += deltaQty
|
||||
}
|
||||
|
||||
dateCopy := prep.receivedDate
|
||||
@@ -892,7 +902,7 @@ func (s *purchaseService) ReceiveProducts(c *fiber.Ctx, id uint, req *validation
|
||||
|
||||
updates = append(updates, update)
|
||||
|
||||
if item.Price > 0 && prep.receivedQty >= 0 {
|
||||
if prep.receivedQty >= 0 {
|
||||
priceUpdates = append(priceUpdates, rPurchase.PurchasePricingUpdate{
|
||||
ItemID: item.Id,
|
||||
Price: item.Price,
|
||||
@@ -919,6 +929,19 @@ func (s *purchaseService) ReceiveProducts(c *fiber.Ctx, id uint, req *validation
|
||||
}
|
||||
}
|
||||
|
||||
if len(totalQtyDeltas) > 0 {
|
||||
for itemID, delta := range totalQtyDeltas {
|
||||
if delta == 0 {
|
||||
continue
|
||||
}
|
||||
if err := tx.Model(&entity.PurchaseItem{}).
|
||||
Where("purchase_id = ? AND id = ?", purchase.Id, itemID).
|
||||
Update("total_qty", gorm.Expr("COALESCE(total_qty,0) + ?", delta)).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Update due_date based on earliest received date when receiving approved.
|
||||
if earliestReceived != nil {
|
||||
due := earliestReceived.AddDate(0, 0, purchase.CreditTerm)
|
||||
@@ -1371,10 +1394,6 @@ func (s *purchaseService) buildStaffAdjustmentPayload(
|
||||
qtyCopy := effectiveQty
|
||||
update.Quantity = &qtyCopy
|
||||
}
|
||||
if syncReceiving {
|
||||
qtyCopy := effectiveQty
|
||||
update.TotalQty = &qtyCopy
|
||||
}
|
||||
|
||||
updates = append(updates, update)
|
||||
delete(requestItems, item.Id)
|
||||
|
||||
Reference in New Issue
Block a user