189 lines
8.3 KiB
Go
189 lines
8.3 KiB
Go
package queries
|
|
|
|
import (
|
|
"database/sql"
|
|
"fmt"
|
|
)
|
|
|
|
func EnsurePricingCalcInfraTables(pg *sql.DB) error {
|
|
stmts := []string{
|
|
`
|
|
CREATE TABLE IF NOT EXISTS mk_fx_rate_cache (
|
|
rate_date DATE PRIMARY KEY,
|
|
usd_try NUMERIC(18,6) NOT NULL DEFAULT 0,
|
|
eur_try NUMERIC(18,6) NOT NULL DEFAULT 0,
|
|
usd_eur NUMERIC(18,6) NOT NULL DEFAULT 0,
|
|
source_system TEXT NOT NULL DEFAULT 'MSSQL',
|
|
source_updated_at TIMESTAMPTZ,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
|
|
)`,
|
|
`CREATE INDEX IF NOT EXISTS ix_mk_fx_rate_cache_updated_at ON mk_fx_rate_cache (updated_at DESC)`,
|
|
`
|
|
CREATE TABLE IF NOT EXISTS mk_price_snapshot (
|
|
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
product_code TEXT NOT NULL,
|
|
pricing_parameter_id BIGINT REFERENCES mk_urunpricingprmtr(id) ON DELETE CASCADE,
|
|
rule_id UUID REFERENCES mk_pricing_rule(id) ON DELETE SET NULL,
|
|
strategy_code TEXT NOT NULL DEFAULT 'CORE',
|
|
anchor_mode TEXT NOT NULL DEFAULT 'USD',
|
|
fx_date DATE NOT NULL,
|
|
cost_date DATE,
|
|
base_price_try NUMERIC(18,6) NOT NULL DEFAULT 0,
|
|
base_price_usd NUMERIC(18,6) NOT NULL DEFAULT 0,
|
|
try1 NUMERIC(18,6) NOT NULL DEFAULT 0,
|
|
try2 NUMERIC(18,6) NOT NULL DEFAULT 0,
|
|
try3 NUMERIC(18,6) NOT NULL DEFAULT 0,
|
|
try4 NUMERIC(18,6) NOT NULL DEFAULT 0,
|
|
try5 NUMERIC(18,6) NOT NULL DEFAULT 0,
|
|
try6 NUMERIC(18,6) NOT NULL DEFAULT 0,
|
|
usd1 NUMERIC(18,6) NOT NULL DEFAULT 0,
|
|
usd2 NUMERIC(18,6) NOT NULL DEFAULT 0,
|
|
usd3 NUMERIC(18,6) NOT NULL DEFAULT 0,
|
|
usd4 NUMERIC(18,6) NOT NULL DEFAULT 0,
|
|
usd5 NUMERIC(18,6) NOT NULL DEFAULT 0,
|
|
usd6 NUMERIC(18,6) NOT NULL DEFAULT 0,
|
|
eur1 NUMERIC(18,6) NOT NULL DEFAULT 0,
|
|
eur2 NUMERIC(18,6) NOT NULL DEFAULT 0,
|
|
eur3 NUMERIC(18,6) NOT NULL DEFAULT 0,
|
|
eur4 NUMERIC(18,6) NOT NULL DEFAULT 0,
|
|
eur5 NUMERIC(18,6) NOT NULL DEFAULT 0,
|
|
eur6 NUMERIC(18,6) NOT NULL DEFAULT 0,
|
|
calc_hash TEXT NOT NULL DEFAULT '',
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
CONSTRAINT uq_mk_price_snapshot_product_scope UNIQUE (product_code, pricing_parameter_id),
|
|
CONSTRAINT ck_mk_price_snapshot_strategy_code CHECK (strategy_code IN ('CORE','PREMIUM','SARTORIAL')),
|
|
CONSTRAINT ck_mk_price_snapshot_anchor_mode CHECK (anchor_mode IN ('TRY','USD'))
|
|
)`,
|
|
`CREATE INDEX IF NOT EXISTS ix_mk_price_snapshot_rule ON mk_price_snapshot (rule_id)`,
|
|
`CREATE INDEX IF NOT EXISTS ix_mk_price_snapshot_updated_at ON mk_price_snapshot (updated_at DESC)`,
|
|
`
|
|
CREATE TABLE IF NOT EXISTS mk_price_target_map_pg (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
currency TEXT NOT NULL,
|
|
level_no SMALLINT NOT NULL,
|
|
sdprcgrp_id INTEGER,
|
|
description TEXT NOT NULL DEFAULT '',
|
|
is_active BOOLEAN NOT NULL DEFAULT TRUE,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
CONSTRAINT uq_mk_price_target_map_pg UNIQUE (currency, level_no),
|
|
CONSTRAINT ck_mk_price_target_map_pg_currency CHECK (currency IN ('TRY','USD','EUR')),
|
|
CONSTRAINT ck_mk_price_target_map_pg_level_no CHECK (level_no BETWEEN 1 AND 6)
|
|
)`,
|
|
`CREATE INDEX IF NOT EXISTS ix_mk_price_target_map_pg_active ON mk_price_target_map_pg (is_active, currency, level_no)`,
|
|
`
|
|
CREATE TABLE IF NOT EXISTS mk_price_target_map_nebim (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
currency TEXT NOT NULL,
|
|
level_no SMALLINT NOT NULL,
|
|
price_group_code TEXT NOT NULL DEFAULT '',
|
|
description TEXT NOT NULL DEFAULT '',
|
|
is_active BOOLEAN NOT NULL DEFAULT TRUE,
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
CONSTRAINT uq_mk_price_target_map_nebim UNIQUE (currency, level_no),
|
|
CONSTRAINT ck_mk_price_target_map_nebim_currency CHECK (currency IN ('TRY','USD','EUR')),
|
|
CONSTRAINT ck_mk_price_target_map_nebim_level_no CHECK (level_no BETWEEN 1 AND 6)
|
|
)`,
|
|
`CREATE INDEX IF NOT EXISTS ix_mk_price_target_map_nebim_active ON mk_price_target_map_nebim (is_active, currency, level_no)`,
|
|
`
|
|
CREATE TABLE IF NOT EXISTS mk_price_recalc_queue (
|
|
id BIGSERIAL PRIMARY KEY,
|
|
product_code TEXT NOT NULL,
|
|
pricing_parameter_id BIGINT REFERENCES mk_urunpricingprmtr(id) ON DELETE SET NULL,
|
|
reason TEXT NOT NULL DEFAULT '',
|
|
status TEXT NOT NULL DEFAULT 'pending',
|
|
attempts SMALLINT NOT NULL DEFAULT 0,
|
|
available_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
queued_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
processed_at TIMESTAMPTZ,
|
|
last_error TEXT NOT NULL DEFAULT '',
|
|
created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
CONSTRAINT ck_mk_price_recalc_queue_status CHECK (status IN ('pending','processing','done','failed'))
|
|
)`,
|
|
`CREATE INDEX IF NOT EXISTS ix_mk_price_recalc_queue_status ON mk_price_recalc_queue (status, available_at, queued_at)`,
|
|
`CREATE UNIQUE INDEX IF NOT EXISTS uq_mk_price_recalc_queue_pending ON mk_price_recalc_queue (product_code, COALESCE(pricing_parameter_id, 0)) WHERE status IN ('pending','processing')`,
|
|
`
|
|
CREATE TABLE IF NOT EXISTS mk_mmitem_dim_combo (
|
|
product_code TEXT NOT NULL,
|
|
dim1 INTEGER NOT NULL,
|
|
dim3 INTEGER,
|
|
dim3_key INTEGER GENERATED ALWAYS AS (COALESCE(dim3, 0)) STORED,
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
CONSTRAINT pk_mk_mmitem_dim_combo PRIMARY KEY (product_code, dim1, dim3_key)
|
|
)`,
|
|
`CREATE INDEX IF NOT EXISTS ix_mk_mmitem_dim_combo_product ON mk_mmitem_dim_combo (product_code, updated_at DESC)`,
|
|
`
|
|
CREATE TABLE IF NOT EXISTS mk_dim_token_map (
|
|
dim_column TEXT NOT NULL, -- dimval1 or dimval3
|
|
token TEXT NOT NULL, -- normalized token (e.g. "001", "82", etc.)
|
|
dim_id INTEGER NOT NULL,
|
|
updated_at TIMESTAMPTZ NOT NULL DEFAULT now(),
|
|
CONSTRAINT pk_mk_dim_token_map PRIMARY KEY (dim_column, token)
|
|
)`,
|
|
`CREATE INDEX IF NOT EXISTS ix_mk_dim_token_map_updated ON mk_dim_token_map (updated_at DESC)`,
|
|
}
|
|
|
|
for _, stmt := range stmts {
|
|
if _, err := pg.Exec(stmt); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
if err := seedPricingTargetMapRows(pg, "mk_price_target_map_pg", "sdprcgrp_id"); err != nil {
|
|
return err
|
|
}
|
|
if err := seedPricingTargetMapRows(pg, "mk_price_target_map_nebim", "price_group_code"); err != nil {
|
|
return err
|
|
}
|
|
|
|
// Repair invalid/missing pg target mappings after manual edits or table resets.
|
|
// sdprcgrp_id is expected to be 1..6 in this installation.
|
|
if _, err := pg.Exec(`
|
|
UPDATE mk_price_target_map_pg
|
|
SET sdprcgrp_id = level_no,
|
|
updated_at = now()
|
|
WHERE is_active = TRUE
|
|
AND (sdprcgrp_id IS NULL OR sdprcgrp_id NOT BETWEEN 1 AND 6)
|
|
`); err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func seedPricingTargetMapRows(pg *sql.DB, tableName string, valueColumn string) error {
|
|
currencies := []string{"TRY", "USD", "EUR"}
|
|
for _, currency := range currencies {
|
|
for level := 1; level <= 6; level++ {
|
|
stmt := fmt.Sprintf(`
|
|
INSERT INTO %s (currency, level_no, %s, description, is_active, created_at, updated_at)
|
|
VALUES ($1, $2, NULL, '', TRUE, now(), now())
|
|
ON CONFLICT (currency, level_no) DO NOTHING
|
|
`, tableName, valueColumn)
|
|
// PG targets: default sdprcgrp_id = level_no (1..6). This keeps sdprc writes valid after resets.
|
|
if tableName == "mk_price_target_map_pg" && valueColumn == "sdprcgrp_id" {
|
|
stmt = fmt.Sprintf(`
|
|
INSERT INTO %s (currency, level_no, %s, description, is_active, created_at, updated_at)
|
|
VALUES ($1, $2, $2, '', TRUE, now(), now())
|
|
ON CONFLICT (currency, level_no) DO NOTHING
|
|
`, tableName, valueColumn)
|
|
}
|
|
if valueColumn == "price_group_code" {
|
|
stmt = fmt.Sprintf(`
|
|
INSERT INTO %s (currency, level_no, %s, description, is_active, created_at, updated_at)
|
|
VALUES ($1, $2, '', '', TRUE, now(), now())
|
|
ON CONFLICT (currency, level_no) DO NOTHING
|
|
`, tableName, valueColumn)
|
|
}
|
|
if _, err := pg.Exec(stmt, currency, level); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
return nil
|
|
}
|