def valid(self): """ This pane will be only valid when at least SimpleCMS or xTheme or Notify are in INSTALLED APPS """ return (djangoenv.has_installed("shuup.simple_cms") or djangoenv.has_installed("shuup.xtheme") or djangoenv.has_installed("shuup.notify"))
def get_form_defs(self): form_defs = [] if djangoenv.has_installed("shuup.simple_cms") or djangoenv.has_installed("shuup.xtheme"): form_defs.append( TemplatedWizardFormDef( name="content", template_name="shuup/admin/content/wizard.jinja", form_class=ContentWizardForm, context={"title": _("Configure the initial content pages")}, kwargs={"shop": self.object} ) ) if djangoenv.has_installed("shuup.notify") and djangoenv.has_installed("shuup.front"): form_defs.append( TemplatedWizardFormDef( name="behaviors", template_name="shuup/admin/content/wizard.jinja", form_class=BehaviorWizardForm, context={"title": _("Configure some notifications")}, kwargs={"shop": self.object} ) ) return form_defs
def get_form_defs(self): form_defs = [] if djangoenv.has_installed( "shuup.simple_cms") or djangoenv.has_installed("shuup.xtheme"): form_defs.append( TemplatedWizardFormDef( name="content", template_name="shuup/admin/content/wizard.jinja", form_class=ContentWizardForm, context={ "title": _("Configure the initial content pages") }, kwargs={"shop": self.object}, )) if djangoenv.has_installed("shuup.notify") and djangoenv.has_installed( "shuup.front"): form_defs.append( TemplatedWizardFormDef( name="behaviors", template_name="shuup/admin/content/wizard.jinja", form_class=BehaviorWizardForm, context={"title": _("Configure some notifications")}, kwargs={"shop": self.object}, )) return form_defs
def valid(self): """ This pane will be only valid when at least SimpleCMS or xTheme or Notify are in INSTALLED APPS """ return (djangoenv.has_installed("shuup.simple_cms") or djangoenv.has_installed("shuup.xtheme") or djangoenv.has_installed("shuup.notify"))
def text(self): cms_xtheme_installed = (djangoenv.has_installed("shuup.simple_cms") or djangoenv.has_installed("shuup.xtheme")) notify_installed = djangoenv.has_installed("shuup.notify") if cms_xtheme_installed and notify_installed: return _("Add the initial content and configure the customer notifications for your shop") elif notify_installed: return _("Configure notifications for your shop") else: return _("Add the initial content")
def form_valid(self, form): if djangoenv.has_installed("shuup.simple_cms") or djangoenv.has_installed("shuup.xtheme"): content_form = form["content"] content_form.save() if djangoenv.has_installed("shuup.notify"): behavior_form = form["behaviors"] behavior_form.save() configuration.set(None, "wizard_content_completed", True)
def text(self): cms_xtheme_installed = (djangoenv.has_installed("shuup.simple_cms") or djangoenv.has_installed("shuup.xtheme")) notify_installed = djangoenv.has_installed("shuup.notify") if cms_xtheme_installed and notify_installed: return _("Add the initial content and configure the customer notifications for your shop") elif notify_installed: return _("Configure notifications for your shop") else: return _("Add the initial content")
def form_valid(self, form): if djangoenv.has_installed("shuup.simple_cms") or djangoenv.has_installed("shuup.xtheme"): content_form = form["content"] content_form.save() if djangoenv.has_installed("shuup.notify"): behavior_form = form["behaviors"] behavior_form.save() configuration.set(None, "wizard_content_completed", True)
def save(self): """ Generate the selected pages is SimpleCMS is installed. Generate the Footer if xTheme is installed. """ if not self.is_valid(): return # form must be validated if djangoenv.has_installed("shuup.simple_cms"): self._handle_simple_cms_save() if djangoenv.has_installed("shuup.xtheme") and self.cleaned_data["configure_footer"]: self._handle_xtheme_save()
def save(self): """ Generate the selected pages is SimpleCMS is installed. Generate the Footer if xTheme is installed. """ if not self.is_valid(): return # form must be validated if djangoenv.has_installed("shuup.simple_cms"): self._handle_simple_cms_save() if djangoenv.has_installed("shuup.xtheme") and self.cleaned_data["configure_footer"]: self._handle_xtheme_save()
def get_fields(self, **kwargs): request = kwargs.get("request", None) if not has_installed("shuup.gdpr") or not request: return [] gdpr_settings = GDPRSettings.get_for_shop(request.shop) if not gdpr_settings.enabled: return [] fields = [] for page in get_active_consent_pages(request.shop): key = "accept_{}".format(page.id) field = forms.BooleanField( label=_("I have read and accept the {}").format(page.title), required=True, help_text=_("Read the <a href='{}' target='_blank'>{}</a>.").format( reverse("shuup:cms_page", kwargs=dict(url=page.url)), page.title ), error_messages=dict(required=self.error_message) ) definition = FormFieldDefinition(name=key, field=field) fields.append(definition) return fields
def post(self, request, *args, **kwargs): shop = request.shop cookie_categories = list( GDPRCookieCategory.objects.filter(shop=shop, always_active=True)) for field, value in request.POST.items(): field_match = re.match(COOKIE_CONSENT_RE, field) if field_match and value.lower() in ["on", "1"]: cookie_category = GDPRCookieCategory.objects.filter( shop=shop, id=field_match.groups()[0]).first() if cookie_category: cookie_categories.append(cookie_category) consent_documents = [] if has_installed("shuup.simple_cms"): from shuup.simple_cms.models import Page, PageType consent_documents = Page.objects.visible(shop).filter( page_type=PageType.GDPR_CONSENT_DOCUMENT) cookie_data = get_cookie_consent_data(cookie_categories, consent_documents) if request.META.get("HTTP_REFERER"): redirect_url = request.META["HTTP_REFERER"] else: redirect_url = reverse("shuup:index") response = HttpResponseRedirect(redirect_url) add_consent_to_response_cookie(response, cookie_data) return response
def update_stock(self, product_id): """ Supplier module update stock should always bump product cache and send `shuup.core.signals.stocks_updated` signal. """ supplier_id = self.supplier.pk sv, _ = StockCount.objects.get_or_create(supplier_id=supplier_id, product_id=product_id) if not sv.stock_managed: # item doesn't manage stocks return # TODO: Consider whether this should be done without a cache table values = get_current_stock_value(supplier_id=supplier_id, product_id=product_id) sv.logical_count = values["logical_count"] sv.physical_count = values["physical_count"] latest_event = ( StockAdjustment.objects .filter(supplier=supplier_id, product=product_id, type=StockAdjustmentType.INVENTORY) .last()) if latest_event: sv.stock_value_value = latest_event.purchase_price_value * sv.logical_count if self.supplier.stock_managed and has_installed("shuup.notify"): if sv.alert_limit and sv.physical_count < sv.alert_limit: product = Product.objects.filter(id=product_id).first() if product: from .notify_events import AlertLimitReached for shop in self.supplier.shops.all(): AlertLimitReached(supplier=self.supplier, product=product).run(shop=shop) sv.save(update_fields=("logical_count", "physical_count", "stock_value_value")) context_cache.bump_cache_for_product(Product.objects.get(id=product_id)) stocks_updated.send( type(self), shops=self.supplier.shops.all(), product_ids=[product_id], supplier=self.supplier)
def test_copy_works_without_simple_supplier(rf, admin_user, settings): settings.INSTALLED_APPS.remove("shuup.simple_supplier") assert not has_installed("shuup.simple_supplier") shop = factories.get_default_shop() supplier = factories.get_default_supplier() request = apply_request_middleware(rf.get("/", {}), user=admin_user) price = 10 product = factories.create_product("product", shop=shop, supplier=supplier, default_price=price) shop_product = product.get_shop_instance(shop) assert Product.objects.count() == 1 view_func = ProductCopyView.as_view() response = view_func(request, pk=shop_product.pk) if hasattr(response, "render"): response.render() assert Product.objects.count() == 2 # Add back so rest of the tests work settings.INSTALLED_APPS.append("shuup.simple_supplier")
def __init__(self, *args, **kwargs): self.request = kwargs.pop("request") self.current_product_ids = kwargs.pop("current_product_ids", "") super(ConfirmForm, self).__init__(*args, **kwargs) if has_installed("shuup.gdpr"): from shuup.gdpr.models import GDPRSettings if GDPRSettings.get_for_shop(self.request.shop).enabled: from shuup.simple_cms.models import Page, PageType gdpr_documents = Page.objects.visible( self.request.shop).filter(page_type=PageType.REVISIONED) if gdpr_documents.exists(): self.fields.pop("accept_terms") for page in gdpr_documents: self.fields["accept_{}".format( page.id )] = forms.BooleanField( label=_("I have read and accept the {}").format( page.title), help_text=_( "Read the <a href='{}' target='_blank'>{}</a>." ).format( reverse("shuup:cms_page", kwargs=dict(url=page.url)), page.title), error_messages=dict(required=_( "You must accept to this to confirm the order." ))) field_properties = settings.SHUUP_CHECKOUT_CONFIRM_FORM_PROPERTIES for field, properties in field_properties.items(): for prop in properties: setattr(self.fields[field], prop, properties[prop])
def post(self, request, *args, **kwargs): shop = request.shop cookie_categories = list(GDPRCookieCategory.objects.filter(shop=shop, always_active=True)) for field, value in request.POST.items(): field_match = re.match(COOKIE_CONSENT_RE, field) if field_match and value.lower() in ["on", "1"]: cookie_category = GDPRCookieCategory.objects.filter(shop=shop, id=field_match.groups()[0]).first() if cookie_category: cookie_categories.append(cookie_category) consent_documents = [] if has_installed("shuup.simple_cms"): consent_documents = get_active_consent_pages(shop) cookie_data = get_cookie_consent_data(cookie_categories, consent_documents) if request.META.get("HTTP_REFERER"): redirect_url = request.META["HTTP_REFERER"] else: redirect_url = force_text(reverse("shuup:index")) response = HttpResponseRedirect(redirect_url) add_consent_to_response_cookie(response, cookie_data) return response
def is_valid(self): if self.shop_product_id: errors = [] try: shop_product = ShopProduct.objects.get(pk=self.shop_product_id) except ShopProduct.DoesNotExist as e: errors.append( ValidationError(_('Invalid shop product.'), code="invalid-shop-product")) if has_installed("raven.contrib.django.raven_compat"): from raven.contrib.django.raven_compat.models import client client.captureException() if shop_product.shop != self.shop: errors.append( ValidationError(_('Invalid shop.'), code="invalid-shop")) errors.extend( list(shop_product.get_visibility_errors(self.customer))) for error in errors: self.add_error(None, error) return super(WishlistForm, self).is_valid()
def update_stock(self, product_id, *args, **kwargs): """ Supplier module update stock should always bump product cache and send `shuup.core.signals.stocks_updated` signal. """ supplier_id = self.supplier.pk sv, _ = StockCount.objects.select_related("product").get_or_create( supplier_id=supplier_id, product_id=product_id) # kind not supported if sv.product.kind not in self.get_supported_product_kinds_values(): return # item doesn't manage stocks if not sv.stock_managed: # make sure to index products either way run_task("shuup.simple_supplier.tasks.index_product", product=product_id, supplier=self.supplier.pk) return values = get_current_stock_value(supplier_id=supplier_id, product_id=product_id) sv.logical_count = values["logical_count"] sv.physical_count = values["physical_count"] latest_event = StockAdjustment.objects.filter( supplier=supplier_id, product=product_id, type=StockAdjustmentType.INVENTORY).last() if latest_event: sv.stock_value_value = latest_event.purchase_price_value * sv.logical_count # TODO: get rid of this and move to shuup.notify app instead, through signals if self.supplier.stock_managed and has_installed("shuup.notify"): if sv.alert_limit and sv.physical_count < sv.alert_limit: product = Product.objects.filter(id=product_id).first() if product: from .notify_events import AlertLimitReached for shop in self.supplier.shops.all(): supplier_email = self.supplier.contact_address.email if self.supplier.contact_address else "" shop_email = shop.contact_address.email if shop.contact_address else "" AlertLimitReached( supplier=self.supplier, product=product, shop_email=shop_email, supplier_email=supplier_email, ).run(shop=shop) sv.save(update_fields=("logical_count", "physical_count", "stock_value_value")) context_cache.bump_cache_for_product(product_id) stocks_updated.send(type(self), shops=self.supplier.shops.all(), product_ids=[product_id], supplier=self.supplier) run_task("shuup.simple_supplier.tasks.index_product", product=product_id, supplier=self.supplier.pk)
def ready(self): from shuup.utils.djangoenv import has_installed if has_installed("shuup.xtheme"): from django.db.models.signals import post_save from shuup.xtheme.cache import bump_xtheme_cache from .models import Carousel, Slide post_save.connect(bump_xtheme_cache, sender=Carousel) post_save.connect(bump_xtheme_cache, sender=Slide)
def get_gdpr_settings(request): from shuup.gdpr.models import GDPRSettings if not has_installed("shuup.gdpr") or not request: return None gdpr_settings = GDPRSettings.get_for_shop(request.shop) return gdpr_settings if gdpr_settings.enabled else None
def valid(self): """ This pane will be only valid when at least SimpleCMS or xTheme or Notify are in INSTALLED APPS """ permissions = [] if djangoenv.has_installed("shuup.simple_cms"): permissions.append("simple_cms.page.edit") if djangoenv.has_installed("shuup.notify"): permissions.append("notify.script.edit-content") from shuup.admin.utils.permissions import get_missing_permissions if get_missing_permissions(self.request.user, permissions): return False return (djangoenv.has_installed("shuup.simple_cms") or djangoenv.has_installed("shuup.xtheme") or djangoenv.has_installed("shuup.notify"))
def ready(self): from shuup.simple_cms.models import Page import reversion reversion.register(Page._parler_meta.root_model) from shuup.utils.djangoenv import has_installed if has_installed("shuup.xtheme"): from django.db.models.signals import post_save from shuup.xtheme.cache import bump_xtheme_cache post_save.connect(bump_xtheme_cache, sender=Page)
def save(self, *args, **kwargs): user = super(PersonRegistrationForm, self).save(*args, **kwargs) get_person_contact(user).shops.add(self.request.shop) if has_installed("shuup.gdpr"): from shuup.gdpr.utils import create_user_consent_for_all_documents create_user_consent_for_all_documents(self.request.shop, user) return user
def process_user(self, user_to_recover): if (not user_to_recover.has_usable_password() or not hasattr(user_to_recover, 'email') or not user_to_recover.email): return False uid = urlsafe_base64_encode(force_bytes(user_to_recover.pk)) token = self.token_generator.make_token(user_to_recover) context = { 'site_name': getattr(self.request, "shop", _("shop")), 'uid': uid, 'user_to_recover': user_to_recover, 'token': token, } notification_sent = False request = getattr(self, "request", None) if has_installed( 'shuup.notify' ) and request and request.shop and self.recover_password_confirm_view_url_name: # Send notification event if any Script enabled from shuup.notify.models import Script from shuup.notify.notify_events import PasswordReset if Script.objects.filter( enabled=True, event_identifier=PasswordReset.identifier).exists(): notification_sent = True recovery_url = request.build_absolute_uri( reverse(self.recover_password_confirm_view_url_name, kwargs=dict(uidb64=uid, token=token))) context.update({ 'customer_email': user_to_recover.email, 'recovery_url': recovery_url }) try: PasswordReset(**context).run(shop=self.request.shop) notification_sent = True except: notification_sent = False if not notification_sent: context.update({'request': self.request}) subject = loader.render_to_string(self.subject_template_name, context) subject = ''.join(subject.splitlines() ) # Email subject *must not* contain newlines body = loader.render_to_string(self.email_template_name, context, request=self.request) email = EmailMessage(from_email=self.from_email, subject=subject, body=body, to=[user_to_recover.email]) email.content_subtype = settings.SHUUP_AUTH_EMAIL_CONTENT_SUBTYPE email.send() return True
def get_product_tabs_options(self): product_detail_tabs = [ ("description", _("Description")), ("details", _("Details")), ("attributes", _("Attributes")), ("files", _("Files")), ] if has_installed("shuup_product_reviews"): product_detail_tabs.append(("product_reviews", _("Product reviews"))) return product_detail_tabs
def add_gdpr_consent_resources(context, content): if not valid_view(context): return request = context["request"] shop = get_shop(request) gdpr_settings = GDPRSettings.get_for_shop(shop) # GDPR not enabled, nothing to do if not gdpr_settings.enabled: return # always add styles add_resource(context, "head_end", static("shuup_gdpr/shuup_gdpr_styles.css")) user = request.user if not user.is_anonymous() and should_reconsent_privacy_policy(shop, user): consent_page = get_privacy_policy_page(shop) render_context = { "request": request, "csrf_token": context["csrf_token"], "url": "/%s" % consent_page.url, "accept_url": reverse("shuup:gdpr_policy_consent", kwargs=dict(page_id=consent_page.id)) } update_resource = InlineMarkupResource( loader.render_to_string("shuup/gdpr/privacy_policy_update.jinja", context=render_context)) add_resource(context, "body_end", update_resource) # consent already added if settings.SHUUP_GDPR_CONSENT_COOKIE_NAME in request.COOKIES: return gdpr_documents = [] if has_installed("shuup.simple_cms"): gdpr_documents = get_active_consent_pages(shop) render_context = { "request": request, "csrf_token": context["csrf_token"], "gdpr_settings": gdpr_settings, "gdpr_documents": gdpr_documents, "gdpr_cookie_categories": GDPRCookieCategory.objects.filter(shop=shop) } html_resource = InlineMarkupResource( loader.render_to_string("shuup/gdpr/gdpr_consent.jinja", context=render_context)) add_resource(context, "body_end", html_resource) add_resource(context, "body_end", static("shuup_gdpr/shuup_gdpr.js"))
def fields(self): fields = self._theme_fields + super(ShuupMegastoreTheme, self).get_base_fields() if has_installed("shuup_product_reviews"): fields.extend([ ("show_product_review", forms.BooleanField( required=False, initial=True, label=_("Show product reviews rating in product card."))) ]) return fields
def __init__(self, *args, **kwargs): self.request = kwargs.pop("request") super(CompanyRegistrationForm, self).__init__(*args, **kwargs) address_form_cls = cached_load('SHUUP_ADDRESS_MODEL_FORM') self.add_form_def('company', CompanyForm, kwargs={"request": self.request}) self.add_form_def('billing', address_form_cls) self.add_form_def('contact_person', ContactPersonForm) self.add_form_def('user_account', UserCreationForm) if has_installed("shuup.gdpr"): from shuup.gdpr.models import GDPRSettings if GDPRSettings.get_for_shop(self.request.shop).enabled: self.add_form_def('agreement', CompanyAgreementForm, kwargs=dict(shop=self.request.shop))
def add_gdpr_consent_resources(context, content): if not valid_view(context): return request = context["request"] shop = get_shop(request) gdpr_settings = GDPRSettings.get_for_shop(shop) # GDPR not enabled, nothing to do if not gdpr_settings.enabled: return # always add styles add_resource(context, "head_end", static("shuup-gdpr.css")) user = request.user if not user.is_anonymous() and should_reconsent_privacy_policy(shop, user): consent_page = get_privacy_policy_page(shop) render_context = { "request": request, "csrf_token": context["csrf_token"], "url": "/%s" % consent_page.url, "accept_url": reverse("shuup:gdpr_policy_consent", kwargs=dict(page_id=consent_page.id)) } update_resource = InlineMarkupResource( loader.render_to_string("shuup/gdpr/privacy_policy_update.jinja", context=render_context) ) add_resource(context, "body_end", update_resource) # consent already added if settings.SHUUP_GDPR_CONSENT_COOKIE_NAME in request.COOKIES: return gdpr_documents = [] if has_installed("shuup.simple_cms"): gdpr_documents = get_active_consent_pages(shop) render_context = { "request": request, "csrf_token": context["csrf_token"], "gdpr_settings": gdpr_settings, "gdpr_documents": gdpr_documents, "gdpr_cookie_categories": GDPRCookieCategory.objects.filter(shop=shop) } html_resource = InlineMarkupResource( loader.render_to_string("shuup/gdpr/gdpr_consent.jinja", context=render_context) ) add_resource(context, "body_end", html_resource) add_resource(context, "body_end", static("shuup-gdpr.js"))
def __init__(self, **kwargs): self.request = kwargs.pop("request") kwargs.setdefault("required_languages", ()) # No required languages here super(PageForm, self).__init__(**kwargs) self.fields["parent"].queryset = Page.objects.filter( shop=get_shop(self.request)) if has_installed("shuup.gdpr"): # remove page type field if GDPR is disabled or the page type is GDPR for existing object from shuup.gdpr.models import GDPRSettings if not GDPRSettings.get_for_shop(get_shop(self.request)).enabled: self.fields.pop("page_type") elif self.instance and self.instance.pk and self.instance.page_type == PageType.GDPR_CONSENT_DOCUMENT: self.fields.pop("page_type")
def add_resources(context, content): if has_installed("shuup_product_reviews"): return request = context.get("request") if request: match = request.resolver_match if match and match.app_name == "shuup_admin": return add_resource( context, "head_end", "%s?v=0.4.0.css" % static("shuup_vendor_reviews/shuup_vendor_reviews.css")) add_resource( context, "body_end", "%s?v=0.4.0.js" % static("shuup_vendor_reviews/shuup_vendor_reviews.js"))
def get_toolbar(self): if has_installed("shuup.gdpr"): if self.object and self.object.pk and self.object.page_type == PageType.GDPR_CONSENT_DOCUMENT: return Toolbar([ PostActionButton( icon="fa fa-save", form_id=self.get_save_form_id(), text=_("Publish New Version"), extra_css_class="btn-success", confirm= _("This action will publish a new version of this GDPR document. " + "All users should consent again to this new version. Are you sure?" )) ]) return super(PageEditView, self).get_toolbar()
def __init__(self, *args, **kwargs): super(EmailAuthenticationForm, self).__init__(*args, **kwargs) self.fields['username'].label = _("Username or email address") if has_installed("shuup.gdpr"): from shuup.gdpr.models import GDPRSettings if GDPRSettings.get_for_shop(self.request.shop).enabled: from shuup.simple_cms.models import Page, PageType for page in Page.objects.visible(self.request.shop).filter(page_type=PageType.REVISIONED): self.fields["accept_{}".format(page.id)] = forms.BooleanField( label=_("I have read and accept the {}").format(page.title), help_text=_("Read the <a href='{}' target='_blank'>{}</a>.").format( reverse("shuup:cms_page", kwargs=dict(url=page.url)), page.title ), error_messages=dict(required=_("You must accept to this to authenticate.")) )
def __init__(self, *args, **kwargs): self.request = kwargs.pop("request") super(PersonRegistrationForm, self).__init__(*args, **kwargs) if has_installed("shuup.gdpr"): from shuup.gdpr.models import GDPRSettings if GDPRSettings.get_for_shop(self.request.shop).enabled: from shuup.simple_cms.models import Page, PageType for page in Page.objects.visible(self.request.shop).filter(page_type=PageType.GDPR_CONSENT_DOCUMENT): self.fields["accept_{}".format(page.id)] = forms.BooleanField( label=_("I have read and accept the {}").format(page.title), help_text=_("Read the <a href='{}' target='_blank'>{}</a>.").format( reverse("shuup:cms_page", kwargs=dict(url=page.url)), page.title ), error_messages=dict(required=_("You must accept to this to register.")) )
def render_product_review_rating(self, product): if not has_installed("shuup_product_reviews"): return "" cache_key = "_product_review_rendered_rating_%d" % product.pk cached_rating = cache.get(cache_key) if cached_rating: return cached_rating from shuup_product_reviews.utils import render_product_review_ratings rendered = render_product_review_ratings(product) if rendered: cache.set(cache_key, rendered) return rendered return ""
def form_valid(self, form): for key, value in form.cleaned_data.items(): self.storage[key] = value self.process() order = self.create_order() self.checkout_process.complete() # Inform the checkout process it's completed if order.require_verification: response = redirect("shuup:order_requires_verification", pk=order.pk, key=order.key) else: response = redirect("shuup:order_process_payment", pk=order.pk, key=order.key) user = self.request.user if has_installed("shuup.gdpr") and user.is_authenticated(): from shuup.gdpr.utils import create_user_consent_for_all_documents create_user_consent_for_all_documents(order.shop, user) return response
def save(self): """ Create and configure the selected objects if needed """ # User wants a order notification and Notify installed and there is no script created previously if (self.is_valid() and self.cleaned_data["order_confirm_notification"] and djangoenv.has_installed("shuup.notify") and not self._get_saved_script()): from shuup.front.notify_events import OrderReceived from shuup.notify.models.script import Script from shuup.notify.script import Step, StepNext send_email_action = self._get_send_email_action() script = Script(event_identifier=OrderReceived.identifier, name="Order Received", enabled=True) script.set_steps([Step(next=StepNext.STOP, actions=(send_email_action,))]) script.save() # save the PK in the configs config.set(self.shop, BEHAVIOR_ORDER_CONFIRM_KEY, script.pk)
def update_stock(self, product_id): """ Supplier module update stock should always bump product cache and send `shuup.core.signals.stocks_updated` signal. """ supplier_id = self.supplier.pk sv, _ = StockCount.objects.get_or_create(supplier_id=supplier_id, product_id=product_id) if not sv.stock_managed: # item doesn't manage stocks return # TODO: Consider whether this should be done without a cache table values = get_current_stock_value(supplier_id=supplier_id, product_id=product_id) sv.logical_count = values["logical_count"] sv.physical_count = values["physical_count"] latest_event = ( StockAdjustment.objects .filter(supplier=supplier_id, product=product_id, type=StockAdjustmentType.INVENTORY) .last()) if latest_event: sv.stock_value_value = latest_event.purchase_price_value * sv.logical_count if self.supplier.stock_managed and has_installed("shuup.notify"): if sv.alert_limit and sv.physical_count < sv.alert_limit: product = Product.objects.filter(id=product_id).first() if product: from .notify_events import AlertLimitReached for shop in self.supplier.shops.all(): supplier_email = self.supplier.contact_address.email if self.supplier.contact_address else "" shop_email = shop.contact_address.email if shop.contact_address else "" AlertLimitReached( supplier=self.supplier, product=product, shop_email=shop_email, supplier_email=supplier_email ).run(shop=shop) sv.save(update_fields=("logical_count", "physical_count", "stock_value_value")) context_cache.bump_cache_for_product(Product.objects.get(id=product_id)) stocks_updated.send( type(self), shops=self.supplier.shops.all(), product_ids=[product_id], supplier=self.supplier)
def is_valid(self): if self.shop_product_id: errors = [] try: shop_product = ShopProduct.objects.get(pk=self.shop_product_id) except ShopProduct.DoesNotExist as e: errors.append(ValidationError(_('Invalid shop product.'), code="invalid-shop-product")) if has_installed("raven.contrib.django.raven_compat"): from raven.contrib.django.raven_compat.models import client client.captureException() if shop_product.shop != self.shop: errors.append(ValidationError(_('Invalid shop.'), code="invalid-shop")) errors.extend(list(shop_product.get_visibility_errors(self.customer))) for error in errors: self.add_error(None, error) return super(WishlistForm, self).is_valid()
def get_fields(self, **kwargs): request = kwargs.get("request", None) if not has_installed("shuup.gdpr") or not request: return [] gdpr_settings = GDPRSettings.get_for_shop(request.shop) if not gdpr_settings.enabled: return [] fields = [] for page in get_active_consent_pages(request.shop): key = "accept_{}".format(page.id) field = forms.BooleanField( label=mark_safe(ugettext( "I have read and accept the <a href='{}' target='_blank' class='gdpr_consent_doc_check'>{}</a>" ).format(reverse("shuup:cms_page", kwargs=dict(url=page.url)), page.title)), required=True, error_messages=dict(required=self.error_message) ) definition = FormFieldDefinition(name=key, field=field) fields.append(definition) return fields
def __init__(self, **kwargs): self.shop = kwargs.pop("shop") if not self.shop: raise ValueError("No shop provided") super(ContentWizardForm, self).__init__(**kwargs) if djangoenv.has_installed("shuup.simple_cms"): pages = self._get_installed_pages() self.fields["about_us"] = forms.BooleanField( label=_("Create About Us page"), required=False, initial=True, widget=forms.CheckboxInput(attrs={"disabled": (content_data.ABOUT_US_KEY in pages)}) ) # set the help text for different ocasions - whether the content is installed or not if content_data.ABOUT_US_KEY in pages: self.fields["about_us"].help_text = _("We have already created an 'About Us' template for you based " "on your shop information. You must review the page and " "change it accordingly.") else: self.fields["about_us"].help_text = _("We will create an 'About Us' template for you. " "We will base content of the page on your shop information. " "After we are done, you must review the page and " "change it accordingly.") self.fields["privacy_policy"] = forms.BooleanField( label=_("Create Privacy Policy page"), required=False, initial=True, widget=forms.CheckboxInput(attrs={"disabled": (content_data.PRIVACY_POLICY_KEY in pages)}) ) # set the help text for different ocasions - whether the content is installed or not if content_data.PRIVACY_POLICY_KEY in pages: self.fields["privacy_policy"].help_text = _("We have already created a 'Privacy Policy' template " "for you based on your shop information. " "You must review the page and change it accordingly.") else: self.fields["privacy_policy"].help_text = _("We will create a 'Privacy Policy' template for you. " "We will base content of the page on " "your shop information. After we are done, " "you must review the page and change it accordingly.") self.fields["terms_conditions"] = forms.BooleanField( label=_("Create Terms and Conditions page"), required=False, initial=True, widget=forms.CheckboxInput(attrs={"disabled": (content_data.TERMS_AND_CONDITIONS_KEY in pages)}), ) # set the help text for different ocasions - whether the content is installed or not if content_data.TERMS_AND_CONDITIONS_KEY in pages: self.fields["terms_conditions"].help_text = _("We have already created a 'Terms & Conditions' template " "for you based on your shop information. " "You must review the page and change it accordingly.") else: self.fields["terms_conditions"].help_text = _("We will create an 'Terms & Conditions' template " "for you. We will base content of the page on " "your shop information. After we are done, " "you must review the page and change it accordingly.") self.fields["refund_policy"] = forms.BooleanField( label=_("Create Refund Policy page"), required=False, initial=True, widget=forms.CheckboxInput(attrs={"disabled": (content_data.REFUND_POLICY_KEY in pages)}), ) # set the help text for different ocasions - whether the content is installed or not if content_data.REFUND_POLICY_KEY in pages: self.fields["refund_policy"].help_text = _("We have already created a 'Refund Policy' template " "for you based on your shop information. " "You must review the page and change it accordingly.") else: self.fields["refund_policy"].help_text = _("We will create an 'Refund Policy' template for you. " "We will base content of the page on your shop information. " "After we are done, you must review the page and " "change it accordingly.") if djangoenv.has_installed("shuup.xtheme"): from shuup.xtheme.models import SavedViewConfig svc_pk = config.get(self.shop, CONTENT_FOOTER_KEY) svc = SavedViewConfig.objects.filter(pk=svc_pk).first() self.fields["configure_footer"] = forms.BooleanField( label=_("Configure the footer"), required=False, initial=True, widget=forms.CheckboxInput(attrs={"disabled": bool(svc)}), help_text=_("We will now configure your shop footer and fill it with some of your shop's information. " "Don't worry, you can change this at any time.") )
from logging import getLogger from django import forms from django.conf import settings from django.template import loader as template_loader from django.utils import translation from django.utils.encoding import force_text from django.utils.translation import ugettext_lazy as _ from shuup import configuration as config from shuup.utils import djangoenv from . import data as content_data # tries to import xtheme stuff if djangoenv.has_installed("shuup.xtheme"): from shuup.xtheme import XTHEME_GLOBAL_VIEW_NAME from shuup.xtheme.plugins.snippets import SnippetsPlugin from shuup.xtheme.models import SavedViewConfig, SavedViewConfigStatus from shuup.xtheme.layout import Layout from shuup.xtheme._theme import get_current_theme logger = getLogger(__name__) BEHAVIOR_ORDER_CONFIRM_KEY = "behavior_order_confirm_script_pk" CONTENT_FOOTER_KEY = "content_footer_pk" class BehaviorWizardForm(forms.Form): order_confirm_notification = forms.BooleanField(label=_("Send customer order confirmation email"),