Skip to content
This repository was archived by the owner on Jan 1, 2026. It is now read-only.

Commit e84f141

Browse files
VianpyroVianpyro
andauthored
Add products functions (#10)
* Add (paginated) product querries * feat: Update database schema tests and seed data - Enhanced `schema.test.sql` to include new tables, columns, and constraints for products, categories, attributes, tags, and customization options. - Expanded test coverage to validate the existence of new tables and their relationships. - Updated `seed_data.test.sql` to include checks for new product categories, products, attributes, tags, and customization options. - Introduced new functions for product price calculation, product attributes filtering, category retrieval, product details fetching, tag retrieval, and product searching. - Added comprehensive tests for the new functions to ensure correct functionality and data retrieval. * Remove useless comments from schema test file * Clean up seed data and test files by removing unnecessary comments * Improve readability of seed data SQL by standardizing comment formatting * Add functions for product management including adding new products, customization options, variants, and updating product status * Enhance product-related functions with detailed data retrieval and pagination support * Implement functions for adding and retrieving product customization options * Rename product management functions files * Refactor product attribute retrieval function to return individual attribute values and counts, enhancing data structure for filtering. --------- Co-authored-by: Vianpyro <vianney@veremme.org>
1 parent 4600e4f commit e84f141

24 files changed

Lines changed: 1042 additions & 402 deletions
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
CREATE OR REPLACE FUNCTION get_customization_option_values(
2+
p_customization_option_id INTEGER,
3+
p_language_iso CHAR(2) DEFAULT 'en'
4+
) RETURNS TABLE (
5+
value_id INTEGER,
6+
customization_option_id INTEGER,
7+
value_name TEXT,
8+
price_modifier NUMERIC(10, 2),
9+
is_default BOOLEAN,
10+
display_order INTEGER,
11+
is_enabled BOOLEAN
12+
) AS $$
13+
BEGIN
14+
RETURN QUERY
15+
SELECT
16+
cov.option_value_id as value_id,
17+
cov.customization_option_id,
18+
COALESCE(covt.value_name, cov.value_name) as value_name,
19+
cov.price_modifier,
20+
cov.is_default,
21+
cov.display_order,
22+
cov.is_enabled
23+
FROM customization_option_values cov
24+
LEFT JOIN customization_option_value_translations covt
25+
ON cov.option_value_id = covt.option_value_id
26+
AND covt.language_id = (SELECT language_id FROM languages WHERE iso_code = p_language_iso)
27+
WHERE cov.customization_option_id = p_customization_option_id
28+
AND cov.is_enabled = TRUE
29+
ORDER BY cov.display_order, cov.value_name;
30+
END;
31+
$$ LANGUAGE plpgsql SECURITY DEFINER;
File renamed without changes.
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
CREATE OR REPLACE FUNCTION add_product_customization_option(
2+
p_product_id INTEGER,
3+
p_customization_option_id INTEGER,
4+
p_is_required BOOLEAN DEFAULT FALSE,
5+
p_display_order INTEGER DEFAULT 0
6+
) RETURNS BOOLEAN AS $$
7+
DECLARE
8+
v_product_type PRODUCT_TYPE;
9+
v_option_exists BOOLEAN;
10+
BEGIN
11+
-- Validate product exists and is configurable
12+
SELECT product_type INTO v_product_type
13+
FROM products
14+
WHERE product_id = p_product_id
15+
AND is_enabled = TRUE;
16+
17+
IF v_product_type IS NULL THEN
18+
RAISE EXCEPTION 'Product ID % not found or is disabled', p_product_id
19+
USING ERRCODE = 'C0001';
20+
END IF;
21+
22+
IF v_product_type != 'configurable' THEN
23+
RAISE EXCEPTION 'Can only add customization options to configurable products'
24+
USING ERRCODE = 'C0002',
25+
HINT = 'Product type is: ' || v_product_type;
26+
END IF;
27+
28+
-- Validate customization option exists
29+
SELECT EXISTS (
30+
SELECT 1 FROM customization_options
31+
WHERE customization_option_id = p_customization_option_id
32+
AND is_enabled = TRUE
33+
) INTO v_option_exists;
34+
35+
IF NOT v_option_exists THEN
36+
RAISE EXCEPTION 'Customization option ID % not found or is disabled', p_customization_option_id
37+
USING ERRCODE = 'C0003';
38+
END IF;
39+
40+
-- Insert the association
41+
INSERT INTO product_customization_options (
42+
product_id,
43+
customization_option_id,
44+
is_required,
45+
display_order
46+
) VALUES (
47+
p_product_id,
48+
p_customization_option_id,
49+
p_is_required,
50+
p_display_order
51+
) ON CONFLICT (product_id, customization_option_id) DO UPDATE SET
52+
is_required = EXCLUDED.is_required,
53+
display_order = EXCLUDED.display_order;
54+
55+
RAISE NOTICE 'Added customization option % to product %', p_customization_option_id, p_product_id;
56+
57+
RETURN TRUE;
58+
59+
EXCEPTION
60+
WHEN OTHERS THEN
61+
RAISE NOTICE 'Error adding customization option: % - %', SQLSTATE, SQLERRM;
62+
RAISE;
63+
END;
64+
$$ LANGUAGE plpgsql SECURITY DEFINER;
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
CREATE OR REPLACE FUNCTION get_product_customization_options(
2+
p_product_id INTEGER,
3+
p_language_iso CHAR(2) DEFAULT 'en'
4+
) RETURNS TABLE (
5+
option_id INTEGER,
6+
product_id INTEGER,
7+
option_name TEXT,
8+
option_type TEXT,
9+
is_required BOOLEAN,
10+
display_order INTEGER,
11+
created_at TIMESTAMPTZ
12+
) AS $$
13+
BEGIN
14+
RETURN QUERY
15+
SELECT
16+
co.customization_option_id as option_id,
17+
pco.product_id,
18+
COALESCE(cot.option_name, co.option_name) as option_name,
19+
co.option_type,
20+
COALESCE(pco.is_required, co.is_required) as is_required,
21+
COALESCE(pco.display_order, co.display_order) as display_order,
22+
pco.created_at
23+
FROM product_customization_options pco
24+
JOIN customization_options co ON pco.customization_option_id = co.customization_option_id
25+
LEFT JOIN customization_option_translations cot
26+
ON co.customization_option_id = cot.customization_option_id
27+
AND cot.language_id = (SELECT language_id FROM languages WHERE iso_code = p_language_iso)
28+
JOIN products p ON pco.product_id = p.product_id
29+
WHERE pco.product_id = p_product_id
30+
AND co.is_enabled = TRUE
31+
AND p.is_enabled = TRUE
32+
ORDER BY COALESCE(pco.display_order, co.display_order), co.option_name;
33+
END;
34+
$$ LANGUAGE plpgsql SECURITY DEFINER;
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
CREATE OR REPLACE FUNCTION get_product_variants(
2+
p_product_id INTEGER
3+
) RETURNS TABLE (
4+
variant_id INTEGER,
5+
product_id INTEGER,
6+
variant_name TEXT,
7+
size TEXT,
8+
quantity INTEGER,
9+
serving_size TEXT,
10+
price_override NUMERIC(10, 2),
11+
final_price NUMERIC(10, 2),
12+
is_default BOOLEAN,
13+
display_order INTEGER
14+
) AS $$
15+
BEGIN
16+
RETURN QUERY
17+
SELECT
18+
pv.product_variant_id as variant_id,
19+
pv.product_id,
20+
pv.variant_name,
21+
pv.size,
22+
pv.quantity,
23+
pv.serving_size,
24+
pv.price_override,
25+
COALESCE(pv.price_override, p.price) as final_price,
26+
pv.is_default,
27+
pv.display_order
28+
FROM product_variants pv
29+
JOIN products p ON pv.product_id = p.product_id
30+
WHERE pv.product_id = p_product_id
31+
AND pv.is_test = FALSE
32+
AND p.is_enabled = TRUE
33+
ORDER BY pv.display_order, pv.product_variant_id;
34+
END;
35+
$$ LANGUAGE plpgsql SECURITY DEFINER;

0 commit comments

Comments
 (0)