增加统一倍率调整按钮
This commit is contained in:
1 parent
be655b6569
commit
4195525dc7
23 files changed
+750
-16
No files matched your search
@@ -16,6 +16,37 @@ ORDER BY provider, capability, id`
|
||||
|
||||
const GetBillingPriceRuleSQL = `SELECT id, provider, capability, req_key, variant_key, unit, standard_unit_price_fen, markup_multiplier, enabled, conditions, quantity_source, priority, note, source, parameter_dimensions, created_at::text, updated_at::text FROM public.billing_price_rules WHERE id = $1::text LIMIT 1`
|
||||
const UpdateBillingPriceRuleSQL = `UPDATE public.billing_price_rules SET markup_multiplier = CASE WHEN $2::text = '' THEN $3::numeric ELSE markup_multiplier END, parameter_dimensions = CASE WHEN $2::text = '' THEN parameter_dimensions ELSE (SELECT jsonb_agg(CASE WHEN dimension->>'key' = $2::text THEN jsonb_set(dimension, '{tiers}', (SELECT jsonb_agg(CASE WHEN tier->>'value' = $4::text THEN jsonb_set(tier, '{markupMultiplier}', to_jsonb($3::numeric), true) ELSE tier END) FROM jsonb_array_elements(dimension->'tiers') tier), true) ELSE dimension END) FROM jsonb_array_elements(parameter_dimensions) dimension) END, updated_at = now() WHERE id = $1::text RETURNING id, provider, capability, req_key, variant_key, unit, standard_unit_price_fen, markup_multiplier, enabled, conditions, quantity_source, priority, note, source, parameter_dimensions, created_at::text, updated_at::text`
|
||||
|
||||
// Lock every requested row first. If even one ID is absent, eligible is false
|
||||
// and this single statement updates none of them.
|
||||
const UpdateBillingPriceRulesSQL = `WITH locked AS MATERIALIZED (
|
||||
SELECT id FROM public.billing_price_rules WHERE id = ANY($1::text[]) FOR UPDATE
|
||||
), eligible AS MATERIALIZED (
|
||||
SELECT count(*) = cardinality($1::text[]) AS all_present FROM locked
|
||||
), updated AS (
|
||||
UPDATE public.billing_price_rules AS rule SET
|
||||
markup_multiplier = $2::numeric,
|
||||
parameter_dimensions = (
|
||||
SELECT COALESCE(jsonb_agg(
|
||||
jsonb_set(dimension.value, '{tiers}', (
|
||||
SELECT COALESCE(jsonb_agg(
|
||||
jsonb_set(tier.value, '{markupMultiplier}', to_jsonb($2::numeric), true)
|
||||
ORDER BY tier.position
|
||||
), '[]'::jsonb)
|
||||
FROM jsonb_array_elements(COALESCE(dimension.value->'tiers', '[]'::jsonb))
|
||||
WITH ORDINALITY AS tier(value, position)
|
||||
), true) ORDER BY dimension.position
|
||||
), '[]'::jsonb)
|
||||
FROM jsonb_array_elements(COALESCE(rule.parameter_dimensions, '[]'::jsonb))
|
||||
WITH ORDINALITY AS dimension(value, position)
|
||||
),
|
||||
updated_at = now()
|
||||
WHERE rule.id IN (SELECT id FROM locked) AND (SELECT all_present FROM eligible)
|
||||
RETURNING id, provider, capability, req_key, variant_key, unit, standard_unit_price_fen,
|
||||
markup_multiplier, enabled, conditions, quantity_source, priority, note, source,
|
||||
parameter_dimensions, created_at::text, updated_at::text
|
||||
)
|
||||
SELECT * FROM updated ORDER BY id`
|
||||
const GetBillingWalletSQL = `SELECT $1::text, COALESCE(balance_fen, 0), COALESCE(total_recharged_fen, 0), COALESCE(total_charged_fen, 0), COALESCE(updated_at::text, '') FROM public.billing_wallets WHERE organization_id = $1::text UNION ALL SELECT $1::text, 0, 0, 0, '' WHERE NOT EXISTS (SELECT 1 FROM public.billing_wallets WHERE organization_id = $1::text) LIMIT 1`
|
||||
const ListBillingWalletsSQL = `SELECT organization_id, balance_fen, total_recharged_fen, total_charged_fen, updated_at::text FROM public.billing_wallets ORDER BY updated_at DESC`
|
||||
const ListBillingLedgerSQL = `SELECT id, organization_id, COALESCE(account_id, ''), COALESCE(job_id, ''), kind, delta_fen, balance_after_fen, currency, idempotency_key, description, metadata, created_at::text FROM public.billing_ledger WHERE ($1::text = '' OR organization_id = $1::text) AND ($2::text = '' OR account_id = $2::text) ORDER BY created_at DESC LIMIT $3::integer`
|
||||
@@ -87,6 +118,31 @@ func (db *Database) UpdateBillingPriceRule(ctx context.Context, id string, patch
|
||||
rule, err := scanFullPriceRule(rows)
|
||||
return &rule, err
|
||||
}
|
||||
func (db *Database) UpdateBillingPriceRules(ctx context.Context, patch billing.BulkPricePatch) ([]billing.PriceRule, error) {
|
||||
if len(patch.RuleIDs) == 0 {
|
||||
return nil, billing.ErrPriceNotFound
|
||||
}
|
||||
rows, err := db.billingQuery(ctx, UpdateBillingPriceRulesSQL, patch.RuleIDs, patch.MarkupMultiplier)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer rows.Close()
|
||||
rules := make([]billing.PriceRule, 0, len(patch.RuleIDs))
|
||||
for rows.Next() {
|
||||
rule, err := scanFullPriceRule(rows)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rules = append(rules, rule)
|
||||
}
|
||||
if err := rows.Err(); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if len(rules) != len(patch.RuleIDs) {
|
||||
return nil, billing.ErrPriceNotFound
|
||||
}
|
||||
return rules, nil
|
||||
}
|
||||
func scanFullPriceRule(rows Rows) (billing.PriceRule, error) {
|
||||
var rule billing.PriceRule
|
||||
var req, variant, quantity, note sql.NullString
|
||||
|
||||
Reference in new issue
Block a user