Merge remote-tracking branch 'origin/master'

This commit is contained in:
M_Kececi
2026-06-04 14:55:42 +03:00
parent 7b1588d69d
commit 6aea7f4012
4 changed files with 130 additions and 93 deletions

View File

@@ -591,7 +591,8 @@ SELECT
COALESCE(tx.m4, 0)::float8,
COALESCE(tx.m5, 0)::float8,
COALESCE(tx.m6, 0)::float8,
COALESCE(tr.step, 0)::float8,
COALESCE(NULLIF(tr.wholesale_step, 0), tr.step, 0)::float8,
COALESCE(NULLIF(tr.retail_step, 0), tr.step, 0)::float8,
COALESCE(ux.base_mult, 0)::float8,
COALESCE(ux.m1, 0)::float8,
@@ -600,7 +601,8 @@ SELECT
COALESCE(ux.m4, 0)::float8,
COALESCE(ux.m5, 0)::float8,
COALESCE(ux.m6, 0)::float8,
COALESCE(ur.step, 0)::float8,
COALESCE(NULLIF(ur.wholesale_step, 0), ur.step, 0)::float8,
COALESCE(NULLIF(ur.retail_step, 0), ur.step, 0)::float8,
COALESCE(ex.base_mult, 0)::float8,
COALESCE(ex.m1, 0)::float8,
@@ -609,7 +611,8 @@ SELECT
COALESCE(ex.m4, 0)::float8,
COALESCE(ex.m5, 0)::float8,
COALESCE(ex.m6, 0)::float8,
COALESCE(er.step, 0)::float8
COALESCE(NULLIF(er.wholesale_step, 0), er.step, 0)::float8,
COALESCE(NULLIF(er.retail_step, 0), er.step, 0)::float8
FROM mk_urunpricingprmtr p
LEFT JOIN LATERAL (
SELECT latest_rule.*
@@ -656,9 +659,9 @@ ORDER BY
&item.BrandGroupSec,
&rule.ID,
&rule.IsActive,
&rule.TryBase, &rule.Try1, &rule.Try2, &rule.Try3, &rule.Try4, &rule.Try5, &rule.Try6, &rule.TryStep,
&rule.UsdBase, &rule.Usd1, &rule.Usd2, &rule.Usd3, &rule.Usd4, &rule.Usd5, &rule.Usd6, &rule.UsdStep,
&rule.EurBase, &rule.Eur1, &rule.Eur2, &rule.Eur3, &rule.Eur4, &rule.Eur5, &rule.Eur6, &rule.EurStep,
&rule.TryBase, &rule.Try1, &rule.Try2, &rule.Try3, &rule.Try4, &rule.Try5, &rule.Try6, &rule.TryWholesaleStep, &rule.TryRetailStep,
&rule.UsdBase, &rule.Usd1, &rule.Usd2, &rule.Usd3, &rule.Usd4, &rule.Usd5, &rule.Usd6, &rule.UsdWholesaleStep, &rule.UsdRetailStep,
&rule.EurBase, &rule.Eur1, &rule.Eur2, &rule.Eur3, &rule.Eur4, &rule.Eur5, &rule.Eur6, &rule.EurWholesaleStep, &rule.EurRetailStep,
); err != nil {
return nil, err
}

View File

