class OrderListView(PicotableListView): model = Order 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"), filter_config=MultiFieldTextFilter( filter_fields=("customer__email", "customer__name"))), Column("status", _(u"Status"), filter_config=ChoicesFilter(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", _(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")), ] def get_queryset(self): return super(OrderListView, self).get_queryset().exclude(deleted=True) 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 get_object_abstract(self, instance, item): return [{ "text": "%s" % instance, "class": "header" }, { "title": _(u"Total"), "text": item["taxful_total_price"] }, { "title": _(u"Status"), "text": item["status"] }]
class ContactListView(PicotableListView): model = Contact columns = [ Column("name", _(u"Name"), linked=True, filter_config=TextFilter()), Column("type", _(u"Type"), display="get_type_display", sortable=False), # TODO: Add a filter 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")) ] def get_queryset(self): groups = self.get_filter().get("groups") query = Q(groups__in=groups) if groups else Q() return super(ContactListView, self).get_queryset().filter(query).annotate(n_orders=Count("customer_orders")) 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_object_abstract(self, instance, item): """ :type instance: shuup.core.models.Contact """ bits = filter(None, [ item["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(bits)} ]
class ProductReviewListView(PicotableListView): model = ProductReview url_identifier = "product_reviews" default_columns = [ Column( "product", _("Product"), filter_config=TextFilter( filter_field="product__translations__name", placeholder=_("Filter by product...") ) ), Column( "reviewer__name", _("Reviewer"), filter_config=TextFilter(filter_field="reviewer__name") ), Column( "rating", _("Rating"), filter_config=RangeFilter(min=1, max=5, step=1, filter_field="rating") ), Column("comment", _("Comment")), Column( "status", _("Status"), filter_config=ChoicesFilter( choices=ReviewStatus.choices(), filter_field="status" ) ) ] mass_actions = [ "shuup_product_reviews.admin_module.mass_actions.ApproveProductReviewMassAction", "shuup_product_reviews.admin_module.mass_actions.RejectProductReviewMassAction" ] def get_queryset(self): return ProductReview.objects.filter(shop=get_shop(self.request))
class BaseProductReviewListView(PicotableListView): model = None default_columns = [ Column("reviewer__name", _("Reviewer"), filter_config=TextFilter(filter_field="reviewer__name")), Column("rating", _("Rating"), filter_config=RangeFilter(min=1, max=5, step=1, filter_field="rating")), Column("comment", _("Comment")), Column("status", _("Status"), filter_config=ChoicesFilter(choices=ReviewStatus.choices(), filter_field="status")) ] def __init__(self): super(BaseProductReviewListView, self).__init__() self.columns = self.default_columns
class CartListView(PicotableListView): model = StoredBasket default_columns = [ Column("key", _(u"Key"), filter_config=TextFilter(filter_field="key")), Column("updated_on", _(u"Last updated on"), display="format_updated_date", filter_config=DateRangeFilter()), Column("finished", _("Completed"), display="format_finished_status", filter_config=ChoicesFilter([(True, _("yes")), (False, _("no"))], filter_field="finished", default=False)), Column("shop", _("Shop"), filter_config=TextFilter( filter_field="shop__translations__public_name")), Column("supplier", _("Supplier"), filter_config=TextFilter(filter_field="supplier__name")), Column("customer", _(u"Customer"), filter_config=MultiFieldTextFilter( filter_fields=("customer__email", "customer__name"))), Column("product_count", _("Product count"), filter_config=RangeFilter()), Column("taxful_total_price", _(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")), ] toolbar_buttons_provider_key = "cart_list_toolbar_provider" mass_actions_provider_key = "cart_list_actions_provider" def __init__(self): super(CartListView, self).__init__() self.columns = self.default_columns def get_queryset(self): """ Ignore potentially active carts, displaying only those not updated for at least 2 hours. """ shop = get_shop(self.request) filters = {"product_count__gte": 0, "persistent": False, "shop": shop} return super(CartListView, self).get_queryset().filter(**filters) def format_finished_status(self, instance, *args, **kwargs): return "yes" if instance.finished else "no" def format_updated_date(self, instance, *args, **kwargs): return get_locally_formatted_datetime(instance.updated_on) def format_taxful_total_price(self, instance, *args, **kwargs): if not instance.taxful_total_price: return "" return escape(format_money(instance.taxful_total_price)) def get_context_data(self, **kwargs): context = super(CartListView, self).get_context_data(**kwargs) context["title"] = _("Carts") return context def get_object_abstract(self, instance, item): return [ { "text": "%s" % instance, "class": "header" }, { "title": _(u"Created on"), "text": item.get("created_on") }, { "title": _(u"Last updated on"), "text": item.get("updated_on") }, { "title": _(u"Ordered"), "text": item.get("finished") }, { "title": _(u"Total"), "text": item.get("taxful_total_price") }, ]
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=ChoicesFilter(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")), ] related_objects = [ ("shop", "shuup.core.models:Shop"), ("billing_address", "shuup.core.models:ImmutableAddress"), ("shipping_address", "shuup.core.models:ImmutableAddress"), ] mass_actions = [ "shuup.admin.modules.orders.mass_actions:CancelOrderAction", "shuup.admin.modules.orders.mass_actions:OrderConfirmationPdfAction", "shuup.admin.modules.orders.mass_actions:OrderDeliveryPdfAction", ] toolbar_buttons_provider_key = "order_list_toolbar_provider" mass_actions_provider_key = "order_list_mass_actions_provider" def get_toolbar(self): toolbar = Toolbar([ NewActionButton.for_model(Order, url=reverse("shuup_admin:order.new")), SettingsActionButton.for_model(Order, return_url="order") ], view=self) return toolbar def get_queryset(self): return super(OrderListView, self).get_queryset().exclude( deleted=True).filter(shop=get_shop(self.request)) 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 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", "shuup.core.models:Product"), ] mass_actions = [ "shuup.admin.modules.products.mass_actions:VisibleMassAction", "shuup.admin.modules.products.mass_actions:InvisibleMassAction", "shuup.admin.modules.products.mass_actions:FileResponseAction", "shuup.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( "shuup_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=Select2Filter("get_groups"), display="get_groups_display" ), Column("shops", _("Shops"), filter_config=Select2Filter("get_shops"), display="get_shops_display"), Column("registration_shop", _("Registered in"), filter_config=Select2Filter("get_shops")) ] mass_actions = [ "shuup.admin.modules.contacts.mass_actions:EditContactsAction", "shuup.admin.modules.contacts.mass_actions:EditContactGroupsAction", ] toolbar_buttons_provider_key = "contact_list_toolbar_provider" mass_actions_provider_key = "contact_list_mass_actions_provider" def __init__(self): super(ContactListView, self).__init__() picture_column = [column for column in self.columns if column.id == "contact_picture"] if picture_column: picture_column[0].raw = True def get_groups(self): return list( ContactGroup.objects.translated().all_except_defaults().values_list("id", "translations__name") ) def get_shops(self): return list( Shop.objects.get_for_user(self.request.user).translated().values_list("id", "translations__public_name") ) 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("shuup_admin:contact.new") + "?type=person" ), NewActionButton.for_model( CompanyContact, extra_css_class="btn-info", url=reverse("shuup_admin:contact.new") + "?type=company" ), settings_button ], view=self) 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() # non superusers can't see superusers contacts if not self.request.user.is_superuser: qs = qs.exclude(PersonContact___user__is_superuser=True) if self.request.GET.get("shop"): qs = qs.filter( shops__in=Shop.objects.get_for_user(self.request.user).filter(pk=self.request.GET["shop"]) ) elif request_limited(self.request): shop = get_shop(self.request) 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): groups = [group.name for group in instance.groups.all_except_defaults()] return ", ".join(groups) if groups else _("No group") def get_shops_display(self, instance): user = self.request.user shops = [shop.name for shop in instance.shops.get_for_user(user=user)] return ", ".join(shops) if shops else _("No shops") def get_object_abstract(self, instance, item): """ :type instance: shuup.core.models.Contact """ bits = filter(None, [ self.get_type_display(instance), _("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 CartListView(PicotableListView): model = StoredBasket columns = [ Column("created_on", _(u"Created on"), display="format_created_date", filter_config=DateRangeFilter()), Column("updated_on", _(u"Last updated on"), display="format_updated_date", filter_config=DateRangeFilter()), Column("finished", _("Abandoned"), display="format_abandoned_status", filter_config=ChoicesFilter([(False, _("yes")), (True, _("no"))])), Column("shop", _("Shop"), filter_config=ChoicesFilter(choices=Shop.objects.all())), Column("product_count", _("Product count"), filter_config=RangeFilter()), Column("customer", _(u"Customer"), filter_config=MultiFieldTextFilter( filter_fields=("customer__email", "customer__name"))), Column("orderer", _(u"Orderer"), filter_config=MultiFieldTextFilter( filter_fields=("orderer__email", "orderer__name"))), Column("taxful_total_price", _(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")), ] def get_queryset(self): """ Ignore potentially active carts, displaying only those not updated for at least 2 hours. """ cutoff = now() - datetime.timedelta(hours=2) filters = { "updated_on__lt": cutoff, "product_count__gte": 0, "persistent": False } return super(CartListView, self).get_queryset().filter(**filters) def format_abandoned_status(self, instance, *args, **kwargs): return "yes" if not instance.finished else "no" def format_created_date(self, instance, *args, **kwargs): return get_locally_formatted_datetime(instance.created_on) def format_updated_date(self, instance, *args, **kwargs): return get_locally_formatted_datetime(instance.updated_on) def format_taxful_total_price(self, instance, *args, **kwargs): if not instance.taxful_total_price: return "" return escape(format_money(instance.taxful_total_price)) def get_context_data(self, **kwargs): context = super(CartListView, self).get_context_data(**kwargs) context["title"] = _("Carts") return context def get_object_abstract(self, instance, item): return [ { "text": "%s" % instance, "class": "header" }, { "title": _(u"Created on"), "text": item["created_on"] }, { "title": _(u"Last updated on"), "text": item["updated_on"] }, { "title": _(u"Ordered"), "text": item["finished"] }, { "title": _(u"Total"), "text": item["taxful_total_price"] }, ]
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")) ] mass_actions = [ "shuup.admin.modules.contacts.mass_actions:EditContactsAction", "shuup.admin.modules.contacts.mass_actions:EditContactGroupsAction", ] def get_toolbar(self): return Toolbar([ NewActionButton.for_model( PersonContact, url=reverse("shuup_admin:contact.new") + "?type=person"), NewActionButton.for_model( CompanyContact, extra_css_class="btn-info", url=reverse("shuup_admin:contact.new") + "?type=company"), SettingsActionButton.for_model(Contact, return_url="contact") ]) def get_queryset(self): groups = self.get_filter().get("groups") query = Q(groups__in=groups) if groups else Q() return ( super(ContactListView, self).get_queryset() .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_object_abstract(self, instance, item): """ :type instance: shuup.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 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 = [ "shuup.admin.modules.contacts.mass_actions:EditContactsAction", "shuup.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("shuup_admin:contact.new") + "?type=person"), NewActionButton.for_model(CompanyContact, extra_css_class="btn-info", url=reverse("shuup_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.SHUUP_ENABLE_MULTIPLE_SHOPS and settings.SHUUP_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: shuup.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 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( "product_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( "product_sku", _(u"SKU"), display="product__sku", filter_config=RangeFilter(filter_field="product__sku"), ordering=3), Column( "product_barcode", _(u"Barcode"), display="product__barcode", filter_config=TextFilter(placeholder=_("Filter by barcode...")), ordering=4), Column( "product_mode", _(u"Mode"), display="product__mode", filter_config=ChoicesFilter(ProductMode.choices), ordering=5), Column( "primary_category", _("Primary Category"), display=(lambda instance: instance.primary_category.name if instance.primary_category else None), filter_config=TextFilter( filter_field="primary_category__translations__name", placeholder=_("Filter by category name...") ), ordering=6), Column( "categories", _("Categories"), display="format_categories", filter_config=TextFilter( filter_field="categories__translations__name", placeholder=_("Filter by category name...") ), ordering=7) ] related_objects = [ ("product", "shuup.core.models:Product"), ] mass_actions = [ "shuup.admin.modules.products.mass_actions:VisibleMassAction", "shuup.admin.modules.products.mass_actions:InvisibleMassAction", "shuup.admin.modules.products.mass_actions:FileResponseAction", "shuup.admin.modules.products.mass_actions:EditProductAttributesAction", ] toolbar_buttons_provider_key = "product_list_toolbar_provider" mass_actions_provider_key = "product_list_mass_actions_provider" def __init__(self): def get_suppliers_column(iterable): return first([col for col in iterable if col.id in ["suppliers", "shopproduct_suppliers"]], default=None) def get_suppliers_filter(): return TextFilter(filter_field="suppliers__name", placeholder=_("Filter by supplier name...")) if settings.SHUUP_ENABLE_MULTIPLE_SUPPLIERS and not get_suppliers_column(self.default_columns): self.default_columns.append( Column( "suppliers", _("Suppliers"), display="format_suppliers", ordering=8, filter_config=get_suppliers_filter(), ) ) super(ProductListView, self).__init__() suppliers_column = get_suppliers_column(self.columns) if suppliers_column: suppliers_column.filter_config = get_suppliers_filter() def format_categories(self, instance): return ", ".join(list(instance.categories.values_list("translations__name", flat=True))) def format_suppliers(self, instance): return ", ".join(list(instance.suppliers.values_list("name", flat=True))) 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='{}{}'>".format(settings.MEDIA_URL, thumbnail) return "<img src='%s'>" % static("shuup_admin/img/no_image_thumbnail.png") def get_queryset(self): filter = self.get_filter() shop = get_shop(self.request) 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 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 = [ "shuup.admin.modules.orders.mass_actions:CancelOrderAction", "shuup.admin.modules.orders.mass_actions:OrderConfirmationPdfAction", "shuup.admin.modules.orders.mass_actions:OrderDeliveryPdfAction", ] 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 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") }]