fix sabtfactor
This commit is contained in:
1 parent
339f909018
commit
bf78bc2520
1 file changed
+16
-22
+16
-22
@@ -951,7 +951,6 @@ def newFactor(request, c_id):
|
||||
|
||||
return redirect('/panel/customer/'+str(c_id)+'/factors/')
|
||||
|
||||
|
||||
@login_required(login_url='/panel/p_login/')
|
||||
def newFactor2(request, c_id):
|
||||
if request.method != 'POST':
|
||||
@@ -959,7 +958,6 @@ def newFactor2(request, c_id):
|
||||
|
||||
user_op = request.user
|
||||
|
||||
# ۱. پارس دادههای JSON ارسال شده از فرم (پشتیبانی کامل از ساختار paylist و orderList جاوااسکریپت)
|
||||
try:
|
||||
prds_list = json.loads(request.POST.get('prdsList') or '[]')
|
||||
json_pardakht_ha = json.loads(request.POST.get('PardakhtHa') or '{}')
|
||||
@@ -970,15 +968,18 @@ def newFactor2(request, c_id):
|
||||
factor_desc = request.POST.get('FactorDesc', '')
|
||||
sar_resid_date = _parse_jalali_date(request.POST.get('sarResidDate'))
|
||||
|
||||
# ۲. واکشی اطلاعات پایهای
|
||||
customer_obj = get_object_or_404(Customer, id=c_id)
|
||||
store_room = get_object_or_404(StoreRoom, user=user_op)
|
||||
|
||||
# ۳. واکشی دستهجمعی محصولات برای جلوگیری از فشار به دیتابیس
|
||||
product_ids = [item.get('prd_id') for item in prds_list if item.get('prd_id') and item.get('prd_id') != 9999]
|
||||
# رفع مشکل متنی/عددی در استخراج شناسه کالاها
|
||||
product_ids = []
|
||||
for item in prds_list:
|
||||
p_id = item.get('prd_id')
|
||||
if p_id and _safe_int(p_id) != 9999:
|
||||
product_ids.append(_safe_int(p_id))
|
||||
|
||||
products_by_id = {p.id: p for p in Product.objects.filter(id__in=product_ids)}
|
||||
|
||||
# ۴. محاسبه مبلغ کل با نادیده گرفتن محصولاتی که گارانتی/اشانتیون هستند
|
||||
sum_price = sum(
|
||||
_safe_int(item.get('prd_count')) * _safe_int(item.get('price'))
|
||||
for item in prds_list
|
||||
@@ -986,10 +987,8 @@ def newFactor2(request, c_id):
|
||||
)
|
||||
|
||||
try:
|
||||
# ۵. باز کردن یک تراکنش امن دیتابیس
|
||||
with transaction.atomic():
|
||||
|
||||
# ثبت آبجکت فاکتور
|
||||
new_factor = Factor.objects.create(
|
||||
customer=customer_obj,
|
||||
amount=sum_price,
|
||||
@@ -999,7 +998,6 @@ def newFactor2(request, c_id):
|
||||
user=user_op
|
||||
)
|
||||
|
||||
# ثبت بدهکاری کلی در سند حسابداری
|
||||
Article.objects.create(
|
||||
debit=sum_price,
|
||||
credit=0,
|
||||
@@ -1009,7 +1007,6 @@ def newFactor2(request, c_id):
|
||||
user=user_op
|
||||
)
|
||||
|
||||
# ثبت ریزپرداختیها بر اساس دیکشنری paylist جاوااسکریپت
|
||||
payment_map = {
|
||||
'l_naghd': 'نقد',
|
||||
'l_kartbekart': 'کارت به کارت',
|
||||
@@ -1035,7 +1032,6 @@ def newFactor2(request, c_id):
|
||||
user=user_op
|
||||
)
|
||||
|
||||
# ثبت اسناد چک و نسیه
|
||||
elif key in ['l_nesiye', 'l_checkPrice']:
|
||||
is_nesiye = (key == 'l_nesiye')
|
||||
type_str = 'nesiye' if is_nesiye else 'check'
|
||||
@@ -1053,12 +1049,12 @@ def newFactor2(request, c_id):
|
||||
sarresidDT=sar_resid_dt
|
||||
)
|
||||
|
||||
# ثبت آیتمهای فاکتور با کارایی بالا (املای کلاس FactorIteam دقیقا منطبق بر models.py)
|
||||
factor_items_pool = []
|
||||
user_fullname = f"{user_op.first_name} {user_op.last_name}".strip() or user_op.username
|
||||
|
||||
for item in prds_list:
|
||||
prd_id = item.get('prd_id')
|
||||
# تبدیل امن شناسه به عدد در همینجا برای جلوگیری از خطای یافت نشدن دیکشنری
|
||||
prd_id = _safe_int(item.get('prd_id'))
|
||||
prd_count = _safe_int(item.get('prd_count'))
|
||||
garanty_esh = item.get('garanty_Esh', '')
|
||||
|
||||
@@ -1073,8 +1069,10 @@ def newFactor2(request, c_id):
|
||||
))
|
||||
else:
|
||||
product_obj = products_by_id.get(prd_id)
|
||||
|
||||
# خطای کاربرپسند در صورت نبود محصول
|
||||
if not product_obj:
|
||||
raise ValidationError(f"محصولی با شناسه {prd_id} یافت نشد.")
|
||||
raise InventoryException(f"خطا در دریافت محصول: محصولی با شناسه {prd_id} در سیستم وجود ندارد.")
|
||||
|
||||
factor_items_pool.append(FactorIteam(
|
||||
factor=new_factor,
|
||||
@@ -1085,12 +1083,10 @@ def newFactor2(request, c_id):
|
||||
garantyEsh=garanty_esh
|
||||
))
|
||||
|
||||
# ثبت یکباره تمام آیتمها
|
||||
FactorIteam.objects.bulk_create(factor_items_pool, batch_size=500)
|
||||
|
||||
# چک کردن موجودی انبار و ثبت کسر کالا
|
||||
for item in prds_list:
|
||||
prd_id = item.get('prd_id')
|
||||
prd_id = _safe_int(item.get('prd_id'))
|
||||
if prd_id == 9999:
|
||||
continue
|
||||
|
||||
@@ -1098,7 +1094,9 @@ def newFactor2(request, c_id):
|
||||
garanty_esh = item.get('garanty_Esh', '')
|
||||
product_obj = products_by_id.get(prd_id)
|
||||
|
||||
# قفل کردن ردیف برای اطمینان ۱۰۰ درصدی از عدم تداخل پیش از متد Save مدل
|
||||
if not product_obj:
|
||||
continue
|
||||
|
||||
stock_records = ProductInStore.objects.select_for_update().filter(
|
||||
Product=product_obj,
|
||||
StoreRoom=store_room,
|
||||
@@ -1119,8 +1117,6 @@ def newFactor2(request, c_id):
|
||||
else:
|
||||
desc_text = f"خروج: {prd_count}#فروش#{customer_obj.name_family} * {user_fullname}"
|
||||
|
||||
# این خط بهطور خودکار متد حرفهای Save شما در models.py را فراخوانی میکند
|
||||
# و جداول تاریخچه انبارداری را نیز بروزرسانی مینماید
|
||||
ProductInStore.objects.create(
|
||||
StoreRoom=store_room,
|
||||
Product=product_obj,
|
||||
@@ -1131,13 +1127,11 @@ def newFactor2(request, c_id):
|
||||
)
|
||||
|
||||
except InventoryException as e:
|
||||
# اگر خطا دهد دیتابیس Rollback میشود و فرم در قالب همان پیغام HTML به کاربر برمیگردد
|
||||
return HttpResponse(str(e), status=400)
|
||||
except Exception as e:
|
||||
logger.error(f"Error creating factor for customer {c_id}: {str(e)}", exc_info=True)
|
||||
return HttpResponse("خطایی غیرمنتظره در سرور رخ داد. اطلاعات ذخیره نشد.", status=500)
|
||||
|
||||
# بازگشت موفقیتآمیز دقیقاً به همان آدرس فایل urls.py
|
||||
return redirect(f'/panel/customer/{c_id}/factors/')
|
||||
|
||||
@login_required(login_url='/panel/p_login/')
|
||||
|
||||
Reference in new issue
Block a user