<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
	<id>https://mediawiki.comfac.net/index.php?action=history&amp;feed=atom&amp;title=Webshop-05-Variant-Selector</id>
	<title>Webshop-05-Variant-Selector - Revision history</title>
	<link rel="self" type="application/atom+xml" href="https://mediawiki.comfac.net/index.php?action=history&amp;feed=atom&amp;title=Webshop-05-Variant-Selector"/>
	<link rel="alternate" type="text/html" href="https://mediawiki.comfac.net/index.php?title=Webshop-05-Variant-Selector&amp;action=history"/>
	<updated>2026-06-05T11:02:48Z</updated>
	<subtitle>Revision history for this page on the wiki</subtitle>
	<generator>MediaWiki 1.45.1</generator>
	<entry>
		<id>https://mediawiki.comfac.net/index.php?title=Webshop-05-Variant-Selector&amp;diff=163&amp;oldid=prev</id>
		<title>Justinaquino: &quot;Add all 14 Frappe ERPNext Webshop chapter pages from wikitext-upload&quot;</title>
		<link rel="alternate" type="text/html" href="https://mediawiki.comfac.net/index.php?title=Webshop-05-Variant-Selector&amp;diff=163&amp;oldid=prev"/>
		<updated>2026-03-06T13:00:41Z</updated>

		<summary type="html">&lt;p&gt;&amp;quot;Add all 14 Frappe ERPNext Webshop chapter pages from wikitext-upload&amp;quot;&lt;/p&gt;
&lt;p&gt;&lt;b&gt;New page&lt;/b&gt;&lt;/p&gt;&lt;div&gt;= 05 - Variant Selector =&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Parent:&amp;#039;&amp;#039;&amp;#039; [Webshop-Index Webshop Index]  &lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Previous:&amp;#039;&amp;#039;&amp;#039; [Webshop-04-Product-Pages-and-Browsing 04 - Product Pages &amp;amp; Browsing]  &lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Next:&amp;#039;&amp;#039;&amp;#039; [Webshop-06-Pricing-and-Discounts 06 - Pricing &amp;amp; Discounts]  &lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Source:&amp;#039;&amp;#039;&amp;#039; [https://github.com/Comfac-Global-Group/comfac-webshop/wiki/05-Variant-Selector Comfac Webshop Wiki - Chapter 05]&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
== How Variants Work in ERPNext + Webshop ==&lt;br /&gt;
&lt;br /&gt;
ERPNext has a built-in &amp;#039;&amp;#039;&amp;#039;Item Variant&amp;#039;&amp;#039;&amp;#039; system:&lt;br /&gt;
&lt;br /&gt;
- &amp;#039;&amp;#039;&amp;#039;Template Item&amp;#039;&amp;#039;&amp;#039;: defines attributes (e.g., Color, Size, RAM, Storage)&lt;br /&gt;
- &amp;#039;&amp;#039;&amp;#039;Variant Items&amp;#039;&amp;#039;&amp;#039;: concrete products with specific attribute values (e.g., &amp;quot;Laptop - 16GB RAM - 512GB SSD&amp;quot;)&lt;br /&gt;
&lt;br /&gt;
The webshop uses this to create a step-by-step configurator on product pages.&lt;br /&gt;
&lt;br /&gt;
== Key Files ==&lt;br /&gt;
&lt;br /&gt;
- &amp;lt;code&amp;gt;webshop/variant_selector/utils.py&amp;lt;/code&amp;gt; - Core variant logic&lt;br /&gt;
- &amp;lt;code&amp;gt;webshop/variant_selector/item_variants_cache.py&amp;lt;/code&amp;gt; - Redis caching layer&lt;br /&gt;
- &amp;lt;code&amp;gt;templates/generators/item/item_configure.html&amp;lt;/code&amp;gt; - Configurator UI&lt;br /&gt;
- &amp;lt;code&amp;gt;templates/generators/item/item_configure.js&amp;lt;/code&amp;gt; - Configurator JS&lt;br /&gt;
&lt;br /&gt;
== Variant Selection Flow ==&lt;br /&gt;
&lt;br /&gt;
1. User visits a Template Item page (has_variants=True)&lt;br /&gt;
2. &amp;lt;code&amp;gt;item_configure.html&amp;lt;/code&amp;gt; renders attribute dropdowns&lt;br /&gt;
3. &amp;lt;code&amp;gt;item_configure.js&amp;lt;/code&amp;gt; calls &amp;lt;code&amp;gt;get_next_attribute_and_values&amp;lt;/code&amp;gt; API on each selection&lt;br /&gt;
4. Backend filters valid combinations, returns:&lt;br /&gt;
   - &amp;lt;code&amp;gt;next_attribute&amp;lt;/code&amp;gt; - which attribute to select next&lt;br /&gt;
   - &amp;lt;code&amp;gt;valid_options_for_attributes&amp;lt;/code&amp;gt; - valid values given current selections&lt;br /&gt;
   - &amp;lt;code&amp;gt;filtered_items_count&amp;lt;/code&amp;gt; - how many variants match&lt;br /&gt;
   - &amp;lt;code&amp;gt;exact_match&amp;lt;/code&amp;gt; - if one variant is fully selected&lt;br /&gt;
   - &amp;lt;code&amp;gt;product_info&amp;lt;/code&amp;gt; - price for the matched variant&lt;br /&gt;
   - &amp;lt;code&amp;gt;available_qty&amp;lt;/code&amp;gt; - stock quantity&lt;br /&gt;
