@@ -251,6 +259,25 @@ $(document).ready(function() {
kamaDatepicker('persianDateP', { buttonsColor: "red", forceFarsiDigits: true });
+ $(document).on('click', '.add-phone-btn', function() {
+ var phoneRow = `
+
`;
+ $(this).closest('div[id^="dynamic-phones"]').append(phoneRow);
+ });
+
+ $(document).on('click', '.remove-phone-btn', function() {
+ $(this).closest('.field.has-addons').remove();
+ });
$("#createCS").click(function(){
var u_name = $(".addNewUser").find('.an_name').val();
diff --git a/admin_panel/views.py b/admin_panel/views.py
index 5f01459..ea39851 100644
--- a/admin_panel/views.py
+++ b/admin_panel/views.py
@@ -611,7 +611,7 @@ def customers(request):
all_customers = Customer.objects.filter(laghv_bazdid=True).order_by('-create_date')
else:
searchStatus = False
- all_customers = Customer.objects.all().order_by('-create_date')
+ all_customers = Customer.objects.filter(is_active=True).order_by('-create_date')
paginator = Paginator(all_customers, 25) # Show 25 contacts per page.
page_number = request.GET.get('page', None)
@@ -671,7 +671,7 @@ def customerNew(request ,c_id):
@login_required(login_url='/panel/p_login/')
def customerNew2(request ,c_id):
- customer = Customer.objects.get(id=c_id)
+ customer = get_object_or_404(Customer, id=c_id, is_active=True)
categorys = ProductCategory.objects.all()
factorha = Factor.objects.filter(customer__id = c_id)
@@ -767,70 +767,86 @@ def productMojodi(request, p_id):
def customersAdd(request):
an_name = request.POST.get('an_name', '')
an_address = request.POST.get('an_address', '')
- phone1 = request.POST.get('phone1', '')
- phone2 = request.POST.get('phone2', '')
- phone3 = request.POST.get('phone3', '')
installDate = request.POST.get('installDate', '')
idnCode = request.POST.get('idnCode', '')
- an_name = request.POST.get('an_name', '')
+
+ # دریافت آرایههای عنوان و شماره تلفن
+ titles_list = request.POST.getlist('phone_titles')
+ phones_list = request.POST.getlist('phones')
+
+ # ترکیب عنوانها و شمارهها و حذف ردیفهای خالی
+ valid_phones = []
+ for title, phone in zip(titles_list, phones_list):
+ if phone.strip():
+ valid_phones.append({
+ 'title': title.strip() if title.strip() else 'تلفن',
+ 'phone': phone.strip()
+ })
- year = int(installDate.split('/')[0])
- month = int(installDate.split('/')[1])
- day = int(installDate.split('/')[2])
-
- #return HttpResponse(year)
- installDate = JalaliDate(year, month, day).to_gregorian()
+ year, month, day = map(int, installDate.split('/'))
+ installDate_gregorian = JalaliDate(year, month, day).to_gregorian()
newCs = Customer()
newCs.name_family = an_name
newCs.address = an_address
- newCs.phone1 = phone1
- newCs.phone2 = phone2
- newCs.phone3 = phone3
- newCs.installDate = installDate
+ newCs.installDate = installDate_gregorian
newCs.idCode = idnCode
+
+ # حفظ سازگاری با کدهای قدیمی (ریختن ۳ شماره اول در فیلدهای قدیمی)
+ newCs.phone1 = valid_phones[0]['phone'] if len(valid_phones) > 0 else ''
+ newCs.phone2 = valid_phones[1]['phone'] if len(valid_phones) > 1 else ''
+ newCs.phone3 = valid_phones[2]['phone'] if len(valid_phones) > 2 else ''
newCs.save()
- #return HttpResponse(installDate)
+ # ذخیره شمارهها به صورت نامحدود در جدول PhoneNumber
+ for item in valid_phones:
+ PhoneNumber.objects.create(customer=newCs, title=item['title'], phone_number=item['phone'])
+
return redirect('/panel/customers/')
- #return render(request, 'admin_panel/customersAdd.html')
+
@login_required(login_url='/panel/p_login/')
def customerEdit(request, c_id):
an_name = request.POST.get('an_name', '')
an_address = request.POST.get('an_address', '')
- phone1 = request.POST.get('phone1', '')
- phone2 = request.POST.get('phone2', '')
- phone3 = request.POST.get('phone3', '')
installDate = request.POST.get('installDate', '')
idnCode = request.POST.get('idnCode', '')
laghv_bazdid = request.POST.get('laghv_bazdid', False)
- an_name = request.POST.get('an_name', '')
- year = int(installDate.split('/')[0])
- month = int(installDate.split('/')[1])
- day = int(installDate.split('/')[2])
+ # دریافت آرایههای عنوان و شماره تلفن
+ titles_list = request.POST.getlist('phone_titles')
+ phones_list = request.POST.getlist('phones')
+
+ valid_phones = []
+ for title, phone in zip(titles_list, phones_list):
+ if phone.strip():
+ valid_phones.append({
+ 'title': title.strip() if title.strip() else 'تلفن',
+ 'phone': phone.strip()
+ })
- #return HttpResponse(year)
- installDate = JalaliDate(year, month, day).to_gregorian()
+ year, month, day = map(int, installDate.split('/'))
+ installDate_gregorian = JalaliDate(year, month, day).to_gregorian()
- newCs = Customer.objects.get(id=c_id)
+ newCs = get_object_or_404(Customer, id=c_id)
newCs.name_family = an_name
newCs.address = an_address
- newCs.phone1 = phone1
- newCs.phone2 = phone2
- newCs.phone3 = phone3
- newCs.installDate = installDate
+ newCs.installDate = installDate_gregorian
newCs.idCode = idnCode
- if laghv_bazdid == 'true':
- newCs.laghv_bazdid = True
- else:
- newCs.laghv_bazdid = False
+ newCs.laghv_bazdid = True if laghv_bazdid == 'true' else False
+
+ # آپدیت فیلدهای قدیمی جهت حفظ سازگاری
+ newCs.phone1 = valid_phones[0]['phone'] if len(valid_phones) > 0 else ''
+ newCs.phone2 = valid_phones[1]['phone'] if len(valid_phones) > 1 else ''
+ newCs.phone3 = valid_phones[2]['phone'] if len(valid_phones) > 2 else ''
newCs.save()
- #return HttpResponse(installDate)
- return redirect('/panel/customer/'+str(c_id))
+ # بروزرسانی جدول بینهایت (حذف قبلیها و درج مجدد)
+ PhoneNumber.objects.filter(customer=newCs).delete()
+ for item in valid_phones:
+ PhoneNumber.objects.create(customer=newCs, title=item['title'], phone_number=item['phone'])
+ return redirect('/panel/customer/'+str(c_id))
@login_required(login_url='/panel/p_login/')
def entezar(request):
@@ -1752,14 +1768,59 @@ def FactorDel(request, c_id, f_id):
return redirect('admin_panel:customerFactors', c_id=c_id)
+from django.contrib import messages
+from django.shortcuts import get_object_or_404, redirect
+import logging
+
+logger = logging.getLogger(__name__)
+
@login_required(login_url='/panel/p_login/')
@permission_required('admin_panel.DelCustomer', raise_exception=True)
def customerDel(request, c_id):
+ customer_obj = get_object_or_404(Customer, id=c_id)
+
try:
- Customer.objects.get(id=c_id).delete()
+ # ۱. بررسی وجود هرگونه سابقه مالی/حسابداری (حتی با مانده صفر)
+ has_articles = Article.objects.filter(customer=customer_obj).exists()
+
+ # ۲. بررسی وجود هرگونه سابقه چک یا نسیه (حتی در صورت پاس شدن و تسویه کامل)
+ has_sarresids = Sarresid.objects.filter(customer=customer_obj).exists()
+
+ # ۳. بررسی وجود هرگونه فاکتور ثبت شده برای این مشتری
+ has_factors = Factor.objects.filter(customer=customer_obj).exists()
+
+ # ۴. بررسی وجود هرگونه سابقه اقدام، بازدید یا نظرسنجی
+ has_actions = Action.objects.filter(customer=customer_obj).exists()
+
+ # ۵. اگر هر کدام از این سوابق وجود داشته باشد، به هیچ عنوان اجازه غیرفعالسازی/حذف نمیدهیم
+ if has_articles or has_sarresids or has_factors or has_actions:
+ error_msg = f"عملیات ناموفق: مشتری '{customer_obj.name_family}' به دلیل داشتن سابقه در سیستم قابل حذف نیست! دلایل: "
+ reasons = []
+
+ if has_articles:
+ reasons.append("داشتن تراکنش مالی یا گردش حسابداری")
+ if has_sarresids:
+ reasons.append("داشتن سابقه چک یا نسیه (حتی تسویه شده)")
+ if has_factors:
+ reasons.append("داشتن فاکتور ثبتشده")
+ if has_actions:
+ reasons.append("داشتن سابقه اقدامات، بازدید یا نظرسنجی")
+
+ error_msg += "، ".join(reasons) + "."
+
+ # ارسال پیام خطا به تمپلیت و بازگرداندن کاربر به صفحه قبلی
+ messages.error(request, error_msg)
+ return redirect(request.META.get('HTTP_REFERER', '/panel/customers/'))
+
+ # ۶. در صورتی که مشتری کاملاً خام بود و هیچ سابقهای در هیچ بخشی نداشت، حذف میشود
+ customer_obj.delete()
+ messages.success(request, f"مشتری '{customer_obj.name_family}' که فاقد هرگونه سابقهای بود، با موفقیت از سیستم حذف شد.")
return redirect('/panel/customers/')
- except:
- return HttpResponse("خطا در حذف مشتری")
+
+ except Exception as e:
+ logger.error(f"Error in deleting customer {c_id}: {str(e)}", exc_info=True)
+ messages.error(request, "خطای سیستمی در بررسی سوابق و حذف مشتری رخ داد.")
+ return redirect(request.META.get('HTTP_REFERER', '/panel/customers/'))
@login_required(login_url='/panel/p_login/')