@@ -13,7 +13,7 @@ import (
// Rule tables:
// - mk_pricing_rule: the "scope" (filters) to which multipliers/roundings apply.
// - mk_pricex: per-currency multipliers (base + 1..6).
// - mk_priceroll: per-currency rounding step (ceil to step).
// - mk_priceroll: per-currency rounding steps for wholesale (1-5) and retail (6+).
func EnsurePricingRuleTables(pg *sql.DB) error {
stmts := []string{
@@ -58,10 +58,15 @@ CREATE TABLE IF NOT EXISTS mk_priceroll (
rule_id UUID NOT NULL REFERENCES mk_pricing_rule(id) ON DELETE CASCADE,
currency TEXT NOT NULL CHECK (currency IN ('TRY','USD','EUR')),
step NUMERIC(18,6) NOT NULL DEFAULT 0,
wholesale_step NUMERIC(18,6) NOT NULL DEFAULT 0,
retail_step NUMERIC(18,6) NOT NULL DEFAULT 0,
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
PRIMARY KEY (rule_id, currency)
)`,
`ALTER TABLE mk_priceroll ADD COLUMN IF NOT EXISTS wholesale_step NUMERIC(18,6) NOT NULL DEFAULT 0`,
`ALTER TABLE mk_priceroll ADD COLUMN IF NOT EXISTS retail_step NUMERIC(18,6) NOT NULL DEFAULT 0`,
`UPDATE mk_priceroll SET wholesale_step = step, retail_step = step WHERE step <> 0 AND wholesale_step = 0 AND retail_step = 0`,
`CREATE INDEX IF NOT EXISTS ix_mk_priceroll_currency ON mk_priceroll (currency)`,
}
for _, s := range stmts {
@@ -90,32 +95,35 @@ type PricingRuleRow struct {
IsActive bool `json:"is_active"`
// multipliers/rolls are per currency
TryBase float64 `json:"try_base"`
Try1 float64 `json:"try1"`
Try2 float64 `json:"try2"`
Try3 float64 `json:"try3"`
Try4 float64 `json:"try4"`
Try5 float64 `json:"try5"`
Try6 float64 `json:"try6"`
TryStep float64 `json:"try_step"`
TryBase float64 `json:"try_base"`
Try1 float64 `json:"try1"`
Try2 float64 `json:"try2"`
Try3 float64 `json:"try3"`
Try4 float64 `json:"try4"`
Try5 float64 `json:"try5"`
Try6 float64 `json:"try6"`
TryWholesaleStep float64 `json:"try_wholesale_step"`
TryRetailStep float64 `json:"try_retail_step"`
UsdBase float64 `json:"usd_base"`
Usd1 float64 `json:"usd1"`
Usd2 float64 `json:"usd2"`
Usd3 float64 `json:"usd3"`
Usd4 float64 `json:"usd4"`
Usd5 float64 `json:"usd5"`
Usd6 float64 `json:"usd6"`
UsdStep float64 `json:"usd_step"`
UsdBase float64 `json:"usd_base"`
Usd1 float64 `json:"usd1"`
Usd2 float64 `json:"usd2"`
Usd3 float64 `json:"usd3"`
Usd4 float64 `json:"usd4"`
Usd5 float64 `json:"usd5"`
Usd6 float64 `json:"usd6"`
UsdWholesaleStep float64 `json:"usd_wholesale_step"`
UsdRetailStep float64 `json:"usd_retail_step"`
EurBase float64 `json:"eur_base"`
Eur1 float64 `json:"eur1"`
Eur2 float64 `json:"eur2"`
Eur3 float64 `json:"eur3"`
Eur4 float64 `json:"eur4"`
Eur5 float64 `json:"eur5"`
Eur6 float64 `json:"eur6"`
EurStep float64 `json:"eur_step"`
EurBase float64 `json:"eur_base"`
Eur1 float64 `json:"eur1"`
Eur2 float64 `json:"eur2"`
Eur3 float64 `json:"eur3"`
Eur4 float64 `json:"eur4"`
Eur5 float64 `json:"eur5"`
Eur6 float64 `json:"eur6"`
EurWholesaleStep float64 `json:"eur_wholesale_step"`
EurRetailStep float64 `json:"eur_retail_step"`
}
type PricingRuleSaveItem struct {
@@ -135,32 +143,35 @@ type PricingRuleSaveItem struct {
IsActive bool `json:"is_active"`
TryBase float64 `json:"try_base"`
Try1 float64 `json:"try1"`
Try2 float64 `json:"try2"`
Try3 float64 `json:"try3"`
Try4 float64 `json:"try4"`
Try5 float64 `json:"try5"`
Try6 float64 `json:"try6"`
TryStep float64 `json:"try_step"`
TryBase float64 `json:"try_base"`
Try1 float64 `json:"try1"`
Try2 float64 `json:"try2"`
Try3 float64 `json:"try3"`
Try4 float64 `json:"try4"`
Try5 float64 `json:"try5"`
Try6 float64 `json:"try6"`
TryWholesaleStep float64 `json:"try_wholesale_step"`
TryRetailStep float64 `json:"try_retail_step"`
UsdBase float64 `json:"usd_base"`
Usd1 float64 `json:"usd1"`
Usd2 float64 `json:"usd2"`
Usd3 float64 `json:"usd3"`
Usd4 float64 `json:"usd4"`
Usd5 float64 `json:"usd5"`
Usd6 float64 `json:"usd6"`
UsdStep float64 `json:"usd_step"`
UsdBase float64 `json:"usd_base"`
Usd1 float64 `json:"usd1"`
Usd2 float64 `json:"usd2"`
Usd3 float64 `json:"usd3"`
Usd4 float64 `json:"usd4"`
Usd5 float64 `json:"usd5"`
Usd6 float64 `json:"usd6"`
UsdWholesaleStep float64 `json:"usd_wholesale_step"`
UsdRetailStep float64 `json:"usd_retail_step"`
EurBase float64 `json:"eur_base"`
Eur1 float64 `json:"eur1"`
Eur2 float64 `json:"eur2"`
Eur3 float64 `json:"eur3"`
Eur4 float64 `json:"eur4"`
Eur5 float64 `json:"eur5"`
Eur6 float64 `json:"eur6"`
EurStep float64 `json:"eur_step"`
EurBase float64 `json:"eur_base"`
Eur1 float64 `json:"eur1"`
Eur2 float64 `json:"eur2"`
Eur3 float64 `json:"eur3"`
Eur4 float64 `json:"eur4"`
Eur5 float64 `json:"eur5"`
Eur6 float64 `json:"eur6"`
EurWholesaleStep float64 `json:"eur_wholesale_step"`
EurRetailStep float64 `json:"eur_retail_step"`
}
func ListPricingRules(ctx context.Context, pg *sql.DB) ([]PricingRuleRow, error) {
@@ -188,7 +199,8 @@ SELECT
COALESCE(tx.m4, 0)::float8 AS try4,
COALESCE(tx.m5, 0)::float8 AS try5,
COALESCE(tx.m6, 0)::float8 AS try6,
COALESCE(tr.step, 0)::float8 AS try_step,
COALESCE(NULLIF(tr.wholesale_step, 0), tr.step, 0)::float8 AS try_wholesale_step,
COALESCE(NULLIF(tr.retail_step, 0), tr.step, 0)::float8 AS try_retail_step,
COALESCE(ux.base_mult, 0)::float8 AS usd_base,
COALESCE(ux.m1, 0)::float8 AS usd1,
@@ -197,7 +209,8 @@ SELECT
COALESCE(ux.m4, 0)::float8 AS usd4,
COALESCE(ux.m5, 0)::float8 AS usd5,
COALESCE(ux.m6, 0)::float8 AS usd6,
COALESCE(ur.step, 0)::float8 AS usd_step,
COALESCE(NULLIF(ur.wholesale_step, 0), ur.step, 0)::float8 AS usd_wholesale_step,
COALESCE(NULLIF(ur.retail_step, 0), ur.step, 0)::float8 AS usd_retail_step,
COALESCE(ex.base_mult, 0)::float8 AS eur_base,
COALESCE(ex.m1, 0)::float8 AS eur1,
@@ -206,7 +219,8 @@ SELECT
COALESCE(ex.m4, 0)::float8 AS eur4,
COALESCE(ex.m5, 0)::float8 AS eur5,
COALESCE(ex.m6, 0)::float8 AS eur6,
COALESCE(er.step, 0)::float8 AS eur_step
COALESCE(NULLIF(er.wholesale_step, 0), er.step, 0)::float8 AS eur_wholesale_step,
COALESCE(NULLIF(er.retail_step, 0), er.step, 0)::float8 AS eur_retail_step
FROM mk_pricing_rule r
LEFT JOIN mk_pricex tx ON tx.rule_id = r.id AND tx.currency='TRY'
LEFT JOIN mk_pricex ux ON ux.rule_id = r.id AND ux.currency='USD'
@@ -240,9 +254,9 @@ ORDER BY r.created_at DESC;
pq.Array(&r.BrandGroupSec),
&r.IsActive,
&r.TryBase, &r.Try1, &r.Try2, &r.Try3, &r.Try4, &r.Try5, &r.Try6, &r.TryStep,
&r.UsdBase, &r.Usd1, &r.Usd2, &r.Usd3, &r.Usd4, &r.Usd5, &r.Usd6, &r.UsdStep,
&r.EurBase, &r.Eur1, &r.Eur2, &r.Eur3, &r.Eur4, &r.Eur5, &r.Eur6, &r.EurStep,
&r.TryBase, &r.Try1, &r.Try2, &r.Try3, &r.Try4, &r.Try5, &r.Try6, &r.TryWholesaleStep, &r.TryRetailStep,
&r.UsdBase, &r.Usd1, &r.Usd2, &r.Usd3, &r.Usd4, &r.Usd5, &r.Usd6, &r.UsdWholesaleStep, &r.UsdRetailStep,
&r.EurBase, &r.Eur1, &r.Eur2, &r.Eur3, &r.Eur4, &r.Eur5, &r.Eur6, &r.EurWholesaleStep, &r.EurRetailStep,
); err != nil {
return nil, err
}
@@ -357,33 +371,35 @@ ON CONFLICT (rule_id, currency) DO UPDATE SET
`, id, cur, base, m1, m2, m3, m4, m5, m6)
return err
}
upsertRoll := func(cur string, step float64) error {
upsertRoll := func(cur string, wholesaleStep, retailStep float64) error {
_, err := tx.ExecContext(ctx, `
INSERT INTO mk_priceroll (rule_id, currency, step, created_at, updated_at)
VALUES ($1,$2,$3,now(),now())
INSERT INTO mk_priceroll (rule_id, currency, step, wholesale_step, retail_step, created_at, updated_at)
VALUES ($1,$2,$3,$4,$5,now(),now())
ON CONFLICT (rule_id, currency) DO UPDATE SET
step=EXCLUDED.step,
wholesale_step=EXCLUDED.wholesale_step,
retail_step=EXCLUDED.retail_step,
updated_at=now()
`, id, cur, step)
`, id, cur, wholesaleStep, wholesaleStep, retailStep)
return err
}
if err := upsertX("TRY", item.TryBase, item.Try1, item.Try2, item.Try3, item.Try4, item.Try5, item.Try6); err != nil {
return "", err
}
if err := upsertRoll("TRY", item.TryStep); err != nil {
if err := upsertRoll("TRY", item.TryWholesaleStep, item.TryRetailStep); err != nil {
return "", err
}
if err := upsertX("USD", item.UsdBase, item.Usd1, item.Usd2, item.Usd3, item.Usd4, item.Usd5, item.Usd6); err != nil {
return "", err
}
if err := upsertRoll("USD", item.UsdStep); err != nil {
if err := upsertRoll("USD", item.UsdWholesaleStep, item.UsdRetailStep); err != nil {
return "", err
}
if err := upsertX("EUR", item.EurBase, item.Eur1, item.Eur2, item.Eur3, item.Eur4, item.Eur5, item.Eur6); err != nil {
return "", err
}
if err := upsertRoll("EUR", item.EurStep); err != nil {
if err := upsertRoll("EUR", item.EurWholesaleStep, item.EurRetailStep); err != nil {
return "", err
}

View File

@@ -63,7 +63,7 @@ func SavePricingRulesBulkHandler(pg *sql.DB) http.HandlerFunc {
updated := 0
for _, it := range payload.Items {
// Zero means that no rounding rule has been configured yet.
if it.TryStep < 0 || it.UsdStep < 0 || it.EurStep < 0 {
if it.TryWholesaleStep < 0 || it.TryRetailStep < 0 || it.UsdWholesaleStep < 0 || it.UsdRetailStep < 0 || it.EurWholesaleStep < 0 || it.EurRetailStep < 0 {
http.Error(w, "invalid rounding step", http.StatusBadRequest)
return
}
@@ -188,9 +188,9 @@ func filterPricingRuleExportRows(rows []queries.PricingParameterRuleRow, r *http
}
fields := []string{
"try_base", "try1", "try2", "try3", "try4", "try5", "try6", "try_step",
"usd_base", "usd1", "usd2", "usd3", "usd4", "usd5", "usd6", "usd_step",
"eur_base", "eur1", "eur2", "eur3", "eur4", "eur5", "eur6", "eur_step",
"try_base", "try1", "try2", "try3", "try4", "try5", "try6", "try_wholesale_step", "try_retail_step",
"usd_base", "usd1", "usd2", "usd3", "usd4", "usd5", "usd6", "usd_wholesale_step", "usd_retail_step",
"eur_base", "eur1", "eur2", "eur3", "eur4", "eur5", "eur6", "eur_wholesale_step", "eur_retail_step",
}
minMap := map[string]*float64{}
maxMap := map[string]*float64{}
@@ -238,8 +238,10 @@ func pricingRuleNumericValue(row queries.PricingParameterRuleRow, field string)
return row.Rule.Try5
case "try6":
return row.Rule.Try6
case "try_step":
return row.Rule.TryStep
case "try_wholesale_step":
return row.Rule.TryWholesaleStep
case "try_retail_step":
return row.Rule.TryRetailStep
case "usd_base":
return row.Rule.UsdBase
case "usd1":
@@ -254,8 +256,10 @@ func pricingRuleNumericValue(row queries.PricingParameterRuleRow, field string)
return row.Rule.Usd5
case "usd6":
return row.Rule.Usd6
case "usd_step":
return row.Rule.UsdStep
case "usd_wholesale_step":
return row.Rule.UsdWholesaleStep
case "usd_retail_step":
return row.Rule.UsdRetailStep
case "eur_base":
return row.Rule.EurBase
case "eur1":
@@ -270,8 +274,10 @@ func pricingRuleNumericValue(row queries.PricingParameterRuleRow, field string)
return row.Rule.Eur5
case "eur6":
return row.Rule.Eur6
case "eur_step":
return row.Rule.EurStep
case "eur_wholesale_step":
return row.Rule.EurWholesaleStep
case "eur_retail_step":
return row.Rule.EurRetailStep
default:
return 0
}
@@ -356,9 +362,9 @@ func buildPricingRuleCSV(rows []queries.PricingParameterRuleRow) string {
headers := []string{
"DURUM", "AKTIF", "ASKILI YAN", "KATEGORI", "URUN ILK GRUBU", "URUN ANA GRUBU", "URUN ALT GRUBU",
"ICERIK", "MARKA", "BRAND CODE", "MARKA GRUBU",
"TRY YUVARLAMA", "TRY TABAN", "TRY 1", "TRY 2", "TRY 3", "TRY 4", "TRY 5", "TRY 6",
"USD YUVARLAMA", "USD TABAN", "USD 1", "USD 2", "USD 3", "USD 4", "USD 5", "USD 6",
"EUR YUVARLAMA", "EUR TABAN", "EUR 1", "EUR 2", "EUR 3", "EUR 4", "EUR 5", "EUR 6",
"TRY TOPTAN YUVARLAMA", "TRY PERAKENDE YUVARLAMA", "TRY TABAN", "TRY 1", "TRY 2", "TRY 3", "TRY 4", "TRY 5", "TRY 6",
"USD TOPTAN YUVARLAMA", "USD PERAKENDE YUVARLAMA", "USD TABAN", "USD 1", "USD 2", "USD 3", "USD 4", "USD 5", "USD 6",
"EUR TOPTAN YUVARLAMA", "EUR PERAKENDE YUVARLAMA", "EUR TABAN", "EUR 1", "EUR 2", "EUR 3", "EUR 4", "EUR 5", "EUR 6",
}
var b strings.Builder
for i, h := range headers {
@@ -386,7 +392,8 @@ func buildPricingRuleCSV(rows []queries.PricingParameterRuleRow) string {
row.Marka,
row.BrandCode,
row.BrandGroupSec,
fmt.Sprintf("%.2f", pricingRuleNumericValue(row, "try_step")),
fmt.Sprintf("%.2f", pricingRuleNumericValue(row, "try_wholesale_step")),
fmt.Sprintf("%.2f", pricingRuleNumericValue(row, "try_retail_step")),
fmt.Sprintf("%.2f", pricingRuleNumericValue(row, "try_base")),
fmt.Sprintf("%.2f", pricingRuleNumericValue(row, "try1")),
fmt.Sprintf("%.2f", pricingRuleNumericValue(row, "try2")),
@@ -394,7 +401,8 @@ func buildPricingRuleCSV(rows []queries.PricingParameterRuleRow) string {
fmt.Sprintf("%.2f", pricingRuleNumericValue(row, "try4")),
fmt.Sprintf("%.2f", pricingRuleNumericValue(row, "try5")),
fmt.Sprintf("%.2f", pricingRuleNumericValue(row, "try6")),
fmt.Sprintf("%.2f", pricingRuleNumericValue(row, "usd_step")),
fmt.Sprintf("%.2f", pricingRuleNumericValue(row, "usd_wholesale_step")),
fmt.Sprintf("%.2f", pricingRuleNumericValue(row, "usd_retail_step")),
fmt.Sprintf("%.2f", pricingRuleNumericValue(row, "usd_base")),
fmt.Sprintf("%.2f", pricingRuleNumericValue(row, "usd1")),
fmt.Sprintf("%.2f", pricingRuleNumericValue(row, "usd2")),
@@ -402,7 +410,8 @@ func buildPricingRuleCSV(rows []queries.PricingParameterRuleRow) string {
fmt.Sprintf("%.2f", pricingRuleNumericValue(row, "usd4")),
fmt.Sprintf("%.2f", pricingRuleNumericValue(row, "usd5")),
fmt.Sprintf("%.2f", pricingRuleNumericValue(row, "usd6")),
fmt.Sprintf("%.2f", pricingRuleNumericValue(row, "eur_step")),
fmt.Sprintf("%.2f", pricingRuleNumericValue(row, "eur_wholesale_step")),
fmt.Sprintf("%.2f", pricingRuleNumericValue(row, "eur_retail_step")),
fmt.Sprintf("%.2f", pricingRuleNumericValue(row, "eur_base")),
fmt.Sprintf("%.2f", pricingRuleNumericValue(row, "eur1")),
fmt.Sprintf("%.2f", pricingRuleNumericValue(row, "eur2")),