5. When exact match found, &amp;quot;Add to Cart&amp;quot; button appears with variant item_code&lt;br /&gt;
&lt;br /&gt;
== Cache System (&amp;lt;code&amp;gt;ItemVariantsCacheManager&amp;lt;/code&amp;gt;) ==&lt;br /&gt;
&lt;br /&gt;
Uses Redis to cache:&lt;br /&gt;
&lt;br /&gt;
- &amp;lt;code&amp;gt;item_variants_data&amp;lt;/code&amp;gt; - all variant attribute values&lt;br /&gt;
- &amp;lt;code&amp;gt;item_attribute_value_map&amp;lt;/code&amp;gt; - attribute -&amp;gt; variant mapping&lt;br /&gt;
- &amp;lt;code&amp;gt;optional_attributes&amp;lt;/code&amp;gt; - which attributes are optional&lt;br /&gt;
&lt;br /&gt;
Cache is invalidated on Item save/rename via crud_events hooks.&lt;br /&gt;
&lt;br /&gt;
== API Endpoints ==&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;get_attributes_and_values(item_code)&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Returns all attributes and their possible values for a template item.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;get_next_attribute_and_values(item_code, selected_attributes)&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Progressive filtering - returns valid options given current selections.&lt;br /&gt;
&lt;br /&gt;
=== &amp;lt;code&amp;gt;get_item_variant_price_dict(item_code, cart_settings)&amp;lt;/code&amp;gt; ===&lt;br /&gt;
&lt;br /&gt;
Gets price for a specific variant item.&lt;br /&gt;
&lt;br /&gt;
== Relevance to System Builder ==&lt;br /&gt;
&lt;br /&gt;
The existing variant selector is a &amp;#039;&amp;#039;&amp;#039;single-item configurator&amp;#039;&amp;#039;&amp;#039;. The planned System Builder would need:&lt;br /&gt;
&lt;br /&gt;
- &amp;#039;&amp;#039;&amp;#039;Multi-item configuration&amp;#039;&amp;#039;&amp;#039; (CPU + RAM + Storage + etc.)&lt;br /&gt;
- &amp;#039;&amp;#039;&amp;#039;Cross-item compatibility rules&amp;#039;&amp;#039;&amp;#039; (not just attribute filtering within one template)&lt;br /&gt;
- &amp;#039;&amp;#039;&amp;#039;Template/preset system&amp;#039;&amp;#039;&amp;#039; (save configurations)&lt;br /&gt;
- &amp;#039;&amp;#039;&amp;#039;Aggregated pricing&amp;#039;&amp;#039;&amp;#039; (total system price with combined discounts)&lt;br /&gt;
&lt;br /&gt;
The variant_selector&amp;#039;s caching and attribute filtering logic could be extended, but the System Builder is fundamentally a different scope.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;See Also:&amp;#039;&amp;#039;&amp;#039; [Webshop-11-Feature-Plan-System-Builder Feature Plan: System Builder]&lt;br /&gt;
&lt;br /&gt;
&amp;#039;&amp;#039;&amp;#039;Navigation:&amp;#039;&amp;#039;&amp;#039; [Webshop-Index Webshop Index] | [Webshop-04-Product-Pages-and-Browsing Previous: 04 - Product Pages] | [Webshop-06-Pricing-and-Discounts Next: 06 - Pricing &amp;amp; Discounts]&lt;/div&gt;</summary>
		<author><name>Justinaquino</name></author>
	</entry>
</feed>