package controllers import ( "encoding/json" "fmt" "nearle/models" "github.com/gofiber/fiber/v2" ) // parseStockRequests reads either one request or a list of them. // // Sniffing the first byte rather than trying one shape and falling back to the // other: BodyParser consumes what it reads, so a failed first attempt can leave // nothing for the second. The body is JSON here and `[` is unambiguous. func parseStockRequests(c *fiber.Ctx) ([]models.StockRequest, error) { body := c.Body() for _, b := range body { switch b { case ' ', '\t', '\r', '\n': continue case '[': var many []models.StockRequest if err := json.Unmarshal(body, &many); err != nil { return nil, err } return many, nil } break } var one models.StockRequest if err := c.BodyParser(&one); err != nil { return nil, err } return []models.StockRequest{one}, nil } // dedupeIDs drops repeats and anything non-positive, preserving order. // // Repeats matter here rather than being tidiness: approving adds stock, so the // same id twice in one batch would try to receive the same delivery twice. The // service has its own guard, but a batch should not be relying on it. func dedupeIDs(ids []int) []int { seen := make(map[int]bool, len(ids)) out := make([]int, 0, len(ids)) for _, id := range ids { if id <= 0 || seen[id] { continue } seen[id] = true out = append(out, id) } return out } // stockBatchMessage says what happened in words a merchant can act on. // // "8 approved, 2 could not be" beats "Success" when two of ten did not land — // the whole point of reporting per row is that the person can go and look. func stockBatchMessage(ok, failed int, verb string) string { if failed == 0 { return fmt.Sprintf("%d %s", ok, verb) } return fmt.Sprintf("%d %s, %d could not be", ok, verb, failed) }