def __init__(self, *args, **kwargs): from shuup.admin.modules.settings import consts from shuup.admin.modules.settings.enums import OrderReferenceNumberMethod shop = kwargs.pop("shop") kwargs["initial"] = { consts.ORDER_REFERENCE_NUMBER_LENGTH_FIELD: configuration.get( shop, consts.ORDER_REFERENCE_NUMBER_LENGTH_FIELD, settings.SHUUP_REFERENCE_NUMBER_LENGTH), consts.ORDER_REFERENCE_NUMBER_PREFIX_FIELD: configuration.get( shop, consts.ORDER_REFERENCE_NUMBER_PREFIX_FIELD, settings.SHUUP_REFERENCE_NUMBER_PREFIX), } super(ShopOrderConfigurationForm, self).__init__(*args, **kwargs) reference_method = configuration.get( shop, consts.ORDER_REFERENCE_NUMBER_METHOD_FIELD, settings.SHUUP_REFERENCE_NUMBER_METHOD) self.prefix_disabled = (reference_method in [OrderReferenceNumberMethod.UNIQUE.value, OrderReferenceNumberMethod.SHOP_RUNNING.value]) self.fields[consts.ORDER_REFERENCE_NUMBER_PREFIX_FIELD].disabled = self.prefix_disabled decimal_places = 2 # default if shop.currency in babel.core.get_global('currency_fractions'): decimal_places = babel.core.get_global('currency_fractions')[shop.currency][0] self.fields[ORDER_MIN_TOTAL_CONFIG_KEY] = FormattedDecimalFormField( label=_("Order minimum total"), decimal_places=decimal_places, max_digits=FORMATTED_DECIMAL_FIELD_MAX_DIGITS, min_value=0, required=False, initial=configuration.get(shop, ORDER_MIN_TOTAL_CONFIG_KEY, Decimal(0)), help_text=_("The minimum sum that an order needs to reach to be created.") )
def test_simple_set_and_get_without_shop(): configuration.set(None, "answer", 42) assert configuration.get(None, "answer") == 42 assert configuration.get(None, "non-existing") is None configuration.set(None, "non-existing", "hello") assert configuration.get(None, "non-existing") == "hello"
def assert_config_value(rf, admin_user, form_id, key, value, expected_value, shop=None): if not shop: shop = get_default_shop() request = apply_request_middleware(rf.get("/"), user=admin_user) view_func = SystemSettingsView.as_view() response = view_func(request) assert response.status_code == 200 form_field = "%s-%s" % (form_id, key) data = {form_field: value} request = apply_request_middleware(rf.post("/", data=data), user=admin_user) response = view_func(request) assert response.status_code == 302 if expected_value == "unset": expected_value = value assert configuration.get(None, key) == expected_value assert len(messages.get_messages(request)) == 1 # Double save the form and the configuration should still be unchanged response = view_func(request) assert response.status_code == 302 assert configuration.get(None, key) == expected_value assert len(messages.get_messages(request)) == 2 return shop
def test_view_default_columns(rf, admin_user): shop = get_default_shop() view = ProductListView.as_view() request = apply_request_middleware(rf.get("/", { "jq": json.dumps({"perPage": 100, "page": 1}) }), user=admin_user) response = view(request) assert 200 <= response.status_code < 300 listview = ProductListView() assert listview.settings.default_columns == listview.default_columns column_names = [c.id for c in sorted(listview.columns, key=lambda x: x.id)] default_column_names = [c.id for c in sorted(listview.default_columns, key=lambda x: x.id)] assert column_names == default_column_names assert configuration.get(None, "view_configuration_shopproduct_name") # name is configured assert listview.settings.view_configured() assert listview.settings.get_settings_key("name") == "view_configuration_shopproduct_name" # we are attached to product view settings_view = ListSettingsView.as_view() view_data = {"model": "ShopProduct", "module": "shuup.core.models", "return_url": "shop_product"} request = rf.get("/", view_data) response = settings_view(request) assert 200 <= response.status_code < 300 # Change configuration by posting form request = rf.post("/?" + urlencode(view_data), {"view_configuration_shopproduct_name": False}) response = settings_view(request) assert response.status_code == 302 assert listview.settings.get_config("name") == configuration.get(None, "view_configuration_shopproduct_name") assert not configuration.get(None, "view_configuration_shopproduct_name").get("active")
def test_global_configurations(): with override_settings(CACHES={ 'default': { 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', 'LOCATION': 'test_global_configurations', } }): cache.init_cache() shop = get_default_shop() configuration.set(None, "key1", {"data": "test1"}) configuration.set(shop, "key2", {"data": "test2"}) # key1 from shop should come from global configuration assert configuration.get(shop, "key1").get("data") == "test1" # key2 shouldn't be in global configurations assert configuration.get(None, "key2") is None # Update global configuration configuration.set(None, "key1", {"data": "test_bump"}) assert configuration.get(shop, "key1").get("data") == "test_bump" # Override shop data for global key1 configuration.set(shop, "key1", "test_data") assert configuration.get(shop, "key1") == "test_data" # Update shop configuration for global key1 configuration.set(shop, "key1", "test_data1") assert configuration.get(shop, "key1") == "test_data1"
def test_simple_set_and_get_cascading(): with override_settings(CACHES={ 'default': { 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', 'LOCATION': 'test_simple_set_and_get_cascading', } }): cache.init_cache() shop = get_default_shop() configuration.set(None, "answer", 42) assert configuration.get(None, "answer") == 42 assert configuration.get(shop, "answer", 42) assert configuration.get(None, "non-existing") is None assert configuration.get(shop, "non-existing") is None configuration.set(shop, "non-existing", "hello") assert configuration.get(None, "non-existing") is None assert configuration.get(shop, "non-existing") == "hello" assert configuration.get(None, "foo") is None assert configuration.get(shop, "foo") is None configuration.set(None, "foo", "bar") configuration.set(shop, "foo", "baz") assert configuration.get(None, "foo") == "bar" assert configuration.get(shop, "foo") == "baz"
def test_simple_set_and_get_with_shop(): shop = get_default_shop() configuration.set(shop, "answer", 42) assert configuration.get(shop, "answer") == 42 assert configuration.get(shop, "non-existing") is None configuration.set(shop, "non-existing", "hello") assert configuration.get(shop, "non-existing") == "hello"
def test_configuration_gets_saved(): configuration.set(None, "x", 1) assert configuration.get(None, "x") == 1 configuration.set(None, "x", 2) assert configuration.get(None, "x") == 2 configuration.set(None, "x", 3) assert configuration.get(None, "x") == 3 conf_item = ConfigurationItem.objects.get(shop=None, key="x") assert conf_item.value == 3
def is_valid(self): shipping_required = configuration.get(self.request.shop, SHIPPING_METHOD_REQUIRED_CONFIG_KEY, True) payment_required = configuration.get(self.request.shop, PAYMENT_METHOD_REQUIRED_CONFIG_KEY, True) if shipping_required and not self.storage.get("shipping_method_id"): return False if payment_required and not self.storage.get("payment_method_id"): return False return True
def get_configuration(shop=None, category=None, force_category_override=False): default_configuration = configuration.get( shop, FACETED_DEFAULT_CONF_KEY, settings.SHUUP_FRONT_DEFAULT_SORT_CONFIGURATION) category_config = configuration.get(None, _get_category_configuration_key(category)) # when override_default_configuration is True, we override the default configuration if category_config and (category_config.get("override_default_configuration") or force_category_override): return category_config return default_configuration
def test_configuration_cache(): cache.clear() shop = get_default_shop() configuration.set(None, "key1", "test1") configuration.set(shop, "key2", "test2") # Shop configurations cache should be bumped assert cache.get(configuration._get_cache_key(shop)) is None configuration.get(shop, "key1") # Now shop configurations and key2 should found from cache assert cache.get(configuration._get_cache_key(shop)).get("key2") == "test2"
def test_configuration_update(): cache.clear() shop = get_default_shop() configuration.set(shop, "key1", {"data": "test1"}) configuration.set(shop, "key2", {"data": "test2"}) configuration.set(shop, "key3", {"data": "test3"}) assert configuration.get(shop, "key1").get("data") == "test1" assert configuration.get(shop, "key3").get("data") == "test3" # Update configuration configuration.set(shop, "key3", {"data": "test_bump"}) assert configuration.get(shop, "key3").get("data") == "test_bump"
def get_running_reference_number(order): from shuup import configuration from shuup.admin.modules.settings.consts import (ORDER_REFERENCE_NUMBER_PREFIX_FIELD, ORDER_REFERENCE_NUMBER_LENGTH_FIELD) value = Counter.get_and_increment(CounterType.ORDER_REFERENCE) prefix = "%s" % configuration.get( order.shop, ORDER_REFERENCE_NUMBER_PREFIX_FIELD, settings.SHUUP_REFERENCE_NUMBER_PREFIX) ref_length = configuration.get( order.shop, ORDER_REFERENCE_NUMBER_LENGTH_FIELD, settings.SHUUP_REFERENCE_NUMBER_LENGTH) padded_value = force_text(value).rjust(ref_length - len(prefix), "0") reference_no = "%s%s" % (prefix, padded_value) return reference_no + calc_reference_number_checksum(reference_no)
def get_form_defs(self): if not self.object.pk: return initial = { "shipping_method_required": configuration.get(self.object, SHIPPING_METHOD_REQUIRED_CONFIG_KEY, True), "payment_method_required": configuration.get(self.object, PAYMENT_METHOD_REQUIRED_CONFIG_KEY, True) } yield TemplatedFormDef( name=self.name, form_class=self.form, template_name="shuup/front/admin/checkout.jinja", required=True, kwargs={"initial": initial} )
def _handle_xtheme_save(self): svc_pk = config.get(self.shop, CONTENT_FOOTER_KEY) svc = SavedViewConfig.objects.filter(pk=svc_pk).first() theme = get_current_theme(self.shop) if not svc and theme: context = {"shop": self.shop} rendered_content = template_loader.render_to_string(content_data.FOOTER_TEMPLATE, context).strip() layout = Layout(theme, "footer-bottom") # adds the footer template layout.begin_row() layout.begin_column({"md": 12}) layout.add_plugin(SnippetsPlugin.identifier, {"in_place": rendered_content}) svc = SavedViewConfig( theme_identifier=theme.identifier, shop=self.shop, view_name=XTHEME_GLOBAL_VIEW_NAME, status=SavedViewConfigStatus.CURRENT_DRAFT ) svc.set_layout_data(layout.placeholder_name, layout) svc.save() svc.publish() config.set(self.shop, CONTENT_FOOTER_KEY, svc.pk)
def toggle_all_seeing_for_user(user): if not getattr(user, "is_superuser", False): return all_seeing_key = ALL_SEEING_FORMAT % {"user_id": user.pk} is_all_seeing = configuration.get(None, all_seeing_key, False) configuration.set(None, all_seeing_key, not is_all_seeing)
def test_configuration_gets_saved(): with override_settings(CACHES={ 'default': { 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', 'LOCATION': 'test_configuration_gets_saved', } }): cache.init_cache() configuration.set(None, "x", 1) assert configuration.get(None, "x") == 1 configuration.set(None, "x", 2) assert configuration.get(None, "x") == 2 configuration.set(None, "x", 3) assert configuration.get(None, "x") == 3 conf_item = ConfigurationItem.objects.get(shop=None, key="x") assert conf_item.value == 3
def save(self, commit=True): company = self.forms['company'].save(commit=False) billing_address = self.forms['billing'].save(commit=False) person = self.forms['contact_person'].save(commit=False) user = self.forms['user_account'].save(commit=False) company.default_billing_address = billing_address company.default_shipping_address = billing_address for field in ['name', 'name_ext', 'email', 'phone']: setattr(billing_address, field, getattr(company, field)) person.user = user user.first_name = person.first_name user.last_name = person.last_name user.email = person.email # If company registration requires approval, # company and person contacts will be created as inactive if configuration.get(None, "company_registration_requires_approval"): company.is_active = False person.is_active = False if commit: user.save() person.user = user person.save() billing_address.save() company.default_billing_address = billing_address company.default_shipping_address = billing_address company.save() company.members.add(person) return user
def get_language_choices(shop=None): """ Returns a list of the available language choices, e.g.: [("en", "English", "English"]) If shot is passed, the languages will be filtered by those enabled for the shop. :rtype iterable[(str, str, str)] """ available_languages = [] languages = [] if shop: available_languages = configuration.get(shop, FRONT_AVAILABLE_LANGUAGES_CONFIG_KEY) if available_languages: available_languages = available_languages.split(",") for code, name in settings.LANGUAGES: if available_languages and code not in available_languages: continue lang_info = get_language_info(code) name_in_current_lang = ugettext(name) local_name = lang_info["name_local"] languages.append((code, name_in_current_lang, local_name)) return languages
def get_unique_reference_number(shop, id): from shuup import configuration from shuup.admin.modules.settings.consts import ORDER_REFERENCE_NUMBER_LENGTH_FIELD now = datetime.datetime.now() ref_length = configuration.get(shop, ORDER_REFERENCE_NUMBER_LENGTH_FIELD, settings.SHUUP_REFERENCE_NUMBER_LENGTH) dt = ("%06s%07d%04d" % (now.strftime("%y%m%d"), now.microsecond, id % 1000)).rjust(ref_length, "0") return dt + calc_reference_number_checksum(dt)
def get_methods_validation_errors(self): shipping_methods = self.get_available_shipping_methods() payment_methods = self.get_available_payment_methods() advice = _( "Try to remove some products from the basket " "and order them separately.") if (self.has_shippable_lines() and not shipping_methods and configuration.get(self.shop, SHIPPING_METHOD_REQUIRED_CONFIG_KEY, True)): msg = _("Products in basket cannot be shipped together. %s") yield ValidationError(msg % advice, code="no_common_shipping") if not payment_methods and configuration.get(self.shop, PAYMENT_METHOD_REQUIRED_CONFIG_KEY, True): msg = _("Products in basket have no common payment method. %s") yield ValidationError(msg % advice, code="no_common_payment")
def get_validation_errors(self): # check for the minimum sum of order total min_total = configuration.get(self.shop, ORDER_MIN_TOTAL_CONFIG_KEY, Decimal(0)) total = (self.taxful_total_price.value if self.shop.prices_include_tax else self.taxless_total_price.value) if total < min_total: min_total_price = format_money(self.shop.create_price(min_total)) yield ValidationError(_("The total should be greater than {} to be ordered.").format(min_total_price), code="order_total_too_low") shipping_method = self.shipping_method payment_method = self.payment_method if shipping_method: for error in shipping_method.get_unavailability_reasons(source=self): yield error if payment_method: for error in payment_method.get_unavailability_reasons(source=self): yield error for supplier in self._get_suppliers(): for product, quantity in iteritems(self._get_products_and_quantities(supplier)): shop_product = product.get_shop_instance(shop=self.shop) if not shop_product: yield ValidationError( _("%s not available in this shop") % product.name, code="product_not_available_in_shop" ) for error in shop_product.get_orderability_errors( supplier=supplier, quantity=quantity, customer=self.customer): error.message = "%s: %s" % (product.name, error.message) yield error
def test_consolidate_objects(rf): get_default_shop() # just visit to make sure GET is ok request = apply_request_middleware(rf.get("/")) response = APIPermissionView.as_view()(request) assert response.status_code == 200 perm_key = make_permission_config_key(UserViewSet()) assert configuration.get(None, perm_key) is None # now post the form to see what happens request = apply_request_middleware(rf.post("/", {perm_key: PermissionLevel.ADMIN})) response = APIPermissionView.as_view()(request) assert response.status_code == 302 # good assert int(configuration.get(None, perm_key)) == PermissionLevel.ADMIN
def toggle_all_seeing(request): return_url = request.META["HTTP_REFERER"] if not request.user.is_superuser: return HttpResponseRedirect(return_url) all_seeing_key = "is_all_seeing:%d" % request.user.pk is_all_seeing = not configuration.get(None, all_seeing_key, False) configuration.set(None, all_seeing_key, is_all_seeing) return HttpResponseRedirect(return_url)
def test_behavior_form(): shop = get_default_shop() assert Script.objects.count() == 0 assert configuration.get(shop, BEHAVIOR_ORDER_CONFIRM_KEY) is None form = BehaviorWizardForm(shop=shop, data={"order_confirm_notification": True}) assert form._get_saved_script() is None form.save() # check if the form creates a order notification correctely script = Script.objects.first() assert script.pk == configuration.get(shop, BEHAVIOR_ORDER_CONFIRM_KEY) assert form._get_saved_script().pk == script.pk assert len(script.get_steps()) == 1 step = script.get_steps()[0] step_data = step.serialize() assert step_data["next"] == StepNext.STOP.value action = step._actions[0] assert isinstance(action, SendEmail) action_data = action.serialize() assert action_data["recipient"]["variable"] == "customer_email" assert action_data["language"]["variable"] == "language" lang = translation.get_language() assert action_data["fallback_language"]["constant"] == lang assert action_data["template_data"][lang]["content_type"] == "html" assert action_data["template_data"][lang]["subject"] == force_text(data.ORDER_CONFIRMATION["subject"]) context = {"shop": shop} content = loader.render_to_string(data.ORDER_CONFIRMATION["body_template"], context).strip() assert action_data["template_data"][lang]["body"] == content # the widget must be disabled form = BehaviorWizardForm(shop=shop, data={"order_confirm_notification": True}) assert form.fields["order_confirm_notification"].widget.attrs["disabled"] is True # clear scripts Script.objects.all().delete() configuration.set(shop, BEHAVIOR_ORDER_CONFIRM_KEY, None) # save the form but do not create the order confirmation notification form = BehaviorWizardForm(shop=shop, data={"order_confirm_notification": False}) form.save() # nothing created assert Script.objects.count() == 0 assert configuration.get(shop, BEHAVIOR_ORDER_CONFIRM_KEY) is None
def test_configuration_update(): with override_settings(CACHES={ 'default': { 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', 'LOCATION': 'test_configuration_update', } }): cache.init_cache() shop = get_default_shop() configuration.set(shop, "key1", {"data": "test1"}) configuration.set(shop, "key2", {"data": "test2"}) configuration.set(shop, "key3", {"data": "test3"}) assert configuration.get(shop, "key1").get("data") == "test1" assert configuration.get(shop, "key3").get("data") == "test3" # Update configuration configuration.set(shop, "key3", {"data": "test_bump"}) assert configuration.get(shop, "key3").get("data") == "test_bump"
def get_global_configuration(name, default=None): """ Get global configuration variable value. :type name: str :type default: Any """ from shuup import configuration return configuration.get(None, name, default)
def test_configuration_cache(): with override_settings(CACHES={ 'default': { 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', 'LOCATION': 'test_configuration_cache', } }): cache.init_cache() shop = get_default_shop() configuration.set(None, "key1", "test1") configuration.set(shop, "key2", "test2") # Shop configurations cache should be bumped assert cache.get(configuration._get_cache_key(shop)) is None configuration.get(shop, "key1") # Now shop configurations and key2 should found from cache assert cache.get(configuration._get_cache_key(shop)).get("key2") == "test2"
def test_simple_set_and_get_cascading(): shop = get_default_shop() configuration.set(None, "answer", 42) assert configuration.get(None, "answer") == 42 assert configuration.get(shop, "answer", 42) assert configuration.get(None, "non-existing") is None assert configuration.get(shop, "non-existing") is None configuration.set(shop, "non-existing", "hello") assert configuration.get(None, "non-existing") is None assert configuration.get(shop, "non-existing") == "hello" assert configuration.get(None, "foo") is None assert configuration.get(shop, "foo") is None configuration.set(None, "foo", "bar") configuration.set(shop, "foo", "baz") assert configuration.get(None, "foo") == "bar" assert configuration.get(shop, "foo") == "baz"
def get_shop_language_choices(context): request = context["request"] languages = [] for code, name in configuration.get(request.shop, "languages", settings.LANGUAGES): lang_info = get_language_info(code) name_in_current_lang = ugettext(name) local_name = lang_info["name_local"] languages.append((code, name_in_current_lang, local_name)) return languages
def setup_wizard_complete(request): """ Check if shop wizard should be run. :return: whether setup wizard needs to be run :rtype: boolean """ if getattr(settings, "SHUUP_ENABLE_MULTIPLE_SHOPS", False): # setup wizard is only applicable in single shop mode return True shop = request.shop complete = configuration.get(shop, "setup_wizard_complete") if complete is None: return not setup_wizard_visible_panes(shop) return complete
def __init__(self, name, form_class, template_name, request, extra_js=""): shop = request.shop form_def_kwargs = { "name": name, "kwargs": { "instance": form_class._meta.model.objects.first(), "languages": configuration.get(shop, "languages", settings.LANGUAGES) } } super(ServiceWizardFormDef, self).__init__( form_class=form_class, template_name=template_name, extra_js=extra_js, **form_def_kwargs )
def set_reference_method(rf, admin_user, reference_method, shop=None): if not shop: shop = get_default_shop() request = apply_request_middleware(rf.get("/"), user=admin_user) view_func = SystemSettingsView.as_view() response = view_func(request) assert response.status_code == 200 data = { "order_settings-order_reference_number_method": reference_method.value } request = apply_request_middleware(rf.post("/", data=data), user=admin_user) view_func(request) assert configuration.get(None, consts.ORDER_REFERENCE_NUMBER_METHOD_FIELD) == reference_method.value return shop
def test_view_default_columns(rf, admin_user): shop = get_default_shop() view = ProductListView.as_view() request = apply_request_middleware(rf.get("/", {"jq": json.dumps({"perPage": 100, "page": 1})}), user=admin_user) response = view(request) assert 200 <= response.status_code < 300 listview = ProductListView() assert listview.settings.default_columns == listview.default_columns column_names = [c.id for c in sorted(listview.columns, key=lambda x: x.id)] default_column_names = [c.id for c in sorted(listview.default_columns, key=lambda x: x.id)] assert column_names == default_column_names assert configuration.get(None, "view_configuration_shopproduct_product_name") # name is configured assert listview.settings.view_configured() assert ( listview.settings.get_settings_key("product_name") == "view_configuration_shopproduct_product_name" ) # we are attached to product view settings_view = ListSettingsView.as_view() view_data = {"model": "ShopProduct", "module": "shuup.core.models", "return_url": "shop_product"} request = rf.get("/", view_data) response = settings_view(request) assert 200 <= response.status_code < 300 # Change configuration by posting form request = rf.post("/?" + urlencode(view_data), {"view_configuration_shopproduct_product_name": False}) response = settings_view(request) assert response.status_code == 302 assert listview.settings.get_config("product_name") == configuration.get( None, "view_configuration_shopproduct_product_name" ) assert not configuration.get(None, "view_configuration_shopproduct_product_name").get("active")
def test_configuration_set_and_get(): with override_settings(CACHES={ 'default': { 'BACKEND': 'django.core.cache.backends.locmem.LocMemCache', 'LOCATION': 'test_configuration_set_and_get', } }): cache.init_cache() shop = get_default_shop() test_conf_data = {"data": "test"} configuration.set(shop, "key", test_conf_data) # Get the configuration via configuration API assert configuration.get(shop, "key") == test_conf_data # Check that configuration is saved to database assert ConfigurationItem.objects.get(shop=shop, key="key").value == test_conf_data
def get_validation_errors(cls, order_source): # check for the minimum sum of order total min_total = configuration.get(order_source.shop, ORDER_MIN_TOTAL_CONFIG_KEY, Decimal(0)) if order_source.shop.prices_include_tax: total = order_source.taxful_total_price.value else: total = order_source.taxless_total_price.value if total < min_total: min_total_price = format_money( order_source.shop.create_price(min_total)) msg = _("The total price should be greater than {} to be ordered." ).format(min_total_price) yield ValidationError(msg, code="order_total_too_low")
def assert_config_value(rf, admin_user, form_id, key, value, expected_value, shop=None): if not shop: shop = get_default_shop() request = apply_request_middleware(rf.get("/"), user=admin_user) view_func = SystemSettingsView.as_view() response = view_func(request) assert response.status_code == 200 form_field = "%s-%s" % (form_id, key) data = {form_field: value} request = apply_request_middleware(rf.post("/", data=data)) response = view_func(request) assert response.status_code == 302 if expected_value == "unset": expected_value = value assert configuration.get(None, key) == expected_value return shop
def __init__(self, name, form_class, template_name, extra_js="", kwargs={}): kwargs.update({ "instance": form_class._meta.model.objects.first(), "languages": configuration.get(Shop.objects.first(), "languages", settings.LANGUAGES) }) form_def_kwargs = {"name": name, "kwargs": kwargs} super(ServiceWizardFormDef, self).__init__(form_class=form_class, template_name=template_name, extra_js=extra_js, **form_def_kwargs)
def get_form_defs(self): return [ TemplatedWizardFormDef( name="shop", template_name="shuup/admin/shops/_wizard_base_shop_form.jinja", extra_js="shuup/admin/shops/_wizard_base_shop_script.jinja", form_class=ShopWizardForm, kwargs={ "instance": self.object, "languages": configuration.get(self.object, "languages", settings.LANGUAGES) }), WizardFormDef(name="address", form_class=ShopAddressWizardForm, kwargs={"instance": self.object.contact_address}) ]
def get_reference_number(order): from shuup import configuration from shuup.admin.modules.settings.consts import ORDER_REFERENCE_NUMBER_METHOD_FIELD if order.reference_number: raise ValueError("Error! Order passed to function `get_reference_number()` already has a reference number.") reference_number_method = configuration.get( order.shop, ORDER_REFERENCE_NUMBER_METHOD_FIELD, settings.SHUUP_REFERENCE_NUMBER_METHOD) if reference_number_method == "unique": return get_unique_reference_number_for_order(order) elif reference_number_method == "running": return get_running_reference_number(order) elif reference_number_method == "shop_running": return get_shop_running_reference_number(order) elif callable(reference_number_method): return reference_number_method(order) else: getter = load(reference_number_method, "Reference number generator") return getter(order)
def get_validation_errors(self): # noqa (C901) # check for the minimum sum of order total min_total = configuration.get(self.shop, ORDER_MIN_TOTAL_CONFIG_KEY, Decimal(0)) total = (self.taxful_total_price.value if self.shop.prices_include_tax else self.taxless_total_price.value) if total < min_total: min_total_price = format_money(self.shop.create_price(min_total)) yield ValidationError( _("The total should be greater than {} to be ordered.").format( min_total_price), code="order_total_too_low") shipping_method = self.shipping_method payment_method = self.payment_method if shipping_method: for error in shipping_method.get_unavailability_reasons( source=self): yield error if payment_method: for error in payment_method.get_unavailability_reasons( source=self): yield error for supplier in self._get_suppliers(): for product, quantity in iteritems( self._get_products_and_quantities(supplier)): try: shop_product = product.get_shop_instance(shop=self.shop) except ShopProduct.DoesNotExist: yield ValidationError(_("%s not available in this shop") % product.name, code="product_not_available_in_shop") continue for error in shop_product.get_orderability_errors( supplier=supplier, quantity=quantity, customer=self.customer): error.message = "%s: %s" % (product.name, error.message) yield error
def save(self, commit=True): company = self.forms['company'].save(commit=False) billing_address = self.forms['billing'].save(commit=False) person = self.forms['contact_person'].save(commit=False) user = self.forms['user_account'].save(commit=False) company.default_billing_address = billing_address company.default_shipping_address = billing_address for field in ['name', 'name_ext', 'email', 'phone']: setattr(billing_address, field, getattr(company, field)) person.user = user user.first_name = person.first_name user.last_name = person.last_name user.email = person.email # If company registration requires approval, # company and person contacts will be created as inactive if configuration.get(None, "company_registration_requires_approval"): company.is_active = False person.is_active = False if commit: user.save() person.user = user person.save() person.shops.add(self.request.shop) billing_address.save() company.default_billing_address = billing_address company.default_shipping_address = billing_address company.save() company.shops.add(self.request.shop) company.members.add(person) 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 _send_telemetry(request, max_age_hours, force_send=False): if not is_telemetry_enabled(): raise TelemetryNotSent("Error! Telemetry not enabled.", "disabled") if not force_send: if is_opt_out(): raise TelemetryNotSent("Error! Telemetry is opted-out.", "optout") if is_in_grace_period(): raise TelemetryNotSent("Error! Telemetry in grace period.", "grace") if max_age_hours is not None: last_send_time = get_last_submission_time() if last_send_time and (now() - last_send_time ).total_seconds() <= max_age_hours * 60 * 60: raise TelemetryNotSent("Trying to resend too soon", "age") data = get_telemetry_data(request) try: resp = requests.post(url=settings.SHUUP_TELEMETRY_URL, data=data, timeout=5) if (not settings.DEBUG and resp.status_code == 200 and resp.json().get("support_id") and not configuration.get(None, "shuup_support_id")): configuration.set(None, "shuup_support_id", resp.json().get("support_id")) except Exception as exc: data = { "data": data, "error": force_text(exc), } else: data = { "data": data, "response": force_text(resp.content, errors="replace"), "status": resp.status_code, } save_telemetry_submission(data) return data
def form_valid(self, form): company = form["contact"].save(commit=False) is_new = not bool(company.pk) company.save() user = self.request.user person = get_person_contact(user) company.members.add(person) billing_address = form["billing"].save() shipping_address = form["shipping"].save() if billing_address.pk != company.default_billing_address_id: # Identity changed due to immutability company.default_billing_address = billing_address if shipping_address.pk != company.default_shipping_address_id: # Identity changed due to immutability company.default_shipping_address = shipping_address user.email = company.email user.first_name = company.name user.last_name = "" user.save() message = _("Company information saved successfully.") # If company registration requires activation, # company will be created as inactive. if is_new and configuration.get( None, "company_registration_requires_approval"): company.is_active = False message = _( "Company information saved successfully. " "Please follow the instructions sent to your email address.") company.save() if is_new: user_registered.send(sender=self.__class__, user=self.request.user, request=self.request) CompanyAccountCreated(contact=company, customer_email=company.email).run() messages.success(self.request, message) return redirect("shuup:company_edit")
def has_permission(self, request, view): try: permission = int(configuration.get(None, make_permission_config_key(view), DEFAULT_PERMISSION)) except ValueError: permission = DEFAULT_PERMISSION # god mode - just works if API is not disabled if request.user.is_superuser: return (permission <= PermissionLevel.ADMIN) # safe requests: GET, HEAD, OPTIONS if request.method in permissions.SAFE_METHODS: # to READ, the permissions can be WRITE or READ return ((request.user.is_authenticated() and permission <= PermissionLevel.AUTHENTICATED_WRITE) or permission <= PermissionLevel.PUBLIC_WRITE) # NOT safe: POST, PUT, DELETE else: # to change data, permission must be exactly WRITE if request.user.is_authenticated(): return permission in (PermissionLevel.AUTHENTICATED_WRITE, PermissionLevel.PUBLIC_WRITE) return (permission == PermissionLevel.PUBLIC_WRITE)
def __init__(self, **kwargs): super(APIPermissionForm, self).__init__(**kwargs) # create a choice field for each entry in the router # this way it will be easy to set permisions based on each viewset # but they must be beautifully configured with name and description # to become more presentable to the merchant for __, viewset, basename in api_urls.router.registry: viewset_instance = viewset() field_name = make_permission_config_key(viewset_instance) initial = configuration.get(None, field_name, DEFAULT_PERMISSION) if issubclass(viewset, PermissionHelperMixin): help_text = viewset.get_help_text() else: help_text = viewset_instance.get_view_description() self.fields[field_name] = forms.ChoiceField( label=(viewset_instance.get_view_name() or basename), help_text=help_text, initial=initial, required=False, choices=self.API_PERMISSION_CHOICES)
def test_form(rf, admin_user, default_shop): configuration.cache.clear() assert not configuration.get(default_shop, MC_API) assert not configuration.get(default_shop, MC_USERNAME) assert not configuration.get(default_shop, MC_LIST_ID) form = ConfigurationForm(shop=default_shop, data={ "api_key": MC_API_KEY, "list_id": MC_API_LIST_ID, "username": MC_API_USERNAME, }) form.full_clean() form.save() configuration.cache.clear() assert configuration.get(default_shop, MC_API) == MC_API_KEY assert configuration.get(default_shop, MC_USERNAME) == MC_API_USERNAME assert configuration.get(default_shop, MC_LIST_ID) == MC_API_LIST_ID
def _handle_xtheme_save(self): svc_pk = config.get(self.shop, CONTENT_FOOTER_KEY) svc = SavedViewConfig.objects.filter(pk=svc_pk).first() theme = get_current_theme() if not svc and theme: context = {"shop": self.shop} rendered_content = template_loader.render_to_string(content_data.FOOTER_TEMPLATE, context).strip() layout = Layout(theme, "footer-bottom") # adds the footer template layout.begin_row() layout.begin_column({"md": 12}) layout.add_plugin(SnippetsPlugin.identifier, {"in_place": rendered_content}) svc = SavedViewConfig( theme_identifier=theme.identifier, view_name=XTHEME_GLOBAL_VIEW_NAME, status=SavedViewConfigStatus.CURRENT_DRAFT ) svc.set_layout_data(layout.placeholder_name, layout) svc.save() svc.publish() config.set(self.shop, CONTENT_FOOTER_KEY, svc.pk)
def set_configuration(self, request, menus): config_key = CUSTOM_ADMIN_MENU_USER_PREFIX.format(request.user.pk) configuration_object = configuration.get(None, config_key, {}) or {} configuration_object.update({get_language(): menus}) configuration.set(None, config_key, configuration_object)
def get_configuration(shop=None, category=None): default_configuration = configuration.get( shop, FACETED_DEFAULT_CONF_KEY, settings.SHUUP_FRONT_DEFAULT_SORT_CONFIGURATION) return (configuration.get(None, _get_category_configuration_key(category)) or default_configuration)
def dispatch(self, request, *args, **kwargs): if not configuration.get(None, "allow_company_registration"): return HttpResponseNotFound() return super(CompanyRegistrationView, self).dispatch(request, *args, **kwargs)
def language(self): if self._language is not None: return self._language return configuration.get(None, "default_contact_language", settings.LANGUAGE_CODE)
def get_support_id(context): support_id = None if is_telemetry_enabled(): support_id = configuration.get(None, "shuup_support_id") return support_id
def get_installed_carousel(shop): """ Returns the installed sample carousel """ return configuration.get(shop, SAMPLE_CAROUSEL_KEY)
def set_configuration(self, request, menus): configuration_object = configuration.get( None, CUSTOM_ADMIN_MENU_SUPERUSER_KEY, {}) or {} configuration_object.update({get_language(): menus}) configuration.set(None, CUSTOM_ADMIN_MENU_SUPERUSER_KEY, configuration_object)
def customize_menu(entries, user): # noqa (C901) """ Merge system menu with customized admin menu """ customized_admin_menu = configuration.get(None, "admin_menu_user_{}".format(user.pk)) if customized_admin_menu: def unset_mismatched(menu): """ find and remove unmatched entries from customized menu tree it can be when menu entry was removed from system """ indexes = [] for index, entry in enumerate(menu.get('entries', [])): unset_mismatched(entry) if isinstance(entry, dict): indexes.append(index) for index in indexes[::-1]: del menu['entries'][index] def find_entry(menu, entry): """ find recursively entry in menu """ if menu['id'] == entry.id: return menu for node in menu.get('entries', []): n = find_entry(node, entry) if n: return n def assign_entry(customized_menu, entry): """ Find and replace customized entry with system menu entry set entry name, hidden flag from customized menu entry """ custom_entries = customized_menu.get('entries', []) for index, node in enumerate(custom_entries): if node['id'] == entry.id: custom_entry = custom_entries[index] entry.name = custom_entry['name'] entry.is_hidden = custom_entry['is_hidden'] entry.entries = custom_entry.get('entries', []) entry.ordering = index custom_entries[index] = entry return custom_entries[index] else: return_entry = assign_entry(custom_entries[index], entry) if return_entry: return return_entry def transform_menu(customized_menu, menu): """ Recursively sort system menu entries and assign it to the customized menu """ indexes = [] for index, entry in enumerate(menu.entries): transform_menu(customized_menu, entry) custom_entry = assign_entry(customized_menu, entry) if not custom_entry: parent_menu = find_entry(customized_menu, menu) if parent_menu: parent_menu.get('entries', []).append(entry) indexes.append(index) else: indexes.append(index) # remove assigned entries from system menu for index in indexes[::-1]: del menu.entries[index] return menu customized_menu = { 'id': 'root', 'name': 'root', 'entries': customized_admin_menu, } system_menu = BaseMenuEntry() system_menu.identifier = 'root' system_menu.entries = entries transform_menu(customized_menu, system_menu) unset_mismatched(customized_menu) return customized_menu['entries'] + system_menu['entries'] else: return entries
def get_permissions_from_group(group): group_id = (group if isinstance(group, six.integer_types) else group.pk) return set( configuration.get(None, _get_permission_key_for_group(group_id), default=[]))
def get_installed_products(shop): """ Returns the installed products samples list """ return configuration.get(shop, SAMPLE_PRODUCTS_KEY) or []
def visible(self): return not configuration.get(None, "sample_data_wizard_completed", False)
def get_installed_categories(shop): """ Returns the installed categories samples list """ return configuration.get(shop, SAMPLE_CATEGORIES_KEY) or []