Compare commits

...

4 Commits

4 changed files with 66 additions and 31 deletions
@@ -65,7 +65,7 @@ type SapronakCategoryRowDTO struct {
QtyOut float64 `json:"qty_out"` QtyOut float64 `json:"qty_out"`
QtyUsed float64 `json:"qty_used"` QtyUsed float64 `json:"qty_used"`
Description string `json:"description"` Description string `json:"description"`
ProductCategory []string `json:"product_category"` ProductCategory string `json:"product_category"`
UnitPrice float64 `json:"unit_price"` UnitPrice float64 `json:"unit_price"`
TotalAmount float64 `json:"total_amount"` TotalAmount float64 `json:"total_amount"`
Notes string `json:"notes"` Notes string `json:"notes"`
@@ -183,13 +183,13 @@ func ToSapronakProjectAggregatedFromReport(report *SapronakReportDTO, flag strin
"PULLET": 0, "PULLET": 0,
} }
buildFlagList := func(productID uint, fallback string) []string { buildFlagList := func(productID uint, fallback string) string {
rawFlags := productFlags[productID] rawFlags := productFlags[productID]
if len(rawFlags) == 0 { if len(rawFlags) == 0 {
if fallback == "" { if fallback == "" {
return []string{} return ""
} }
return []string{fallback} return fallback
} }
seen := make(map[string]struct{}, len(rawFlags)) seen := make(map[string]struct{}, len(rawFlags))
ordered := make([]string, 0, len(rawFlags)) ordered := make([]string, 0, len(rawFlags))
@@ -220,7 +220,7 @@ func ToSapronakProjectAggregatedFromReport(report *SapronakReportDTO, flag strin
} }
return li < lj return li < lj
}) })
return ordered return strings.Join(ordered, " ")
} }
for _, group := range report.Groups { for _, group := range report.Groups {
@@ -4,8 +4,8 @@ import (
"context" "context"
"errors" "errors"
"fmt" "fmt"
"strings"
"time" "time"
commonRepo "gitlab.com/mbugroup/lti-api.git/internal/common/repository" commonRepo "gitlab.com/mbugroup/lti-api.git/internal/common/repository"
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"
@@ -117,18 +117,30 @@ func (s deliveryOrdersService) GetAll(c *fiber.Ctx, params *validation.DeliveryO
Preload("Products.DeliveryProduct") Preload("Products.DeliveryProduct")
if params.Status != "" { if params.Status != "" {
status := strings.TrimSpace(params.Status)
latestApprovalSubQuery := s.MarketingRepo.DB(). latestApprovalSubQuery := s.MarketingRepo.DB().
WithContext(c.Context()). WithContext(c.Context()).
Table("approvals"). Table("approvals").
Select("DISTINCT ON (approvable_id) approvable_id, step_name"). Select("DISTINCT ON (approvable_id) approvable_id, step_name, action").
Where("approvable_type = ?", utils.ApprovalWorkflowMarketing.String()). Where("approvable_type = ?", utils.ApprovalWorkflowMarketing.String()).
Order("approvable_id, id DESC") Order("approvable_id, id DESC")
db = db.Where(`EXISTS (
SELECT 1 if strings.EqualFold(status, "DITOLAK") {
FROM (?) AS latest_approval db = db.Where(`EXISTS (
WHERE latest_approval.approvable_id = marketings.id SELECT 1
AND LOWER(latest_approval.step_name) = LOWER(?) FROM (?) AS latest_approval
)`, latestApprovalSubQuery, params.Status) WHERE latest_approval.approvable_id = marketings.id
AND latest_approval.action = ?
)`, latestApprovalSubQuery, string(entity.ApprovalActionRejected))
} else {
db = db.Where(`EXISTS (
SELECT 1
FROM (?) AS latest_approval
WHERE latest_approval.approvable_id = marketings.id
AND LOWER(latest_approval.step_name) = LOWER(?)
AND (latest_approval.action IS NULL OR latest_approval.action <> ?)
)`, latestApprovalSubQuery, status, string(entity.ApprovalActionRejected))
}
} }
if params.Search != "" { if params.Search != "" {
@@ -152,6 +152,31 @@ func (s *salesOrdersService) CreateOne(c *fiber.Ctx, req *validation.Create) (*e
} }
} }
requestedByWarehouse := make(map[uint]float64)
for _, item := range req.MarketingProducts {
if item.ProductWarehouseId == 0 {
continue
}
requestedByWarehouse[item.ProductWarehouseId] += item.Qty
}
for pwID, requestedQty := range requestedByWarehouse {
productWarehouse, err := s.ProductWarehouseRepo.GetDetailByID(c.Context(), pwID)
if err != nil {
if errors.Is(err, gorm.ErrRecordNotFound) {
return nil, fiber.NewError(fiber.StatusNotFound, fmt.Sprintf("Product warehouse %d not found", pwID))
}
return nil, fiber.NewError(fiber.StatusInternalServerError, "Failed to check stock availability")
}
availableQty := productWarehouse.Quantity
if availableQty+1e-6 < requestedQty {
return nil, fiber.NewError(
fiber.StatusBadRequest,
fmt.Sprintf("Stok tidak mencukupi untuk gudang %d: diminta %.3f, tersedia %.3f", pwID, requestedQty, availableQty),
)
}
}
soDate, err := utils.ParseDateString(req.Date) soDate, err := utils.ParseDateString(req.Date)
if err != nil { if err != nil {
return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid date format") return nil, fiber.NewError(fiber.StatusBadRequest, "Invalid date format")
@@ -308,25 +308,23 @@ func (s projectFlockKandangService) CheckClosing(c *fiber.Ctx, id uint) (*Closin
} }
for _, pw := range productWarehouses { for _, pw := range productWarehouses {
if pw.Quantity > 0 { category := ""
category := "" if pw.Product.ProductCategory.Id != 0 {
if pw.Product.ProductCategory.Id != 0 { category = pw.Product.ProductCategory.Name
category = pw.Product.ProductCategory.Name
}
uomName := ""
if pw.Product.Uom.Id != 0 {
uomName = pw.Product.Uom.Name
}
stockRemain = append(stockRemain, StockRemainingDetail{
FlagName: string(flagName),
ProductWarehouseId: pw.Id,
ProductId: pw.ProductId,
ProductName: pw.Product.Name,
ProductCategory: category,
Uom: uomName,
Quantity: pw.Quantity,
})
} }
uomName := ""
if pw.Product.Uom.Id != 0 {
uomName = pw.Product.Uom.Name
}
stockRemain = append(stockRemain, StockRemainingDetail{
FlagName: string(flagName),
ProductWarehouseId: pw.Id,
ProductId: pw.ProductId,
ProductName: pw.Product.Name,
ProductCategory: category,
Uom: uomName,
Quantity: pw.Quantity,
})
} }
} }
} }