add product
This commit is contained in:
1 parent
423d4cf40e
commit
c8d45dd07c
58 files changed
+8309
-674
No files matched your search
@@ -0,0 +1,109 @@
|
||||
"""Common admin ergonomics without changing application API contracts."""
|
||||
from django import forms
|
||||
from django.contrib import admin
|
||||
from django.db import models
|
||||
from django.core.exceptions import ValidationError
|
||||
|
||||
from utils.admin_excel import excel_response
|
||||
|
||||
|
||||
def workspace_id(obj):
|
||||
if obj is None:
|
||||
return None
|
||||
if hasattr(obj, 'sys_ws_id'):
|
||||
return obj.sys_ws_id
|
||||
for relation in ('order', 'form', 'ticket_comment'):
|
||||
if hasattr(obj, relation):
|
||||
return workspace_id(getattr(obj, relation))
|
||||
return None
|
||||
|
||||
|
||||
class RelatedWorkspaceForm(forms.ModelForm):
|
||||
def clean(self):
|
||||
cleaned = super().clean()
|
||||
workspace = cleaned.get('sys_ws')
|
||||
scope = workspace.pk if workspace else None
|
||||
if scope is None:
|
||||
for key in ('order', 'form', 'ticket_comment'):
|
||||
scope = workspace_id(cleaned.get(key))
|
||||
if scope is not None:
|
||||
break
|
||||
if scope is not None:
|
||||
for field in self._meta.model._meta.fields:
|
||||
if field.is_relation and field.name != 'sys_ws':
|
||||
value = cleaned.get(field.name)
|
||||
related_scope = workspace_id(value)
|
||||
if related_scope is not None and related_scope != scope:
|
||||
self.add_error(field.name, 'این رابطه متعلق به فضای کاری دیگری است.')
|
||||
self.check_category_parent(cleaned)
|
||||
self.check_domain_values(cleaned)
|
||||
return cleaned
|
||||
|
||||
def check_domain_values(self, cleaned):
|
||||
label = self._meta.model._meta.label_lower
|
||||
if label == 'cuser.cuserrole' and cleaned.get('mobile') is not None:
|
||||
from utils.validations.mobile import normalize_mobile
|
||||
try:
|
||||
cleaned['mobile'] = normalize_mobile(cleaned['mobile'])
|
||||
except ValidationError as error:
|
||||
self.add_error('mobile', error.messages)
|
||||
user = cleaned.get('cuser')
|
||||
if user and user.mobile != cleaned.get('mobile'):
|
||||
self.add_error('mobile', 'شماره نقش باید با شماره کاربر یکسان باشد.')
|
||||
if label in ('shop.cart', 'shop.orderitem'):
|
||||
key = 'quantity' if label == 'shop.cart' else 'amount'
|
||||
if cleaned.get(key) is not None and cleaned[key] < 1:
|
||||
self.add_error(key, 'تعداد باید حداقل یک باشد.')
|
||||
if label == 'shop.orderitem' and cleaned.get('price') is not None and cleaned['price'] < 0:
|
||||
self.add_error('price', 'قیمت نباید منفی باشد.')
|
||||
|
||||
def check_category_parent(self, cleaned):
|
||||
if self._meta.model._meta.label_lower != 'shop.productcategory':
|
||||
return
|
||||
parent = cleaned.get('parent')
|
||||
visited = set()
|
||||
while parent is not None:
|
||||
if parent.pk == self.instance.pk or parent.pk in visited:
|
||||
self.add_error('parent', 'دسته والد نباید یک چرخه ایجاد کند.')
|
||||
return
|
||||
visited.add(parent.pk)
|
||||
parent = parent.parent
|
||||
|
||||
|
||||
class CRMModelAdmin(admin.ModelAdmin):
|
||||
form = RelatedWorkspaceForm
|
||||
list_per_page = 50
|
||||
show_full_result_count = False
|
||||
save_on_top = True
|
||||
actions = ('export_selected',)
|
||||
sensitive_fields = ()
|
||||
|
||||
def __init__(self, model, admin_site):
|
||||
super().__init__(model, admin_site)
|
||||
fields = model._meta.fields
|
||||
names = {field.name for field in fields}
|
||||
if self.list_display == ('__str__',):
|
||||
candidates = ('id', 'name', 'name_family', 'title', 'mobile', 'customer', 'lead', 'form',
|
||||
'product', 'order', 'cuser_role', 'role_type', 'sys_ws', 'status', 'type',
|
||||
'is_active', 'expire', 'datetime', 'created_at')
|
||||
self.list_display = tuple(name for name in candidates if name in names)[:9]
|
||||
if not self.search_fields:
|
||||
self.search_fields = tuple(field.name for field in fields if isinstance(field, (models.CharField, models.TextField))
|
||||
and field.name not in self.sensitive_fields)
|
||||
if not self.list_filter:
|
||||
self.list_filter = tuple(field.name for field in fields if field.name == 'sys_ws' or field.choices
|
||||
or isinstance(field, models.BooleanField))
|
||||
self.readonly_fields = tuple(dict.fromkeys((*self.readonly_fields,
|
||||
*(name for name in ('created_at', 'updated_at', 'uuid') if name in names))))
|
||||
self.raw_id_fields = tuple(field.name for field in fields if field.many_to_one)
|
||||
self.list_select_related = tuple(field.name for field in fields if field.many_to_one)
|
||||
if 'created_at' in names:
|
||||
self.date_hierarchy = 'created_at'
|
||||
if not self.ordering and not model._meta.ordering:
|
||||
self.ordering = ('-pk',)
|
||||
|
||||
@admin.action(description='خروجی اکسل ردیفهای انتخابشده', permissions=['view'])
|
||||
def export_selected(self, request, queryset):
|
||||
fields = [field for field in self.model._meta.fields if field.name not in self.sensitive_fields]
|
||||
rows = queryset.values_list(*(field.attname for field in fields)).iterator()
|
||||
return excel_response([str(field.verbose_name) for field in fields], rows, f'{self.model._meta.model_name}.xlsx')
|
||||
Reference in new issue
Block a user