def get_context_data(self, **kwargs): context = super(OrderDetailView, self).get_context_data(**kwargs) context["toolbar"] = self.get_toolbar() context["title"] = force_text(self.object) context["order_sections"] = [] provided_information = [] for provided_info in sorted( get_provide_objects("admin_order_information"), key=lambda x: x.order): info = provided_info(self.object) if info.provides_info(): provided_information.append((info.title, info.information)) context["provided_information"] = provided_information order_sections_provides = sorted( get_provide_objects("admin_order_section"), key=lambda x: x.order) for admin_order_section in order_sections_provides: # Check whether the Section should be visible for the current object if admin_order_section.visible_for_object(self.object, self.request): context["order_sections"].append(admin_order_section) # add additional context data where the key is the order_section identifier section_context = admin_order_section.get_context_data( self.object, self.request) context[admin_order_section.identifier] = section_context return context
def get_form_parts(self, object): form_parts = super(ServiceEditView, self).get_form_parts(object) if not object.pk: return form_parts for form in get_provide_objects(self.form_provide_key): form_parts.append(self._get_behavior_form_part(form, object)) for form_class in get_provide_objects(self.form_part_provide_key): form_parts.append(form_class(self.request, object)) return form_parts
def get_form_parts(self, object): form_parts = super(CampaignEditView, self).get_form_parts(object) if not object.pk: return form_parts for form in get_provide_objects(self.condition_key): form_parts.append(self._get_rules_form_part(form, object)) for provide_key, form_part_class in self.effects: for form in get_provide_objects(provide_key): form_parts.append(self._get_effects_form_part(form, object, form_part_class)) return form_parts
def _build_action_menu(self, product): # cross selling cross_sell_button = DropdownItem( text=_("Manage Cross-Selling"), icon="fa fa-random", url=reverse("wshop_admin:shop_product.edit_cross_sell", kwargs={"pk": product.pk}) ) menu_items = [menu_item for menu_item in self._get_header_items( header=_("Cross-Selling"), divider=False, identifier=ProductActionCategory.CHILD_CROSS_SELL)] menu_items.append(cross_sell_button) # packages for item in self._get_variation_and_package_menu_items(product): menu_items.append(item) provided_items = get_provide_objects("admin_product_toolbar_action_item") if provided_items: for item in self._get_header_items(header=_("Other"), identifier=ProductActionCategory.CHILD_OTHER): menu_items.append(item) for button in provided_items: if button.visible_for_object(product): menu_items.append(button(product)) # add the actual Action button self.append(DropdownActionButton( menu_items, icon="fa fa-star", text=_(u"Actions"), extra_css_class="btn-info", identifier=ProductActionCategory.MAIN ))
def get_form(self, form_class=None): form_classes = list(get_provide_objects(self.form_provide_key)) form_infos = FormInfoMap(form_classes) if self.object and self.object.pk: return self._get_concrete_form(form_infos) else: return self._get_type_choice_form(form_infos)
def search_from_provided_contexts(self, object): provide_object_key = "provided_columns_%s" % type(object).__name__ for provided_column_object in get_provide_objects(provide_object_key): obj = provided_column_object() display_callable = maybe_callable(self.display, context=obj) if display_callable: return display_callable(object)
def get_matching_for_product(shop_product, provide_category, skippable_classes=None): """ Get matching ids for shop product based on provide category For example: matching_ids = get_matching_for_product(shop_product, "campaign_catalog_filter") :param shop_product: A Shop Product :type shop_product: wshop.core.models.ShopProduct :param provide_category: Provide category name :type provide_category: str :param skip: Classes to skip :type skip: None or list :return: list of collected item ids :rtype: list[int] """ collected = set() matcher = ProductCampaignMatcher(shop_product) for item in get_provide_objects(provide_category): if skippable_classes: objects = item._meta.model.objects.not_instance_of( *skippable_classes).all() else: objects = item._meta.model.objects.all() for obj in objects: if matcher.matches(obj): collected.add(obj.pk) return collected
def get_menu_items(self): items = [] for cls in get_provide_objects("customer_dashboard_items"): c = cls(self.request) if c.show_on_menu(): items.append(c) return items
def _add_provided_columns(self, columns, identifier, known_names, model): provide_object_key = "provided_columns_%s" % model.__name__ for provided_column_object in get_provide_objects(provide_object_key): obj = provided_column_object() column = obj.get_column(model, known_names, identifier) if column: columns.append(column)
def _get_delivery_html(request, order, shipment, html_mode=False): context = { "shipment": shipment, "order": order, "method_lines": OrderLine.objects.filter( order_id=order.id, type__in=[OrderLineType.PAYMENT, OrderLineType.SHIPPING]).order_by("ordering"), "today": datetime.date.today(), "header": "%s | %s | %s %s" % (_("Delivery slip"), order.shop.name, _("Order"), order.pk), "footer": _get_footer_information(order.shop), "html_mode": html_mode } provided_information = {} for provided_info in sorted( get_provide_objects("order_printouts_delivery_extra_fields")): info = provided_info(order, shipment) if info.provides_extra_fields(): provided_information.update(info.extra_fields) context['extra_fields'] = provided_information return render_to_string("wshop/order_printouts/admin/delivery_pdf.jinja", context=context, request=request)
def populate(self): """ Iterate over all report_writer_populator provides to fill/update the report writer map """ for report_writer_populator_func in get_provide_objects( "report_writer_populator"): report_writer_populator_func(self)
def _postprocess(self, context, content): for inject_func in get_provide_objects("xtheme_resource_injection"): if callable(inject_func): inject_func(context, content) add_edit_resources(context) content = inject_resources(context, content) return content
def _get_service_provider_form_defs(self): form_defs = [] for form_def in get_provide_objects(self.form_def_provide_key): inst = form_def(request=self.request) if inst.visible(): form_defs.append(inst) form_defs.sort(key=lambda form_def: getattr(form_def, "priority", 0)) return form_defs
def get_form_parts(self, object): form_parts = super(CatalogCampaignEditView, self).get_form_parts(object) if not object.pk: return form_parts for form in get_provide_objects(self.filter_key): form_parts.append(self._get_filters_form_part(form, object)) return form_parts
def form_valid_hook(self, form, object): has_extension_errors = False for extend_class in get_provide_objects( form.form_modifier_provide_key): try: extend_class().form_valid_hook(form, object) except Problem as problem: has_extension_errors = True messages.error(self.request, problem) return has_extension_errors
def build_provides_buttons(self): action_menu_items = [] for button in get_provide_objects("admin_contact_toolbar_action_item"): if button.visible_for_object(self.contact): action_menu_items.append(button(object=self.contact)) if action_menu_items: self.append( DropdownActionButton( action_menu_items, icon="fa fa-star", text=_(u"Actions"), extra_css_class="btn-info", )) for button in get_provide_objects("admin_contact_toolbar_button"): warnings.warn( "admin_contact_toolbar_button provider is deprecated, use admin_contact_toolbar_action_item instead", RemovedFromWshopWarning) self.append(button(self.contact))
def get_toolbar(self): toolbar = get_default_edit_toolbar( self, self.get_save_form_id(), discard_url=(get_model_url(self.object) if self.object.pk else None)) for button in get_provide_objects("admin_contact_edit_toolbar_button"): toolbar.append(button(self.object)) return toolbar
def get_form_part_classes(self): form_part_classes = [] contact_type = self.get_contact_type() if contact_type == "person": form_part_classes.append(PersonContactBaseFormPart) else: form_part_classes.append(CompanyContactBaseFormPart) form_part_classes += list( get_provide_objects(self.form_part_class_provide_key)) if self.object.pk: form_part_classes.append(ContactAddressesFormPart) return form_part_classes
def get_module_choices(cls, empty_label=None): if empty_label is None: empty_label = _('No Choice') choices = [("", empty_label)] for module in get_provide_objects(cls.module_provides_key): if module.identifier: choices.append( (module.identifier, getattr(module, "name", None) or module.identifier)) choices.sort() return choices
def test_blacklist_provides(): with override_settings( INSTALLED_APPS=["wshop_tests.core"], WSHOP_PROVIDES_BACKLIST={ "module_test_module": ["wshop_tests.core.module_test_module:ModuleTestModule"] }): from wshop.apps.provides import clear_provides_cache clear_provides_cache() provides = [ module.__name__ for module in list(get_provide_objects("module_test_module")) ] assert "AnotherModuleTestModule" in provides assert "ModuleTestModule" not in provides # invalid object with override_settings(WSHOP_PROVIDES_BACKLIST=["invalid"]): from wshop.apps.provides import clear_provides_cache clear_provides_cache() with pytest.raises(ImproperlyConfigured): list(get_provide_objects("module_test_module"))
def render_menu_extensions(self, request, location=MenuExtenderLocation.MAIN_MENU): """ Render menu extensions Some addons want to provide items to main menu. :param request: :return safe HTML string: """ items = [] for menu_extender in get_provide_objects("front_menu_extender"): extender = menu_extender() if extender.location == location: items.append(extender.get_rendered_menu_items(request, self)) return mark_safe("".join(items))
def test_provides(): IDENTIFIED_OBJECT_SPEC = "%s:IdentifiedObject" % __name__ category = str(uuid.uuid4()) with override_provides(category, [ IDENTIFIED_OBJECT_SPEC, "%s:UnidentifiedObject" % __name__, "%s:VeryUnidentifiedObject" % __name__, ]): objects = get_provide_objects(category) assert set(objects) == set( (IdentifiedObject, UnidentifiedObject, VeryUnidentifiedObject)) assert get_identifier_to_object_map( category)["identifier"] == IdentifiedObject assert get_identifier_to_spec_map( category)["identifier"] == IDENTIFIED_OBJECT_SPEC assert get_provide_specs_and_objects( category)[IDENTIFIED_OBJECT_SPEC] == IdentifiedObject # Test the context manager clears things correctly assert empty_iterable(get_provide_objects(category)) assert empty_iterable(get_provide_specs_and_objects(category)) assert empty_iterable(get_identifier_to_object_map(category)) assert empty_iterable(get_identifier_to_spec_map(category))
def _get_helpers(): helpers = HelpersNamespace() from wshop.front.template_helpers import general, product, category, urls helpers.general = general helpers.product = product helpers.category = category helpers.urls = urls for namespace in get_provide_objects("front_template_helper_namespace"): if namespace and getattr(namespace, "name", None): if callable(namespace): # If it's a class, instantiate it namespace = namespace() setattr(helpers, namespace.name, namespace) return helpers
def _build_action_button(self): action_menu_items = [] for button in get_provide_objects("admin_order_toolbar_action_item"): if button.visible_for_object(self.order): action_menu_items.append(button(object=self.order)) if action_menu_items: self.append( DropdownActionButton( action_menu_items, icon="fa fa-star", text=_(u"Actions"), extra_css_class="btn-info", ) )
def get_checkout_phases_for_service(checkout_process, service): """ Get checkout phases for given service. :type checkout_process: wshop.front.checkout.CheckoutProcess :type service: wshop.core.models.Service :rtype: Iterable[wshop.front.checkout.CheckoutPhaseViewMixin] """ classes = get_provide_objects("front_service_checkout_phase_provider") for provider_cls in classes: provider = provider_cls() assert isinstance(provider, ServiceCheckoutPhaseProvider) phase = provider.get_checkout_phase(checkout_process, service) if phase: assert isinstance(phase, CheckoutPhaseViewMixin) yield phase
def get_theme_context(shop): themes = [] active_theme = None # create one ThemeSettings for each theme if needed for theme in get_provide_objects("xtheme"): if not theme.identifier: continue theme_settings = ThemeSettings.objects.get_or_create( theme_identifier=theme.identifier, shop=shop)[0] themes.append(theme) if theme_settings.active: active_theme = theme return { "theme_classes": sorted(themes, key=lambda t: (t.name or t.identifier)), "current_theme": active_theme }
def get_context_data(self, **kwargs): context = super(ContactDetailView, self).get_context_data(**kwargs) context["toolbar"] = ContactDetailToolbar(contact=self.object, request=self.request) context["title"] = "%s: %s" % (self.object._meta.verbose_name.title(), force_text(self.object)) context["contact_sections"] = [] contact_sections_provides = sorted( get_provide_objects("admin_contact_section"), key=lambda x: x.order) for admin_contact_section in contact_sections_provides: # Check whether the ContactSection should be visible for the current object if admin_contact_section.visible_for_object( self.object, self.request): context["contact_sections"].append(admin_contact_section) # add additional context data where the key is the contact_section identifier section_context = admin_contact_section.get_context_data( self.object, self.request) context[admin_contact_section.identifier] = section_context return context
def get_plugin_choices(cls, empty_label=None): """ Get a sorted list of 2-tuples (identifier and name) of available Xtheme plugins. Handy for `<select>` boxes. :param empty_label: Label for the "empty" choice. If falsy, no empty choice is prepended :type empty_label: str|None :return: List of 2-tuples :rtype: Iterable[tuple[str, str]] """ choices = [] if empty_label: choices.append(("", empty_label)) for plugin in get_provide_objects("xtheme_plugin"): if plugin.identifier: choices.append( (plugin.identifier, getattr(plugin, "name", None) or plugin.identifier)) choices.sort() return choices
def _get_active_modifiers(shop=None, category=None): key = None if category: key, val = context_cache.get_cached_value( identifier="active_modifiers", item=category, allow_cache=True, context={"shop": shop}) if val is not None: return val configurations = get_configuration(shop=shop, category=category) def sorter(extend_obj): return extend_obj.get_ordering(configurations) objs = [] for cls in get_provide_objects(FORM_MODIFIER_PROVIDER_KEY): obj = cls() if obj.should_use(configurations): objs.append(obj) sorted_objects = sorted(objs, key=sorter) if category and key: context_cache.set_cached_value(key, sorted_objects) return sorted_objects
def get_theme_by_identifier(identifier, shop): """ Get an instantiated theme by identifier. :param identifier: Theme identifier :type identifier: str :param shop: Shop to fetch the theme settings :type shop: wshop.core.models.Shop :return: Theme object or None :rtype: Theme """ for theme_cls in get_provide_objects("xtheme"): if theme_cls.identifier == identifier: from wshop.xtheme.models import ThemeSettings theme_settings = ThemeSettings.objects.get_or_create( theme_identifier=identifier, shop=shop )[0] return theme_cls(theme_settings=theme_settings) return None # No such thing.