🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
184 lines
7.0 KiB
PL/PgSQL
184 lines
7.0 KiB
PL/PgSQL
-- Add fee payment model options to organizations table
|
|
-- This determines whether customers pay the platform fee on top of the ticket price
|
|
-- or if the fee is absorbed into the ticket price
|
|
|
|
ALTER TABLE organizations
|
|
ADD COLUMN platform_fee_model VARCHAR(20) DEFAULT 'customer_pays',
|
|
ADD COLUMN absorb_fee_in_price BOOLEAN DEFAULT false;
|
|
|
|
-- Update fee_structures table to include the fee model
|
|
ALTER TABLE fee_structures
|
|
ADD COLUMN fee_model VARCHAR(20) DEFAULT 'customer_pays',
|
|
ADD COLUMN absorb_fee_in_price BOOLEAN DEFAULT false;
|
|
|
|
-- Add comments for clarity
|
|
COMMENT ON COLUMN organizations.platform_fee_model IS 'Fee payment model: customer_pays, absorbed_in_price';
|
|
COMMENT ON COLUMN organizations.absorb_fee_in_price IS 'Whether to hide fee by including it in the displayed ticket price';
|
|
COMMENT ON COLUMN fee_structures.fee_model IS 'Fee payment model: customer_pays, absorbed_in_price';
|
|
COMMENT ON COLUMN fee_structures.absorb_fee_in_price IS 'Whether to hide fee by including it in the displayed ticket price';
|
|
|
|
-- Update existing organizations with default fee model and actual BCT rates
|
|
UPDATE organizations
|
|
SET
|
|
platform_fee_model = 'customer_pays',
|
|
absorb_fee_in_price = false,
|
|
platform_fee_percentage = 0.025, -- 2.5% BCT platform fee
|
|
platform_fee_fixed = 150 -- $1.50 BCT platform fee
|
|
WHERE platform_fee_model IS NULL;
|
|
|
|
-- Update existing fee structure templates with actual rates
|
|
UPDATE fee_structures
|
|
SET
|
|
fee_model = 'customer_pays',
|
|
absorb_fee_in_price = false
|
|
WHERE fee_model IS NULL;
|
|
|
|
-- Update the default template to reflect actual BCT rates
|
|
UPDATE fee_structures
|
|
SET
|
|
fee_percentage = 0.025,
|
|
fee_fixed = 150,
|
|
description = 'BCT platform fee: 2.5% + $1.50 per transaction'
|
|
WHERE name = 'Standard Platform Fee' AND is_template = true;
|
|
|
|
-- Add new fee structure templates with absorbed fee model and correct BCT rates
|
|
INSERT INTO fee_structures (name, description, fee_type, fee_percentage, fee_fixed, fee_model, absorb_fee_in_price, is_template) VALUES
|
|
('All-Inclusive BCT Standard', 'BCT platform fee 2.5% + $1.50 included in ticket price', 'percentage_plus_fixed', 0.025, 150, 'absorbed_in_price', true, true),
|
|
('All-Inclusive Percentage Only', '2.5% fee included in ticket price', 'percentage', 0.025, 0, 'absorbed_in_price', true, true),
|
|
('All-Inclusive Fixed Only', '$1.50 fee included in ticket price', 'fixed', 0.0000, 150, 'absorbed_in_price', true, true),
|
|
('Premium All-Inclusive', 'Premium 3% + $2.00 fee included in ticket price', 'percentage_plus_fixed', 0.030, 200, 'absorbed_in_price', true, true);
|
|
|
|
-- Add template for Stripe fee structure (for reference/calculation)
|
|
INSERT INTO fee_structures (name, description, fee_type, fee_percentage, fee_fixed, fee_model, absorb_fee_in_price, is_template) VALUES
|
|
('Stripe Processing Fee', 'Stripe credit card processing: 2.99% + $0.30', 'percentage_plus_fixed', 0.0299, 30, 'customer_pays', false, true);
|
|
|
|
-- Add function to calculate the display price based on fee model
|
|
CREATE OR REPLACE FUNCTION calculate_display_price(
|
|
base_price DECIMAL,
|
|
fee_percentage DECIMAL DEFAULT 0.03,
|
|
fee_fixed INTEGER DEFAULT 30,
|
|
fee_type VARCHAR DEFAULT 'percentage_plus_fixed',
|
|
fee_model VARCHAR DEFAULT 'customer_pays'
|
|
) RETURNS DECIMAL AS $$
|
|
DECLARE
|
|
platform_fee DECIMAL;
|
|
display_price DECIMAL;
|
|
BEGIN
|
|
-- Calculate platform fee based on fee type
|
|
CASE fee_type
|
|
WHEN 'percentage' THEN
|
|
platform_fee := base_price * fee_percentage;
|
|
WHEN 'fixed' THEN
|
|
platform_fee := fee_fixed / 100.0; -- Convert cents to dollars
|
|
WHEN 'percentage_plus_fixed' THEN
|
|
platform_fee := (base_price * fee_percentage) + (fee_fixed / 100.0);
|
|
ELSE
|
|
platform_fee := (base_price * fee_percentage) + (fee_fixed / 100.0);
|
|
END CASE;
|
|
|
|
-- Calculate display price based on fee model
|
|
CASE fee_model
|
|
WHEN 'customer_pays' THEN
|
|
-- Customer pays base price + platform fee
|
|
display_price := base_price;
|
|
WHEN 'absorbed_in_price' THEN
|
|
-- Platform fee is absorbed into the display price
|
|
-- To maintain the same net revenue for organizer,
|
|
-- we need to increase the display price to cover the fee
|
|
display_price := base_price + platform_fee;
|
|
ELSE
|
|
display_price := base_price;
|
|
END CASE;
|
|
|
|
RETURN ROUND(display_price, 2);
|
|
END;
|
|
$$ LANGUAGE plpgsql;
|
|
|
|
-- Add function to calculate the total amount customer pays
|
|
CREATE OR REPLACE FUNCTION calculate_customer_total(
|
|
base_price DECIMAL,
|
|
fee_percentage DECIMAL DEFAULT 0.03,
|
|
fee_fixed INTEGER DEFAULT 30,
|
|
fee_type VARCHAR DEFAULT 'percentage_plus_fixed',
|
|
fee_model VARCHAR DEFAULT 'customer_pays'
|
|
) RETURNS DECIMAL AS $$
|
|
DECLARE
|
|
platform_fee DECIMAL;
|
|
customer_total DECIMAL;
|
|
BEGIN
|
|
-- Calculate platform fee based on fee type
|
|
CASE fee_type
|
|
WHEN 'percentage' THEN
|
|
platform_fee := base_price * fee_percentage;
|
|
WHEN 'fixed' THEN
|
|
platform_fee := fee_fixed / 100.0; -- Convert cents to dollars
|
|
WHEN 'percentage_plus_fixed' THEN
|
|
platform_fee := (base_price * fee_percentage) + (fee_fixed / 100.0);
|
|
ELSE
|
|
platform_fee := (base_price * fee_percentage) + (fee_fixed / 100.0);
|
|
END CASE;
|
|
|
|
-- Calculate total amount customer pays
|
|
CASE fee_model
|
|
WHEN 'customer_pays' THEN
|
|
-- Customer pays base price + platform fee separately
|
|
customer_total := base_price + platform_fee;
|
|
WHEN 'absorbed_in_price' THEN
|
|
-- Customer pays only the display price (fee is included)
|
|
customer_total := base_price;
|
|
ELSE
|
|
customer_total := base_price + platform_fee;
|
|
END CASE;
|
|
|
|
RETURN ROUND(customer_total, 2);
|
|
END;
|
|
$$ LANGUAGE plpgsql;
|
|
|
|
-- Add function to calculate organizer net with fee model
|
|
CREATE OR REPLACE FUNCTION calculate_organizer_net(
|
|
base_price DECIMAL,
|
|
fee_percentage DECIMAL DEFAULT 0.03,
|
|
fee_fixed INTEGER DEFAULT 30,
|
|
fee_type VARCHAR DEFAULT 'percentage_plus_fixed',
|
|
fee_model VARCHAR DEFAULT 'customer_pays'
|
|
) RETURNS DECIMAL AS $$
|
|
DECLARE
|
|
platform_fee DECIMAL;
|
|
organizer_net DECIMAL;
|
|
BEGIN
|
|
-- Calculate platform fee based on fee type
|
|
CASE fee_type
|
|
WHEN 'percentage' THEN
|
|
platform_fee := base_price * fee_percentage;
|
|
WHEN 'fixed' THEN
|
|
platform_fee := fee_fixed / 100.0; -- Convert cents to dollars
|
|
WHEN 'percentage_plus_fixed' THEN
|
|
platform_fee := (base_price * fee_percentage) + (fee_fixed / 100.0);
|
|
ELSE
|
|
platform_fee := (base_price * fee_percentage) + (fee_fixed / 100.0);
|
|
END CASE;
|
|
|
|
-- Calculate organizer net (what they receive)
|
|
organizer_net := base_price - platform_fee;
|
|
|
|
-- Ensure organizer net is never negative
|
|
IF organizer_net < 0 THEN
|
|
organizer_net := 0;
|
|
END IF;
|
|
|
|
RETURN ROUND(organizer_net, 2);
|
|
END;
|
|
$$ LANGUAGE plpgsql;
|
|
|
|
-- Add indexes for performance
|
|
CREATE INDEX idx_organizations_platform_fee_model ON organizations(platform_fee_model);
|
|
CREATE INDEX idx_fee_structures_fee_model ON fee_structures(fee_model);
|
|
|
|
-- Add check constraints to ensure valid fee models
|
|
ALTER TABLE organizations
|
|
ADD CONSTRAINT check_platform_fee_model
|
|
CHECK (platform_fee_model IN ('customer_pays', 'absorbed_in_price'));
|
|
|
|
ALTER TABLE fee_structures
|
|
ADD CONSTRAINT check_fee_model
|
|
CHECK (fee_model IN ('customer_pays', 'absorbed_in_price')); |