mirror of
https://github.com/frappe/erpnext.git
synced 2026-05-26 08:24:47 +00:00
refactor!: drop ecommerce in favor of webshop (#33265)
* refactor!: remove ecommerce item group field check Signed-off-by: Sabu Siyad <hello@ssiyad.com> * refactor!: remove `e_commerce` directory Signed-off-by: Sabu Siyad <hello@ssiyad.com> * refactor!: remove `get_context` from `item_group` https://frappeframework.com/docs/v14/user/en/guides/portal-development/context Signed-off-by: Sabu Siyad <hello@ssiyad.com> * refactor!: remove related `./templates` Signed-off-by: Sabu Siyad <hello@ssiyad.com> * refactor!(navbar): remove wishlist (ecommerce) Signed-off-by: Sabu Siyad <hello@ssiyad.com> * refactor!(js): remove js from scripts Signed-off-by: Sabu Siyad <hello@ssiyad.com> * refactor!: remove `www/all-products` Signed-off-by: Sabu Siyad <hello@ssiyad.com> * refactor!: remove pages and js Signed-off-by: Sabu Siyad <hello@ssiyad.com> * refactor!: remove js/customer_reviews Signed-off-by: Sabu Siyad <hello@ssiyad.com> * refactor!(portal utils): remove shopping cart debtor account Signed-off-by: Sabu Siyad <hello@ssiyad.com> * refactor!: remove e_commerce events from hooks Signed-off-by: Sabu Siyad <hello@ssiyad.com> * refactor!(web): remove e_commerce js from bundle Signed-off-by: Sabu Siyad <hello@ssiyad.com> * refactor!(setup): remove shopping cart setup Signed-off-by: Sabu Siyad <hello@ssiyad.com> * refactor!: remove pages Signed-off-by: Sabu Siyad <hello@ssiyad.com> * refactor(item): remove website item button Signed-off-by: Sabu Siyad <hello@ssiyad.com> * refactor!(payment request): remove `on_payment_authorized` Signed-off-by: Sabu Siyad <hello@ssiyad.com> * refactor!: @staticmethod `get_gateway_details` to avoid monkey patching, in custom apps https://discuss.erpnext.com/t/how-to-override-method-in-frappe/28786/36 Signed-off-by: Sabu Siyad <hello@ssiyad.com> * refactor!(pages): remove product page Signed-off-by: Sabu Siyad <hello@ssiyad.com> * refactor!(homepage): do not setup website items Signed-off-by: Sabu Siyad <hello@ssiyad.com> * refactor(workspace): remove link to ecommerce settings Signed-off-by: Sabu Siyad <hello@ssiyad.com> * refactor!(www): remove shop-by-category Signed-off-by: Sabu Siyad <hello@ssiyad.com> * refactor!(homepage): remove featured product Signed-off-by: Sabu Siyad <hello@ssiyad.com> * refactor: remove products in homepage Signed-off-by: Sabu Siyad <hello@ssiyad.com> * refactor(homepage): remove explore button Signed-off-by: Sabu Siyad <hello@ssiyad.com> * refactor: remove products fields from homepage Signed-off-by: Sabu Siyad <hello@ssiyad.com> * Revert "refactor!: @staticmethod `get_gateway_details`" This reverts commit 561bcd96680a930bb92627869502d9346b10611b. Signed-off-by: Sabu Siyad <hello@ssiyad.com> * refactor!: remove payment gateway e_commerce import Signed-off-by: Sabu Siyad <hello@ssiyad.com> * chore: pre-commit Signed-off-by: Sabu Siyad <hello@ssiyad.com> * refactor!: pass `party` into `get_price` Signed-off-by: Sabu Siyad <hello@ssiyad.com> * refactor: move `get_item_codes_by_attributes` to `utilities/product` Signed-off-by: Sabu Siyad <hello@ssiyad.com> * refactor!(quotation): input customer group Signed-off-by: Sabu Siyad <hello@ssiyad.com> * chore: pre-commit * refactor: remove custom `navbar_items.html` * refactor!(item): remove `published_in_website` * refactor: move `validate_duplicate_website_item` before rename * test: remove `test_shopping_cart_without_website_item` * chore: add doctype drop patch * refactor: removed website item related code * refactor: removed shopping_cart code * refactor: removed e-commerce related patches * refactor: removed website related fields from item group * fix: patch create_asset_depreciation_schedules_from_assets, KeyError: '0K BU64 AUY' --------- Signed-off-by: Sabu Siyad <hello@ssiyad.com> Co-authored-by: Rohit Waghchaure <rohitw1991@gmail.com>
This commit is contained in:
@@ -1,51 +0,0 @@
|
||||
{% from "erpnext/templates/includes/macros.html" import attribute_filter_section, field_filter_section, discount_range_filters %}
|
||||
{% extends "templates/web.html" %}
|
||||
|
||||
{% block title %}{{ _('All Products') }}{% endblock %}
|
||||
{% block header %}
|
||||
<div class="mb-6">{{ _('All Products') }}</div>
|
||||
{% endblock header %}
|
||||
|
||||
{% block page_content %}
|
||||
<div class="row">
|
||||
<!-- Items section -->
|
||||
<div id="product-listing" class="col-12 order-2 col-md-9 order-md-2 item-card-group-section">
|
||||
<!-- Rendered via JS -->
|
||||
</div>
|
||||
|
||||
<!-- Filters Section -->
|
||||
<div class="col-12 order-1 col-md-3 order-md-1">
|
||||
<div class="collapse d-md-block mr-4 filters-section" id="product-filters">
|
||||
<div class="d-flex justify-content-between align-items-center mb-5 title-section">
|
||||
<div class="mb-4 filters-title" > {{ _('Filters') }} </div>
|
||||
<a class="mb-4 clear-filters" href="/all-products">{{ _('Clear All') }}</a>
|
||||
</div>
|
||||
<!-- field filters -->
|
||||
{% if field_filters %}
|
||||
{{ field_filter_section(field_filters) }}
|
||||
{% endif %}
|
||||
|
||||
<!-- attribute filters -->
|
||||
{% if attribute_filters %}
|
||||
{{ attribute_filter_section(attribute_filters) }}
|
||||
{% endif %}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
frappe.ready(() => {
|
||||
$('.btn-prev, .btn-next').click((e) => {
|
||||
const $btn = $(e.target);
|
||||
$btn.prop('disabled', true);
|
||||
const start = $btn.data('start');
|
||||
let query_params = frappe.utils.get_query_params();
|
||||
query_params.start = start;
|
||||
let path = window.location.pathname + '?' + frappe.utils.get_url_from_dict(query_params);
|
||||
window.location.href = path;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
{% endblock %}
|
||||
@@ -1,27 +0,0 @@
|
||||
$(() => {
|
||||
class ProductListing {
|
||||
constructor() {
|
||||
let me = this;
|
||||
let is_item_group_page = $(".item-group-content").data("item-group");
|
||||
this.item_group = is_item_group_page || null;
|
||||
|
||||
let view_type = localStorage.getItem("product_view") || "List View";
|
||||
|
||||
// Render Product Views, Filters & Search
|
||||
new erpnext.ProductView({
|
||||
view_type: view_type,
|
||||
products_section: $('#product-listing'),
|
||||
item_group: me.item_group
|
||||
});
|
||||
|
||||
this.bind_card_actions();
|
||||
}
|
||||
|
||||
bind_card_actions() {
|
||||
erpnext.e_commerce.shopping_cart.bind_add_to_cart_action();
|
||||
erpnext.e_commerce.wishlist.bind_wishlist_action();
|
||||
}
|
||||
}
|
||||
|
||||
new ProductListing();
|
||||
});
|
||||
@@ -1,22 +0,0 @@
|
||||
import frappe
|
||||
from frappe.utils import cint
|
||||
|
||||
from erpnext.e_commerce.product_data_engine.filters import ProductFiltersBuilder
|
||||
|
||||
sitemap = 1
|
||||
|
||||
|
||||
def get_context(context):
|
||||
# Add homepage as parent
|
||||
context.body_class = "product-page"
|
||||
context.parents = [{"name": frappe._("Home"), "route": "/"}]
|
||||
|
||||
filter_engine = ProductFiltersBuilder()
|
||||
context.field_filters = filter_engine.get_field_filters()
|
||||
context.attribute_filters = filter_engine.get_attribute_filters()
|
||||
|
||||
context.page_length = (
|
||||
cint(frappe.db.get_single_value("E Commerce Settings", "products_per_page")) or 20
|
||||
)
|
||||
|
||||
context.no_cache = 1
|
||||
@@ -1 +0,0 @@
|
||||
<div class="d-flex justify-content-center p-3 text-muted">{{ _('No products found') }}</div>
|
||||
@@ -1,30 +0,0 @@
|
||||
{%- macro card(title, image, type, url=None, text_primary=False) -%}
|
||||
<!-- style defined at shop-by-category index -->
|
||||
<div class="card category-card" data-type="{{ type }}" data-name="{{ title }}">
|
||||
{% if image %}
|
||||
<img class="card-img-top" src="{{ image }}" alt="{{ title }}" style="height: 80%;">
|
||||
{% else %}
|
||||
<div class="placeholder-div">
|
||||
<span class="placeholder">
|
||||
{{ frappe.utils.get_abbr(title) }}
|
||||
</span>
|
||||
</div>
|
||||
{% endif %}
|
||||
<div class="card-body text-center text-muted">
|
||||
{{ title or '' }}
|
||||
</div>
|
||||
<a href="{{ url or '#' }}" class="stretched-link"></a>
|
||||
</div>
|
||||
{%- endmacro -%}
|
||||
|
||||
<div class="col-12 item-card-group-section">
|
||||
<div class="row products-list product-category-section">
|
||||
{%- for row in data -%}
|
||||
{%- set title = row.name -%}
|
||||
{%- set image = row.get("image") -%}
|
||||
{%- if title -%}
|
||||
{{ card(title, image, type, row.get("route")) }}
|
||||
{%- endif -%}
|
||||
{%- endfor -%}
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,48 +0,0 @@
|
||||
{% extends "templates/web.html" %}
|
||||
{% block title %}{{ _('Shop by Category') }}{% endblock %}
|
||||
|
||||
{% block head_include %}
|
||||
<style>
|
||||
.category-slideshow {
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
.category-card {
|
||||
height: 300px !important;
|
||||
width: 300px !important;
|
||||
margin: 30px !important;
|
||||
}
|
||||
</style>
|
||||
{% endblock %}
|
||||
|
||||
{% block script %}
|
||||
<script type="text/javascript" src="/shop-by-category/index.js"></script>
|
||||
{% endblock %}
|
||||
|
||||
{% block page_content %}
|
||||
<div class="shop-by-category-content">
|
||||
<div class="category-slideshow">
|
||||
{% if slideshow %}
|
||||
<!-- slideshow -->
|
||||
{{ web_block(
|
||||
"Hero Slider",
|
||||
values=slideshow,
|
||||
add_container=0,
|
||||
add_top_padding=0,
|
||||
add_bottom_padding=0,
|
||||
) }}
|
||||
{% endif %}
|
||||
</div>
|
||||
<div class="category-tabs">
|
||||
{% if tabs %}
|
||||
<!-- tabs -->
|
||||
{{ web_block(
|
||||
"Section with Tabs",
|
||||
values=tabs,
|
||||
add_container=0,
|
||||
add_top_padding=0,
|
||||
add_bottom_padding=0
|
||||
) }}
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
{% endblock %}
|
||||
@@ -1,12 +0,0 @@
|
||||
$(() => {
|
||||
$('.category-card').on('click', (e) => {
|
||||
let category_type = e.currentTarget.dataset.type;
|
||||
let category_name = e.currentTarget.dataset.name;
|
||||
|
||||
if (category_type != "item_group") {
|
||||
let filters = {};
|
||||
filters[category_type] = [category_name];
|
||||
window.location.href = "/all-products?field_filters=" + JSON.stringify(filters);
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -1,91 +0,0 @@
|
||||
import frappe
|
||||
from frappe import _
|
||||
|
||||
sitemap = 1
|
||||
|
||||
|
||||
def get_context(context):
|
||||
context.body_class = "product-page"
|
||||
|
||||
settings = frappe.get_cached_doc("E Commerce Settings")
|
||||
context.categories_enabled = settings.enable_field_filters
|
||||
|
||||
if context.categories_enabled:
|
||||
categories = [row.fieldname for row in settings.filter_fields]
|
||||
context.tabs = get_tabs(categories)
|
||||
|
||||
if settings.slideshow:
|
||||
context.slideshow = get_slideshow(settings.slideshow)
|
||||
|
||||
context.no_cache = 1
|
||||
|
||||
|
||||
def get_slideshow(slideshow):
|
||||
values = {"show_indicators": 1, "show_controls": 1, "rounded": 1, "slider_name": "Categories"}
|
||||
slideshow = frappe.get_cached_doc("Website Slideshow", slideshow)
|
||||
slides = slideshow.get({"doctype": "Website Slideshow Item"})
|
||||
for index, slide in enumerate(slides, start=1):
|
||||
values[f"slide_{index}_image"] = slide.image
|
||||
values[f"slide_{index}_title"] = slide.heading
|
||||
values[f"slide_{index}_subtitle"] = slide.description
|
||||
values[f"slide_{index}_theme"] = slide.get("theme") or "Light"
|
||||
values[f"slide_{index}_content_align"] = slide.get("content_align") or "Centre"
|
||||
values[f"slide_{index}_primary_action"] = slide.url
|
||||
|
||||
return values
|
||||
|
||||
|
||||
def get_tabs(categories):
|
||||
tab_values = {
|
||||
"title": _("Shop by Category"),
|
||||
}
|
||||
|
||||
categorical_data = get_category_records(categories)
|
||||
for index, tab in enumerate(categorical_data, start=1):
|
||||
tab_values[f"tab_{index + 1}_title"] = frappe.unscrub(tab)
|
||||
# pre-render cards for each tab
|
||||
tab_values[f"tab_{index + 1}_content"] = frappe.render_template(
|
||||
"erpnext/www/shop-by-category/category_card_section.html",
|
||||
{"data": categorical_data[tab], "type": tab},
|
||||
)
|
||||
return tab_values
|
||||
|
||||
|
||||
def get_category_records(categories: list):
|
||||
categorical_data = {}
|
||||
website_item_meta = frappe.get_meta("Website Item", cached=True)
|
||||
|
||||
for c in categories:
|
||||
if c == "item_group":
|
||||
categorical_data["item_group"] = frappe.db.get_all(
|
||||
"Item Group",
|
||||
filters={"parent_item_group": "All Item Groups", "show_in_website": 1},
|
||||
fields=["name", "parent_item_group", "is_group", "image", "route"],
|
||||
)
|
||||
|
||||
continue
|
||||
|
||||
field_type = website_item_meta.get_field(c).fieldtype
|
||||
|
||||
if field_type == "Table MultiSelect":
|
||||
child_doc = website_item_meta.get_field(c).options
|
||||
for field in frappe.get_meta(child_doc, cached=True).fields:
|
||||
if field.fieldtype == "Link" and field.reqd:
|
||||
doctype = field.options
|
||||
else:
|
||||
doctype = website_item_meta.get_field(c).options
|
||||
|
||||
fields = ["name"]
|
||||
|
||||
try:
|
||||
meta = frappe.get_meta(doctype, cached=True)
|
||||
if meta.get_field("image"):
|
||||
fields += ["image"]
|
||||
|
||||
data = frappe.db.get_all(doctype, fields=fields)
|
||||
categorical_data[c] = data
|
||||
except BaseException:
|
||||
frappe.throw(_("DocType {} not found").format(doctype))
|
||||
continue
|
||||
|
||||
return categorical_data
|
||||
Reference in New Issue
Block a user