class OrderStatusListView(PicotableListView): model = OrderStatus default_columns = [ Column("identifier", _("Identifier"), linked=True, filter_config=TextFilter(operator="startswith")), Column("name", _("Name"), linked=True, filter_config=TextFilter(operator="startswith")), Column("public_name", _("Public Name"), linked=False, filter_config=TextFilter(operator="startswith")), Column("role", _("Role"), linked=False, filter_config=ChoicesFilter(choices=OrderStatusRole.choices)), Column("default", _("Default"), linked=False, filter_config=ChoicesFilter([(False, _("yes")), (True, _("no"))])), Column("is_active", _("Active"), linked=False, filter_config=ChoicesFilter([(False, _("yes")), (True, _("no"))])), ]
class UserListView(PicotableListView): model = settings.AUTH_USER_MODEL default_columns = [ Column("username", _(u"Username"), filter_config=TextFilter()), Column("email", _(u"Email"), filter_config=TextFilter()), Column("first_name", _(u"First Name"), filter_config=TextFilter()), Column("last_name", _(u"Last Name"), filter_config=TextFilter()), Column("is_active", _(u"Active"), filter_config=ChoicesFilter([(False, _("no")), (True, _("yes"))], default=True)), Column("is_staff", _(u"Staff"), filter_config=true_or_false_filter), Column("is_superuser", _(u"Superuser"), filter_config=true_or_false_filter), ] def get_model(self): return get_user_model() def get_queryset(self): model = self.get_model() qs = self.get_model().objects.all() if "date_joined" in model._meta.get_all_field_names(): qs = qs.order_by("-date_joined") return qs def get_context_data(self, **kwargs): context = super(UserListView, self).get_context_data(**kwargs) context["title"] = force_text( self.get_model()._meta.verbose_name_plural).title() return context def get_object_abstract(self, instance, item): bits = filter(None, [ _("First Name: %s") % (getattr(instance, 'first_name', None) or "\u2014"), _("Last Name: %s") % (getattr(instance, 'last_name', None) or "\u2014"), _("Active") if instance.is_active else _(u"Inactive"), _("Email: %s") % (getattr(instance, 'email', None) or "\u2014"), _("Staff") if getattr(instance, 'is_staff', None) else None, _("Superuser") if getattr(instance, 'is_superuser', None) else None ]) return [{ "text": instance.get_username() or _("User"), "class": "header" }, { "text": ", ".join([force_text(bit) for bit in bits]) }]
def _get_translated_column(self, model, field, known_names, identifier): field_name = field.verbose_name.title() if field_name in known_names: field_name = "%s %s" % (model.__name__, field_name) # take the first extension, usually we should not have more then one translation_rel_name = model._parler_meta._extensions[0].rel_name if model != self.model: filter_field = "%s__%s__%s" % ( identifier, translation_rel_name, field.name) if identifier else field.name else: filter_field = "%s__%s" % (translation_rel_name, field.name) display = "%s__%s" % (identifier, field.name) if identifier else field.name column = Column("%s_%s" % (model.__name__.lower(), field.name), field_name, sort_field=display, display=display, filter_config=TextFilter(filter_field=filter_field, placeholder=field_name)) return self.handle_special_column(field, column)[0]
class ContactGroupListView(PicotableListView): model = ContactGroup default_columns = [ Column("name", _(u"Name"), sort_field="translations__name", display="name", filter_config=TextFilter(filter_field="translations__name", placeholder=_("Filter by name..."))), Column("n_members", _(u"Number of Members")), ] def get_queryset(self): return ContactGroup.objects.all().annotate(n_members=Count("members")) def get_context_data(self, **kwargs): context = super(ContactGroupListView, self).get_context_data(**kwargs) if self.request.user.is_superuser: settings_button = SettingsActionButton.for_model( ContactGroup, return_url="contact_group") else: settings_button = None context["toolbar"] = Toolbar([ NewActionButton("wshop_admin:contact_group.new"), settings_button ]) return context
class SupplierListView(PicotableListView): model = Supplier default_columns = [ Column("name", _(u"Name"), sort_field="name", display="name", filter_config=TextFilter(filter_field="name", placeholder=_("Filter by name..."))), Column("type", _(u"Type")), Column("module_identifier", _(u"Module"), display="get_module_display", sortable=True) ] def get_module_display(self, instance): return instance.module.name or _( "No %s module") % self.model._meta.verbose_name def get_toolbar(self): if settings.WSHOP_ENABLE_MULTIPLE_SUPPLIERS: return super(SupplierListView, self).get_toolbar() else: return Toolbar([])
def get_pico(rf, model=None, columns=None): get_default_shop() model = model or get_user_model() columns = columns or [ Column("id", "Id", filter_config=Filter(), display=instance_id), Column("username", "Username", sortable=False, filter_config=MultiFieldTextFilter( filter_fields=("username", "email"), operator="iregex")), Column("email", "Email", sortable=False, filter_config=TextFilter()), Column("is_superuser", "Is Superuser", display="superuser_display", filter_config=ChoicesFilter(choices=false_and_true())), Column("is_active", "Is Active", filter_config=ChoicesFilter( choices=false_and_true)), # `choices` callable Column("date_joined", "Date Joined", filter_config=DateRangeFilter()) ] request = apply_request_middleware(rf.get("/")) return Picotable(request=request, columns=columns, mass_actions=[], queryset=model.objects.all(), context=PicoContext(request))
class PageListView(PicotableListView): url_identifier = "simple_cms.page" model = Page default_columns = [ Column("title", _(u"Title"), sort_field="translations__title", display="title", linked=True, filter_config=TextFilter(operator="startswith")), Column("available_from", _(u"Available from")), Column("available_to", _(u"Available to")), Column("created_by", _(u"Created by")), Column("created_on", _(u"Date created")), ] def get_object_abstract(self, instance, item): return [{ "text": "%s" % (instance or _("Page")), "class": "header" }, { "title": _(u"Available from"), "text": item.get("available_from") }, { "title": _(u"Available to"), "text": item.get("available_to") } if instance.available_to else None] def get_queryset(self): return super(PageListView, self).get_queryset().for_shop(get_shop(self.request))
class CouponListView(PicotableListView): model = Coupon default_columns = [ Column("code", _(u"Code"), sort_field="code", display="code", linked=True, filter_config=TextFilter(operator="startswith")), Column("usages", _("Usages"), display="get_usages"), Column("usage_limit_customer", _("Usages Limit per contact")), Column("usage_limit", _("Usage Limit")), Column("active", _("Active")), Column("created_by", _(u"Created by")), Column("created_on", _(u"Date created")), ] def get_usages(self, instance, *args, **kwargs): return instance.usages.count() def get_context_data(self, **kwargs): context = super(CouponListView, self).get_context_data(**kwargs) if self.request.user.is_superuser: settings_button = SettingsActionButton.for_model( self.model, return_url="coupon") else: settings_button = None context["toolbar"] = Toolbar([ NewActionButton("wshop_admin:coupon.new", text=_("Create new Coupon")), settings_button ]) return context
class ShopListView(PicotableListView): model = Shop default_columns = [ Column("logo", _(u"Logo"), display="logo", class_name="text-center", raw=True, ordering=1, sortable=False), Column("name", _(u"Name"), sort_field="translations__name", display="name", filter_config=TextFilter(filter_field="translations__name", placeholder=_("Filter by name..."))), Column("domain", _(u"Domain")), Column("identifier", _(u"Identifier")), Column("status", _(u"Status"), filter_config=ChoicesFilter(choices=ShopStatus.choices)), ] def get_queryset(self): if self.request.user.is_superuser: return super(ShopListView, self).get_queryset() else: return Shop.objects.get_for_user(self.request.user) def get_toolbar(self): if WshopSettings.get_setting("WSHOP_ENABLE_MULTIPLE_SHOPS"): return super(ShopListView, self).get_toolbar() else: return Toolbar([])
class CurrencyListView(PicotableListView): model = Currency default_columns = [ Column("name", _("Name"), display="get_currency_display", sortable=False), Column("code", _(u"Code"), sort_field="code", filter_config=TextFilter( filter_field="code", placeholder=_("Filter by code"), )), Column( "decimal_places", _("Decimal places"), display="format_decimal_places", ) ] def format_decimal_places(self, instance): return "{0}".format(instance.decimal_places) def get_currency_display(self, instance): locale = get_current_babel_locale() return locale.currencies.get(instance.code, instance.code)
def test_picotable_correctly_sorts_translated_fields(rf, admin_user, regular_user): """ Make sure that translated fields, such as product names, are correctly sorted """ populate_if_required() columns = [ Column("id", "Id", filter_config=Filter(), display=instance_id), Column("name", "Name", sort_field="translations__name", filter_config=TextFilter(filter_field="translations__name")), ] pico = get_pico(rf, model=Product, columns=columns) # Verify ascending sort sorted_products = pico.get_data({ "perPage": 100, "page": 1, "sort": "+name" }) sorted_names = [p["name"] for p in sorted_products["items"]] assert sorted_names == sorted(sorted_names) # Verify descending sort sorted_products = pico.get_data({ "perPage": 100, "page": 1, "sort": "-name" }) sorted_names = [p["name"] for p in sorted_products["items"]] assert sorted_names == sorted(sorted_names, reverse=True)
def test_choice_filter_with_default(rf, admin_user, regular_user): columns = [ Column("id", "Id", filter_config=Filter(), display=instance_id), Column("username", "Username", sortable=False, filter_config=MultiFieldTextFilter(filter_fields=("username", "email"), operator="iregex")), Column("email", "Email", sortable=False, filter_config=TextFilter()), Column("is_superuser", "Is Superuser", display="superuser_display", filter_config=ChoicesFilter(choices=false_and_true())), Column("date_joined", "Date Joined", filter_config=DateRangeFilter()) ] is_active = [ Column("is_active", "Is Active", filter_config=ChoicesFilter(choices=false_and_true)) ] is_active_with_default = [ Column("is_active", "Is Active", filter_config=ChoicesFilter(choices=false_and_true, default=True)) ] query = {"perPage": 100, "page": 1, "sort": "+id"} pico_no_defaults = get_pico(rf, columns=(columns + is_active)) data = pico_no_defaults.get_data(query) user_data = data["items"][0] user = get_user_model().objects.get(id=user_data["id"]) assert user.is_active pico_with_defaults = get_pico(rf, columns=(columns + is_active_with_default)) data = pico_with_defaults.get_data(query) user_data = data["items"][0] user_with_defaults = get_user_model().objects.get(id=user_data["id"]) assert user_with_defaults == user user.is_active = False user.save() data = pico_no_defaults.get_data(query) user_data = data["items"][0] new_user = get_user_model().objects.get(id=user_data["id"]) assert new_user == user data = pico_with_defaults.get_data(query) user_data = data["items"][0] new_user_with_defaults = get_user_model().objects.get(id=user_data["id"]) assert new_user_with_defaults != user_with_defaults
class ScriptListView(PicotableListView): template_name = "notify/admin/list_script.jinja" model = Script default_columns = [ Column("name", _("Name"), linked=True, filter_config=TextFilter(operator="startswith")), Column("event_identifier", _("Event"), display="get_event_identifier_text"), Column("enabled", _("Enabled"), filter_config=true_or_false_filter), ] def get_object_url(self, instance): return reverse("wshop_admin:notify.script.edit", kwargs={"pk": instance.pk}) def get_event_identifier_text(self, instance): if not hasattr(self, "_event_identifier_names"): self._event_identifier_names = dict(get_name_map("notify_event")) return self._event_identifier_names.get(instance.event_identifier, instance.event_identifier) def get_toolbar(self): return Toolbar([ URLActionButton(text=_("New Script"), icon="fa fa-plus", extra_css_class="btn-success", url=reverse("wshop_admin:notify.script.new")), JavaScriptActionButton(text=_("New From Template"), icon="fa fa-book", extra_css_class="btn-info", onclick="showScriptTemplates()") ]) def get_object_abstract(self, instance, item): return [{ "text": "%s" % instance, "class": "header" }, { "title": _("Event"), "text": item.get("event_identifier") }, { "title": _("Enabled"), "text": item.get("enabled") }] def get_queryset(self): return super(ScriptListView, self).get_queryset().filter(shop=get_shop(self.request))
class CarouselListView(PicotableListView): model = Carousel default_columns = [ Column("name", _("Name"), sort_field="name", display="name", filter_config=TextFilter(filter_field="name", placeholder=_("Filter by name..."))), ] def get_queryset(self): return super(CarouselListView, self).get_queryset().filter(shops=get_shop(self.request))
class TaxClassListView(PicotableListView): model = TaxClass default_columns = [ Column( "name", _("Name"), sort_field="translations__name", filter_config=TextFilter( filter_field="translations__name", placeholder=_("Filter by name..."), ), ), ]
class ProductTypeListView(PicotableListView): model = ProductType default_columns = [ Column("name", _(u"Name"), sort_field="translations__name", display="name", filter_config=TextFilter(filter_field="translations__name", placeholder=_("Filter by name..."))), Column("n_attributes", _(u"Number of Attributes")), ] def get_queryset(self): return ProductType.objects.all().annotate( n_attributes=Count("attributes"))
class TaxListView(PicotableListView): model = Tax default_columns = [ Column( "name", _("Name"), sort_field="translations__name", filter_config=TextFilter( filter_field="translations__name", placeholder=_("Filter by name..."), ), ), Column("code", _(u"Code")), Column("rate", _("Rate"), display=_format_rate), # Column("amount", _(u"Amount")), Column("enabled", _(u"Enabled"), filter_config=true_or_false_filter), ]
class CampaignListView(PicotableListView): default_columns = [ Column("name", _(u"Title"), sort_field="name", display="name", linked=True, filter_config=TextFilter(operator="startswith")), Column("start_datetime", _("Starts")), Column("end_datetime", _("Ends")), Column("active", _("Active"), filter_config=ChoicesFilter(choices=[(0, _("No")), (1, _("Yes"))])), ] def get_queryset(self): shop = self.request.shop return self.model.objects.filter(shop=shop) def start_datetime(self, instance, *args, **kwargs): if not instance.start_datetime: return "" return self._formatted_datetime(instance.start_datetime) def end_datetime(self, instance, *args, **kwargs): if not instance.end_datetime: return "" return self._formatted_datetime(instance.end_datetime) def _formatted_datetime(self, dt): return format_datetime(localtime(dt), locale=get_current_babel_locale()) def get_object_abstract(self, instance, item): return [ { "text": "%s" % (instance or _("CatalogCampaign")), "class": "header" }, ]
class ServiceListView(PicotableListView): model = None # Override in subclass columns = [] base_columns = [ Column("name", _("Name"), sort_field="translations__name", filter_config=TextFilter(filter_field="translations__name", placeholder=_("Filter by name..."))), Column( "choice_identifier", _(u"Service choice"), display="format_service_choice", sortable=False, ), Column("enabled", _(u"Enabled"), filter_config=true_or_false_filter), Column("shop", _(u"Shop")) ] def get_object_abstract(self, instance, item): return [ { "text": "%s" % instance, "class": "header" }, ] def format_service_choice(self, instance, *args, **kwargs): if instance.provider: for choice in instance.provider.get_service_choices(): if choice.identifier == instance.choice_identifier: return force_text(choice.name) def get_queryset(self): return super(ServiceListView, self).get_queryset().filter(shop=self.request.shop)
def _get_column(self, model, field, known_names, identifier): if not self._valid_field(field.name): return None field_name = field.verbose_name.title() if field_name in known_names: field_name = "%s %s" % (model.__name__, field_name) display = "%s__%s" % (identifier, field.name) if identifier else field.name column = Column("%s_%s" % (model.__name__.lower(), field.name), field_name, display=display) column, is_special = self.handle_special_column(field, column) if not is_special: if isinstance(field, CharField): column.filter_config = TextFilter(placeholder=field_name) if isinstance(field, EnumIntegerField): column.filter_config = ChoicesFilter(field.choices) if isinstance(field, BooleanField): column.filter_config = true_or_false_filter return column
class PermissionGroupListView(PicotableListView): model = PermissionGroup default_columns = [ Column( "name", _(u"Name"), sort_field="name", display="name", filter_config=TextFilter(filter_field="name", placeholder=_("Filter by name...")) ), ] def get_context_data(self, **kwargs): context = super(PermissionGroupListView, self).get_context_data(**kwargs) context["title"] = _("Permission Groups") if self.request.user.is_superuser: settings_button = SettingsActionButton.for_model(self.model, return_url="permission_group") else: settings_button = None context["toolbar"] = Toolbar([ NewActionButton("wshop_admin:permission_group.new", text=_("Create new Permission Group")), settings_button ]) return context
class ServiceProviderListView(PicotableListView): model = ServiceProvider default_columns = [ Column("name", _("Name"), sort_field="base_translations__name", filter_config=TextFilter(filter_field="base_translations__name", placeholder=_("Filter by name..."))), Column("type", _(u"Type"), display="get_type_display", sortable=False), ] def get_type_display(self, instance): return instance._meta.verbose_name.capitalize() def get_object_abstract(self, instance, item): return [ { "text": "%s" % instance, "class": "header" }, { "text": self.get_type_display(instance) }, ]
class ProductListView(PicotableListView): model = ShopProduct picotable_class = ProductPicotable default_columns = [ Column("primary_image", _(u"Primary Image"), display="get_primary_image", class_name="text-center", raw=True, ordering=1, sortable=False), Column("name", _(u"Name"), sort_field="product__translations__name", display="product__name", filter_config=TextFilter( filter_field="product__translations__name", placeholder=_("Filter by name...")), ordering=2), Column("shop", _("Shop"), ordering=2), Column("sku", _(u"SKU"), display="product__sku", filter_config=RangeFilter(filter_field="product__sku"), ordering=3), Column("barcode", _(u"Barcode"), display="product__barcode", filter_config=TextFilter(placeholder=_("Filter by barcode...")), ordering=4), Column("type", _(u"Type"), display="product__type", ordering=5), Column("mode", _(u"Mode"), display="product__mode", filter_config=ChoicesFilter(ProductMode.choices), ordering=6), ] related_objects = [ ("product", "wshop.core.models:Product"), ] mass_actions = [ "wshop.admin.modules.products.mass_actions:VisibleMassAction", "wshop.admin.modules.products.mass_actions:InvisibleMassAction", "wshop.admin.modules.products.mass_actions:FileResponseAction", "wshop.admin.modules.products.mass_actions:EditProductAttributesAction", ] def get_columns(self): for column in self.columns: if column.id == 'shop': shops = Shop.objects.get_for_user( self.request.user).prefetch_related('translations') column.filter_config = ChoicesFilter(choices=shops) break return self.columns def get_primary_image(self, instance): if instance.product.primary_image: thumbnail = instance.product.primary_image.get_thumbnail() if thumbnail: return "<img src='/media/{}'>".format(thumbnail) return "<img src='%s'>" % static( "wshop_admin/img/no_image_thumbnail.png") def get_queryset(self): filter = self.get_filter() shop = self.request.shop qs = ShopProduct.objects.filter(product__deleted=False, shop=shop) q = Q() for mode in filter.get("modes", []): q |= Q(product__mode=mode) manufacturer_ids = filter.get("manufacturers") if manufacturer_ids: q |= Q(product__manufacturer_id__in=manufacturer_ids) qs = qs.filter(q) return qs def get_object_abstract(self, instance, item): return [ { "text": "%s" % instance.product, "class": "header" }, { "title": _(u"Barcode"), "text": item.get("product__barcode") }, { "title": _(u"SKU"), "text": item.get("product__sku") }, { "title": _(u"Type"), "text": item.get("product__type") }, ]
class ContactListView(PicotableListView): model = Contact default_columns = [ Column("name", _(u"Name"), linked=True, filter_config=TextFilter()), Column("type", _(u"Type"), display="get_type_display", sortable=False, filter_config=ContactTypeFilter()), Column("email", _(u"Email"), filter_config=TextFilter()), Column("phone", _(u"Phone"), filter_config=TextFilter()), Column("is_active", _(u"Active"), filter_config=ChoicesFilter([(False, _("no")), (True, _("yes"))], default=True)), Column("n_orders", _(u"# Orders"), class_name="text-right", filter_config=RangeFilter(step=1)), Column("groups", _("Groups"), filter_config=ChoicesFilter(ContactGroup.objects.all(), "groups"), display="get_groups_display"), Column("shops", _("Shops"), filter_config=Select2Filter(Shop.objects.all()), display="get_shop_display") ] mass_actions = [ "wshop.admin.modules.contacts.mass_actions:EditContactsAction", "wshop.admin.modules.contacts.mass_actions:EditContactGroupsAction", ] def get_toolbar(self): if self.request.user.is_superuser: settings_button = SettingsActionButton.for_model( Contact, return_url="contact") else: settings_button = None return Toolbar([ NewActionButton.for_model(PersonContact, url=reverse("wshop_admin:contact.new") + "?type=person"), NewActionButton.for_model(CompanyContact, extra_css_class="btn-info", url=reverse("wshop_admin:contact.new") + "?type=company"), settings_button ]) def get_queryset(self): qs = super(ContactListView, self).get_queryset() groups = self.get_filter().get("groups") query = Q(groups__in=groups) if groups else Q() limited = (settings.WSHOP_ENABLE_MULTIPLE_SHOPS and settings.WSHOP_MANAGE_CONTACTS_PER_SHOP and not self.request.user.is_superuser) if limited: shop = self.request.shop qs = qs.filter(shops=shop) return (qs.filter(query).annotate( n_orders=Count("customer_orders")).order_by("-created_on")) def get_type_display(self, instance): if isinstance(instance, PersonContact): return _(u"Person") elif isinstance(instance, CompanyContact): return _(u"Company") else: return _(u"Contact") def get_groups_display(self, instance): if instance.groups.count(): return ", ".join( instance.groups.values_list("translations__name", flat=True)) return _("No group") def get_shop_display(self, instance): if instance.shops.count(): return ", ".join( instance.shops.values_list("translations__name", flat=True)) return _("No shop") def get_object_abstract(self, instance, item): """ :type instance: wshop.core.models.Contact """ bits = filter(None, [ item.get("type"), _("Active") if instance.is_active else _("Inactive"), _("Email: %s") % (instance.email or "\u2014"), _("Phone: %s") % (instance.phone or "\u2014"), _("%d orders") % instance.n_orders, ]) return [{ "text": instance.name or _("Contact"), "class": "header" }, { "text": ", ".join([force_text(bit) for bit in bits]) }]
class OrderListView(PicotableListView): model = Order default_columns = [ Column("identifier", _(u"Order"), linked=True, filter_config=TextFilter(operator="startswith")), Column("order_date", _(u"Order Date"), display="format_order_date", filter_config=DateRangeFilter()), Column("customer", _(u"Customer"), display="format_customer_name", filter_config=MultiFieldTextFilter( filter_fields=("customer__email", "customer__name", "billing_address__name", "shipping_address__name", "orderer__name"))), Column( "status", _(u"Status"), filter_config=OrderStatusChoicesFilter( choices=OrderStatus.objects.all()), ), Column("payment_status", _(u"Payment Status"), filter_config=ChoicesFilter(choices=PaymentStatus.choices)), Column("shipping_status", _(u"Shipping Status"), filter_config=ChoicesFilter(choices=ShippingStatus.choices)), Column("taxful_total_price_value", _(u"Total"), sort_field="taxful_total_price_value", display="format_taxful_total_price", class_name="text-right", filter_config=RangeFilter( field_type="number", filter_field="taxful_total_price_value")), ] mass_actions = [ "wshop.admin.modules.orders.mass_actions:CancelOrderAction", "wshop.admin.modules.orders.mass_actions:OrderConfirmationPdfAction", "wshop.admin.modules.orders.mass_actions:OrderDeliveryPdfAction", ] def get_toolbar(self): return Toolbar([ NewActionButton.for_model(Order, url=reverse("wshop_admin:order.new")), SettingsActionButton.for_model(Order, return_url="order") ]) def get_queryset(self): return super(OrderListView, self).get_queryset().exclude( deleted=True).filter(shop=self.request.shop) def format_customer_name(self, instance, *args, **kwargs): return instance.get_customer_name() or "" def format_order_date(self, instance, *args, **kwargs): return get_locally_formatted_datetime(instance.order_date) def format_taxful_total_price(self, instance, *args, **kwargs): return escape(format_money(instance.taxful_total_price)) def label(self, instance, *args, **kwargs): # format label to make it human readable return instance.label.replace("_", " ").title() def get_object_abstract(self, instance, item): return [{ "text": "%s" % instance, "class": "header" }, { "title": _(u"Total"), "text": item.get("taxful_total_price_value") }, { "title": _(u"Status"), "text": item.get("status") }]
class StocksListView(PicotableListView): template_name = "wshop/simple_supplier/admin/base_picotable.jinja" model = Product default_columns = [ Column("sku", _("SKU"), sort_field="product__sku", display="product__sku", linked=True, filter_config=TextFilter(filter_field="product__sku", placeholder=_("Filter by SKU..."))), Column("name", _("Name"), sort_field="product__translations__name", display="product__name", linked=True, filter_config=TextFilter( filter_field="product__translations__name", placeholder=_("Filter by name..."))), Column( "supplier", _("Supplier"), display="supplier", linked=False, filter_config=ChoicesFilter( Supplier.objects.filter(module_identifier="simple_supplier"))), Column("stock_information", _("Stock information"), display="get_stock_information", linked=False, sortable=False, raw=True), Column("adjust_stock", _("Adjust stock"), display="get_stock_adjustment_form", sortable=False, linked=False, raw=True) ] def __init__(self): super(StocksListView, self).__init__() self.columns = self.default_columns def get_object_abstract(self, instance, item): item.update({ "_linked_in_mobile": False, "_url": self.get_object_url(instance.product) }) return [ { "text": item.get("name"), "class": "header" }, { "title": "", "text": item.get("sku") }, { "title": "", "text": " ", "raw": item.get("stock_information") }, { "title": "", "text": " ", "raw": item.get("adjust_stock") }, ] def get_queryset(self): return StockCount.objects.filter( supplier__module_identifier="simple_supplier", product__stock_behavior=StockBehavior.STOCKED, product__deleted=False).order_by("product__id") def get_context_data(self, **kwargs): context = super(PicotableListView, self).get_context_data(**kwargs) context["toolbar"] = None context["title"] = _("Stock management") return context def get_stock_information(self, instance): return get_stock_information_html(instance.supplier, instance.product) def get_stock_adjustment_form(self, instance): return get_stock_adjustment_div(self.request, instance.supplier, instance.product)
class UnitListView(PicotableListView): default_columns = [ Column("name", _(u"Name"), sort_field="translations__name", display="name", filter_config=TextFilter( filter_field="translations__name", placeholder=_("Filter by name...") )), Column("symbol", _(u"Symbol"), sort_field="translations__symbol", display="symbol"), Column("decimals", _(u"Allowed decimals")), ] def get_queryset(self): return self.model.objects.all()