Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -18,6 +18,7 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
"github.com/lib/pq"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
|
||||
@@ -497,25 +498,65 @@ func UserCreateRoute(db *sql.DB) http.HandlerFunc {
|
||||
|
||||
// ROLES
|
||||
for _, role := range payload.Roles {
|
||||
_, _ = tx.Exec(queries.InsertUserRole, newID, role)
|
||||
role = strings.TrimSpace(role)
|
||||
if role == "" {
|
||||
continue
|
||||
}
|
||||
if _, err := tx.Exec(queries.InsertUserRole, newID, role); err != nil {
|
||||
log.Printf("USER ROLE INSERT ERROR user_id=%d role=%q err=%v", newID, role, err)
|
||||
http.Error(w, "Rol eklenemedi", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// DEPARTMENTS
|
||||
for _, d := range payload.Departments {
|
||||
_, _ = tx.Exec(queries.InsertUserDepartment, newID, d.Code)
|
||||
code := strings.TrimSpace(d.Code)
|
||||
if code == "" {
|
||||
continue
|
||||
}
|
||||
if _, err := tx.Exec(queries.InsertUserDepartment, newID, code); err != nil {
|
||||
log.Printf("USER DEPARTMENT INSERT ERROR user_id=%d department=%q err=%v", newID, code, err)
|
||||
http.Error(w, "Departman eklenemedi", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// PIYASALAR
|
||||
for _, p := range payload.Piyasalar {
|
||||
_, _ = tx.Exec(queries.InsertUserPiyasa, newID, p.Code)
|
||||
code := strings.TrimSpace(p.Code)
|
||||
if code == "" {
|
||||
continue
|
||||
}
|
||||
if _, err := tx.Exec(queries.InsertUserPiyasa, newID, code); err != nil {
|
||||
log.Printf("USER PIYASA INSERT ERROR user_id=%d piyasa=%q err=%v", newID, code, err)
|
||||
http.Error(w, "Piyasa eklenemedi", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// NEBIM
|
||||
for _, n := range payload.NebimUsers {
|
||||
_, _ = tx.Exec(queries.InsertUserNebim, newID, n.Username)
|
||||
username := strings.TrimSpace(n.Username)
|
||||
if username == "" {
|
||||
continue
|
||||
}
|
||||
if _, err := tx.Exec(queries.InsertUserNebim, newID, username); err != nil {
|
||||
log.Printf("USER NEBIM INSERT ERROR user_id=%d username=%q err=%v", newID, username, err)
|
||||
http.Error(w, "Nebim kullanıcısı eklenemedi", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if err := tx.Commit(); err != nil {
|
||||
if pe, ok := err.(*pq.Error); ok {
|
||||
log.Printf(
|
||||
"USER CREATE COMMIT ERROR user_id=%d code=%s detail=%s constraint=%s table=%s err=%v",
|
||||
newID, pe.Code, pe.Detail, pe.Constraint, pe.Table, err,
|
||||
)
|
||||
} else {
|
||||
log.Printf("USER CREATE COMMIT ERROR user_id=%d err=%v", newID, err)
|
||||
}
|
||||
http.Error(w, "Commit başarısız", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -32,13 +32,31 @@ func GetProductPricingListHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
limit := 500
|
||||
if raw := strings.TrimSpace(r.URL.Query().Get("limit")); raw != "" {
|
||||
if parsed, err := strconv.Atoi(raw); err == nil && parsed > 0 && parsed <= 10000 {
|
||||
if parsed, err := strconv.Atoi(raw); err == nil && parsed > 0 && parsed <= 500 {
|
||||
limit = parsed
|
||||
}
|
||||
}
|
||||
afterProductCode := strings.TrimSpace(r.URL.Query().Get("after_product_code"))
|
||||
page := 1
|
||||
if raw := strings.TrimSpace(r.URL.Query().Get("page")); raw != "" {
|
||||
if parsed, err := strconv.Atoi(raw); err == nil && parsed > 0 {
|
||||
page = parsed
|
||||
}
|
||||
}
|
||||
filters := queries.ProductPricingFilters{
|
||||
Search: strings.TrimSpace(r.URL.Query().Get("q")),
|
||||
ProductCode: splitCSVParam(r.URL.Query().Get("product_code")),
|
||||
BrandGroup: splitCSVParam(r.URL.Query().Get("brand_group_selection")),
|
||||
AskiliYan: splitCSVParam(r.URL.Query().Get("askili_yan")),
|
||||
Kategori: splitCSVParam(r.URL.Query().Get("kategori")),
|
||||
UrunIlkGrubu: splitCSVParam(r.URL.Query().Get("urun_ilk_grubu")),
|
||||
UrunAnaGrubu: splitCSVParam(r.URL.Query().Get("urun_ana_grubu")),
|
||||
UrunAltGrubu: splitCSVParam(r.URL.Query().Get("urun_alt_grubu")),
|
||||
Icerik: splitCSVParam(r.URL.Query().Get("icerik")),
|
||||
Karisim: splitCSVParam(r.URL.Query().Get("karisim")),
|
||||
Marka: splitCSVParam(r.URL.Query().Get("marka")),
|
||||
}
|
||||
|
||||
rows, err := queries.GetProductPricingList(ctx, limit+1, afterProductCode)
|
||||
pageResult, err := queries.GetProductPricingPage(ctx, page, limit, filters)
|
||||
if err != nil {
|
||||
if isPricingTimeoutLike(err, ctx.Err()) {
|
||||
log.Printf(
|
||||
@@ -63,38 +81,24 @@ func GetProductPricingListHandler(w http.ResponseWriter, r *http.Request) {
|
||||
http.Error(w, "Urun fiyatlandirma listesi alinamadi: "+err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
hasMore := len(rows) > limit
|
||||
if hasMore {
|
||||
rows = rows[:limit]
|
||||
}
|
||||
nextCursor := ""
|
||||
if hasMore && len(rows) > 0 {
|
||||
nextCursor = strings.TrimSpace(rows[len(rows)-1].ProductCode)
|
||||
}
|
||||
|
||||
log.Printf(
|
||||
"[ProductPricing] trace=%s success user=%s id=%d limit=%d after=%q count=%d has_more=%t next=%q duration_ms=%d",
|
||||
"[ProductPricing] trace=%s success user=%s id=%d page=%d limit=%d count=%d total=%d total_pages=%d duration_ms=%d",
|
||||
traceID,
|
||||
claims.Username,
|
||||
claims.ID,
|
||||
pageResult.Page,
|
||||
limit,
|
||||
afterProductCode,
|
||||
len(rows),
|
||||
hasMore,
|
||||
nextCursor,
|
||||
len(pageResult.Rows),
|
||||
pageResult.TotalCount,
|
||||
pageResult.TotalPages,
|
||||
time.Since(started).Milliseconds(),
|
||||
)
|
||||
|
||||
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||
if hasMore {
|
||||
w.Header().Set("X-Has-More", "true")
|
||||
} else {
|
||||
w.Header().Set("X-Has-More", "false")
|
||||
}
|
||||
if nextCursor != "" {
|
||||
w.Header().Set("X-Next-Cursor", nextCursor)
|
||||
}
|
||||
_ = json.NewEncoder(w).Encode(rows)
|
||||
w.Header().Set("X-Total-Count", strconv.Itoa(pageResult.TotalCount))
|
||||
w.Header().Set("X-Total-Pages", strconv.Itoa(pageResult.TotalPages))
|
||||
w.Header().Set("X-Page", strconv.Itoa(pageResult.Page))
|
||||
_ = json.NewEncoder(w).Encode(pageResult.Rows)
|
||||
}
|
||||
|
||||
func buildPricingTraceID(r *http.Request) string {
|
||||
@@ -124,3 +128,20 @@ func isPricingTimeoutLike(err error, ctxErr error) bool {
|
||||
strings.Contains(e, "no connection could be made") ||
|
||||
strings.Contains(e, "failed to respond")
|
||||
}
|
||||
|
||||
func splitCSVParam(raw string) []string {
|
||||
raw = strings.TrimSpace(raw)
|
||||
if raw == "" {
|
||||
return nil
|
||||
}
|
||||
parts := strings.Split(raw, ",")
|
||||
out := make([]string, 0, len(parts))
|
||||
for _, p := range parts {
|
||||
p = strings.TrimSpace(p)
|
||||
if p == "" {
|
||||
continue
|
||||
}
|
||||
out = append(out, p)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user