Merge remote-tracking branch 'origin/master'
This commit is contained in:
@@ -8,7 +8,6 @@ import (
|
||||
"database/sql"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/gorilla/mux"
|
||||
@@ -23,6 +22,42 @@ type FirstGroupMailLookupResponse struct {
|
||||
Mails []models.MailOption `json:"mails"`
|
||||
}
|
||||
|
||||
func ensureFirstGroupMailMappingTables(pg *sql.DB) error {
|
||||
// Idempotent bootstrap: create tables if they don't exist.
|
||||
// We keep schema minimal: (group_code, mail_id) + created_at and FK to mk_mail.
|
||||
stmts := []string{
|
||||
`
|
||||
CREATE TABLE IF NOT EXISTS mk_costing_first_group_mail (
|
||||
urun_ilk_grubu TEXT NOT NULL,
|
||||
mail_id UUID NOT NULL,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
PRIMARY KEY (urun_ilk_grubu, mail_id),
|
||||
CONSTRAINT fk_costing_first_group_mail_mail
|
||||
FOREIGN KEY (mail_id) REFERENCES mk_mail(id) ON DELETE CASCADE
|
||||
)
|
||||
`,
|
||||
`CREATE INDEX IF NOT EXISTS ix_costing_first_group_mail_group ON mk_costing_first_group_mail (urun_ilk_grubu)`,
|
||||
`
|
||||
CREATE TABLE IF NOT EXISTS mk_pricing_first_group_mail (
|
||||
urun_ilk_grubu TEXT NOT NULL,
|
||||
mail_id UUID NOT NULL,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
||||
PRIMARY KEY (urun_ilk_grubu, mail_id),
|
||||
CONSTRAINT fk_pricing_first_group_mail_mail
|
||||
FOREIGN KEY (mail_id) REFERENCES mk_mail(id) ON DELETE CASCADE
|
||||
)
|
||||
`,
|
||||
`CREATE INDEX IF NOT EXISTS ix_pricing_first_group_mail_group ON mk_pricing_first_group_mail (urun_ilk_grubu)`,
|
||||
}
|
||||
|
||||
for _, s := range stmts {
|
||||
if _, err := pg.Exec(s); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func GetCostingFirstGroupMailMappingLookupsHandler(pg *sql.DB) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json; charset=utf-8")
|
||||
@@ -32,6 +67,10 @@ func GetCostingFirstGroupMailMappingLookupsHandler(pg *sql.DB) http.HandlerFunc
|
||||
http.Error(w, "mssql connection not available", http.StatusServiceUnavailable)
|
||||
return
|
||||
}
|
||||
if err := ensureFirstGroupMailMappingTables(pg); err != nil {
|
||||
http.Error(w, "mapping table bootstrap error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
traceID := utils.TraceIDFromRequest(r)
|
||||
ctx := utils.ContextWithTraceID(r.Context(), traceID)
|
||||
@@ -39,21 +78,23 @@ func GetCostingFirstGroupMailMappingLookupsHandler(pg *sql.DB) http.HandlerFunc
|
||||
firstGroups := make([]models.FirstGroupOption, 0, 256)
|
||||
mails := make([]models.MailOption, 0, 256)
|
||||
|
||||
fgRows, err := queries.ListProductFirstGroupOptions(ctx, mssql, "", 5000)
|
||||
fgRows, err := queries.ListProductFirstGroupCodeDescOptions(ctx, mssql, "", 5000)
|
||||
if err != nil {
|
||||
http.Error(w, "first group lookup error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
defer fgRows.Close()
|
||||
for fgRows.Next() {
|
||||
var g string
|
||||
if err := fgRows.Scan(&g); err != nil {
|
||||
var code string
|
||||
var title string
|
||||
if err := fgRows.Scan(&code, &title); err != nil {
|
||||
http.Error(w, "first group scan error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
g = strings.TrimSpace(g)
|
||||
if g != "" {
|
||||
firstGroups = append(firstGroups, models.FirstGroupOption{ID: g, Label: g})
|
||||
code = strings.TrimSpace(code)
|
||||
title = strings.TrimSpace(title)
|
||||
if code != "" {
|
||||
firstGroups = append(firstGroups, models.FirstGroupOption{Code: code, Title: title})
|
||||
}
|
||||
}
|
||||
if err := fgRows.Err(); err != nil {
|
||||
@@ -98,34 +139,44 @@ func GetCostingFirstGroupMailMappingsHandler(pg *sql.DB) http.HandlerFunc {
|
||||
http.Error(w, "mssql connection not available", http.StatusServiceUnavailable)
|
||||
return
|
||||
}
|
||||
if err := ensureFirstGroupMailMappingTables(pg); err != nil {
|
||||
http.Error(w, "mapping table bootstrap error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
traceID := utils.TraceIDFromRequest(r)
|
||||
ctx := utils.ContextWithTraceID(r.Context(), traceID)
|
||||
|
||||
// Fetch all first groups from V3 (source of truth for the list)
|
||||
allGroups := make([]string, 0, 512)
|
||||
fgRows, err := queries.ListProductFirstGroupOptions(ctx, mssql, "", 5000)
|
||||
allCodes := make([]string, 0, 512)
|
||||
titleByCode := make(map[string]string, 512)
|
||||
fgRows, err := queries.ListProductFirstGroupCodeDescOptions(ctx, mssql, "", 5000)
|
||||
if err != nil {
|
||||
http.Error(w, "first group lookup error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
defer fgRows.Close()
|
||||
for fgRows.Next() {
|
||||
var g string
|
||||
if err := fgRows.Scan(&g); err != nil {
|
||||
var code string
|
||||
var title string
|
||||
if err := fgRows.Scan(&code, &title); err != nil {
|
||||
http.Error(w, "first group scan error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
g = strings.TrimSpace(g)
|
||||
if g != "" {
|
||||
allGroups = append(allGroups, g)
|
||||
code = strings.TrimSpace(code)
|
||||
title = strings.TrimSpace(title)
|
||||
if code != "" {
|
||||
allCodes = append(allCodes, code)
|
||||
if _, ok := titleByCode[code]; !ok {
|
||||
titleByCode[code] = title
|
||||
}
|
||||
}
|
||||
}
|
||||
if err := fgRows.Err(); err != nil {
|
||||
http.Error(w, "first group rows error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
sort.Strings(allGroups)
|
||||
allCodes = normalizeIDList(allCodes)
|
||||
|
||||
// Fetch mappings from Postgres
|
||||
rows, err := pg.Query(queries.GetCostingFirstGroupMailMappingRows)
|
||||
@@ -136,9 +187,11 @@ func GetCostingFirstGroupMailMappingsHandler(pg *sql.DB) http.HandlerFunc {
|
||||
defer rows.Close()
|
||||
|
||||
byGroup := map[string]*models.FirstGroupMailMappingRow{}
|
||||
for _, g := range allGroups {
|
||||
byGroup[g] = &models.FirstGroupMailMappingRow{
|
||||
UrunIlkGrubu: g,
|
||||
for _, code := range allCodes {
|
||||
byGroup[code] = &models.FirstGroupMailMappingRow{
|
||||
UrunIlkGrubu: code,
|
||||
GroupCode: code,
|
||||
GroupTitle: titleByCode[code],
|
||||
MailIDs: make([]string, 0, 8),
|
||||
Mails: make([]models.FirstGroupMailOption, 0, 8),
|
||||
}
|
||||
@@ -153,19 +206,21 @@ func GetCostingFirstGroupMailMappingsHandler(pg *sql.DB) http.HandlerFunc {
|
||||
http.Error(w, "mapping scan error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
g := strings.TrimSpace(group.String)
|
||||
if g == "" {
|
||||
code := strings.TrimSpace(group.String)
|
||||
if code == "" {
|
||||
continue
|
||||
}
|
||||
row, ok := byGroup[g]
|
||||
row, ok := byGroup[code]
|
||||
if !ok {
|
||||
row = &models.FirstGroupMailMappingRow{
|
||||
UrunIlkGrubu: g,
|
||||
UrunIlkGrubu: code,
|
||||
GroupCode: code,
|
||||
GroupTitle: titleByCode[code],
|
||||
MailIDs: make([]string, 0, 8),
|
||||
Mails: make([]models.FirstGroupMailOption, 0, 8),
|
||||
}
|
||||
byGroup[g] = row
|
||||
allGroups = append(allGroups, g)
|
||||
byGroup[code] = row
|
||||
allCodes = append(allCodes, code)
|
||||
}
|
||||
if mailID.Valid && strings.TrimSpace(mailID.String) != "" {
|
||||
id := strings.TrimSpace(mailID.String)
|
||||
@@ -182,11 +237,15 @@ func GetCostingFirstGroupMailMappingsHandler(pg *sql.DB) http.HandlerFunc {
|
||||
return
|
||||
}
|
||||
|
||||
sort.Strings(allGroups)
|
||||
out := make([]models.FirstGroupMailMappingRow, 0, len(allGroups))
|
||||
for _, g := range allGroups {
|
||||
if r := byGroup[g]; r != nil {
|
||||
allCodes = normalizeIDList(allCodes)
|
||||
out := make([]models.FirstGroupMailMappingRow, 0, len(allCodes))
|
||||
for _, code := range allCodes {
|
||||
if r := byGroup[code]; r != nil {
|
||||
r.MailIDs = normalizeIDList(r.MailIDs)
|
||||
// Fill title if missing
|
||||
if strings.TrimSpace(r.GroupTitle) == "" {
|
||||
r.GroupTitle = titleByCode[code]
|
||||
}
|
||||
out = append(out, *r)
|
||||
}
|
||||
}
|
||||
@@ -203,33 +262,43 @@ func GetPricingFirstGroupMailMappingsHandler(pg *sql.DB) http.HandlerFunc {
|
||||
http.Error(w, "mssql connection not available", http.StatusServiceUnavailable)
|
||||
return
|
||||
}
|
||||
if err := ensureFirstGroupMailMappingTables(pg); err != nil {
|
||||
http.Error(w, "mapping table bootstrap error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
traceID := utils.TraceIDFromRequest(r)
|
||||
ctx := utils.ContextWithTraceID(r.Context(), traceID)
|
||||
|
||||
allGroups := make([]string, 0, 512)
|
||||
fgRows, err := queries.ListProductFirstGroupOptions(ctx, mssql, "", 5000)
|
||||
allCodes := make([]string, 0, 512)
|
||||
titleByCode := make(map[string]string, 512)
|
||||
fgRows, err := queries.ListProductFirstGroupCodeDescOptions(ctx, mssql, "", 5000)
|
||||
if err != nil {
|
||||
http.Error(w, "first group lookup error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
defer fgRows.Close()
|
||||
for fgRows.Next() {
|
||||
var g string
|
||||
if err := fgRows.Scan(&g); err != nil {
|
||||
var code string
|
||||
var title string
|
||||
if err := fgRows.Scan(&code, &title); err != nil {
|
||||
http.Error(w, "first group scan error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
g = strings.TrimSpace(g)
|
||||
if g != "" {
|
||||
allGroups = append(allGroups, g)
|
||||
code = strings.TrimSpace(code)
|
||||
title = strings.TrimSpace(title)
|
||||
if code != "" {
|
||||
allCodes = append(allCodes, code)
|
||||
if _, ok := titleByCode[code]; !ok {
|
||||
titleByCode[code] = title
|
||||
}
|
||||
}
|
||||
}
|
||||
if err := fgRows.Err(); err != nil {
|
||||
http.Error(w, "first group rows error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
sort.Strings(allGroups)
|
||||
allCodes = normalizeIDList(allCodes)
|
||||
|
||||
rows, err := pg.Query(queries.GetPricingFirstGroupMailMappingRows)
|
||||
if err != nil {
|
||||
@@ -239,9 +308,11 @@ func GetPricingFirstGroupMailMappingsHandler(pg *sql.DB) http.HandlerFunc {
|
||||
defer rows.Close()
|
||||
|
||||
byGroup := map[string]*models.FirstGroupMailMappingRow{}
|
||||
for _, g := range allGroups {
|
||||
byGroup[g] = &models.FirstGroupMailMappingRow{
|
||||
UrunIlkGrubu: g,
|
||||
for _, code := range allCodes {
|
||||
byGroup[code] = &models.FirstGroupMailMappingRow{
|
||||
UrunIlkGrubu: code,
|
||||
GroupCode: code,
|
||||
GroupTitle: titleByCode[code],
|
||||
MailIDs: make([]string, 0, 8),
|
||||
Mails: make([]models.FirstGroupMailOption, 0, 8),
|
||||
}
|
||||
@@ -256,19 +327,21 @@ func GetPricingFirstGroupMailMappingsHandler(pg *sql.DB) http.HandlerFunc {
|
||||
http.Error(w, "mapping scan error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
g := strings.TrimSpace(group.String)
|
||||
if g == "" {
|
||||
code := strings.TrimSpace(group.String)
|
||||
if code == "" {
|
||||
continue
|
||||
}
|
||||
row, ok := byGroup[g]
|
||||
row, ok := byGroup[code]
|
||||
if !ok {
|
||||
row = &models.FirstGroupMailMappingRow{
|
||||
UrunIlkGrubu: g,
|
||||
UrunIlkGrubu: code,
|
||||
GroupCode: code,
|
||||
GroupTitle: titleByCode[code],
|
||||
MailIDs: make([]string, 0, 8),
|
||||
Mails: make([]models.FirstGroupMailOption, 0, 8),
|
||||
}
|
||||
byGroup[g] = row
|
||||
allGroups = append(allGroups, g)
|
||||
byGroup[code] = row
|
||||
allCodes = append(allCodes, code)
|
||||
}
|
||||
if mailID.Valid && strings.TrimSpace(mailID.String) != "" {
|
||||
id := strings.TrimSpace(mailID.String)
|
||||
@@ -285,11 +358,14 @@ func GetPricingFirstGroupMailMappingsHandler(pg *sql.DB) http.HandlerFunc {
|
||||
return
|
||||
}
|
||||
|
||||
sort.Strings(allGroups)
|
||||
out := make([]models.FirstGroupMailMappingRow, 0, len(allGroups))
|
||||
for _, g := range allGroups {
|
||||
if r := byGroup[g]; r != nil {
|
||||
allCodes = normalizeIDList(allCodes)
|
||||
out := make([]models.FirstGroupMailMappingRow, 0, len(allCodes))
|
||||
for _, code := range allCodes {
|
||||
if r := byGroup[code]; r != nil {
|
||||
r.MailIDs = normalizeIDList(r.MailIDs)
|
||||
if strings.TrimSpace(r.GroupTitle) == "" {
|
||||
r.GroupTitle = titleByCode[code]
|
||||
}
|
||||
out = append(out, *r)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user