Add qoute step.
This commit is contained in:
		
							parent
							
								
									b71ea45681
								
							
						
					
					
						commit
						6ff4740d04
					
				
					 30 changed files with 3362 additions and 376 deletions
				
			
		| 
						 | 
				
			
			@ -1,3 +1,415 @@
 | 
			
		|||
from django.shortcuts import render
 | 
			
		||||
from django.shortcuts import render, get_object_or_404, redirect
 | 
			
		||||
import logging
 | 
			
		||||
from django.contrib.auth.decorators import login_required
 | 
			
		||||
from django.contrib import messages
 | 
			
		||||
from django.http import JsonResponse
 | 
			
		||||
from django.views.decorators.http import require_POST
 | 
			
		||||
from django.utils import timezone
 | 
			
		||||
from django.urls import reverse
 | 
			
		||||
from decimal import Decimal, InvalidOperation
 | 
			
		||||
import json
 | 
			
		||||
 | 
			
		||||
# Create your views here.
 | 
			
		||||
from processes.models import ProcessInstance, ProcessStep, StepInstance
 | 
			
		||||
from .models import Item, Quote, QuoteItem, Payment, Invoice
 | 
			
		||||
 | 
			
		||||
@login_required
 | 
			
		||||
def quote_step(request, instance_id, step_id):
 | 
			
		||||
    """مرحله انتخاب اقلام و ساخت پیشفاکتور"""
 | 
			
		||||
    instance = get_object_or_404(
 | 
			
		||||
        ProcessInstance.objects.select_related('process', 'well', 'requester', 'representative', 'representative__profile'),
 | 
			
		||||
        id=instance_id
 | 
			
		||||
    )
 | 
			
		||||
    step = get_object_or_404(instance.process.steps, id=step_id)
 | 
			
		||||
    
 | 
			
		||||
    # بررسی دسترسی به مرحله
 | 
			
		||||
    if not instance.can_access_step(step):
 | 
			
		||||
        messages.error(request, 'شما به این مرحله دسترسی ندارید. ابتدا مراحل قبلی را تکمیل کنید.')
 | 
			
		||||
        return redirect('processes:request_list')
 | 
			
		||||
    
 | 
			
		||||
    # دریافت آیتمها
 | 
			
		||||
    items = Item.objects.all().order_by('name')
 | 
			
		||||
    existing_quote = Quote.objects.filter(process_instance=instance).first()
 | 
			
		||||
    existing_quote_items = {}
 | 
			
		||||
    if existing_quote:
 | 
			
		||||
        existing_quote_items = {qi.item_id: qi.quantity for qi in existing_quote.items.all()}
 | 
			
		||||
    
 | 
			
		||||
    step_instance = instance.step_instances.filter(step=step).first()
 | 
			
		||||
    
 | 
			
		||||
    # Navigation logic
 | 
			
		||||
    previous_step = instance.process.steps.filter(order__lt=step.order).last()
 | 
			
		||||
    next_step = instance.process.steps.filter(order__gt=step.order).first()
 | 
			
		||||
    
 | 
			
		||||
    return render(request, 'invoices/quote_step.html', {
 | 
			
		||||
        'instance': instance,
 | 
			
		||||
        'step': step,
 | 
			
		||||
        'step_instance': step_instance,
 | 
			
		||||
        'items': items,
 | 
			
		||||
        'existing_quote_items': existing_quote_items,
 | 
			
		||||
        'existing_quote': existing_quote,
 | 
			
		||||
        'previous_step': previous_step,
 | 
			
		||||
        'next_step': next_step,
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
@require_POST
 | 
			
		||||
@login_required
 | 
			
		||||
def create_quote(request, instance_id, step_id):
 | 
			
		||||
    """ساخت/بروزرسانی پیشفاکتور از اقلام انتخابی"""
 | 
			
		||||
    instance = get_object_or_404(ProcessInstance, id=instance_id)
 | 
			
		||||
    step = get_object_or_404(instance.process.steps, id=step_id)
 | 
			
		||||
    
 | 
			
		||||
    try:
 | 
			
		||||
        items_payload = json.loads(request.POST.get('items') or '[]')
 | 
			
		||||
    except json.JSONDecodeError:
 | 
			
		||||
        return JsonResponse({'success': False, 'message': 'دادههای اقلام نامعتبر است'})
 | 
			
		||||
 | 
			
		||||
    # اطمینان از حضور اقلام پیشفرض حتی اگر کلاینت ارسال نکرده باشد
 | 
			
		||||
    payload_by_id = {}
 | 
			
		||||
    for entry in items_payload:
 | 
			
		||||
        try:
 | 
			
		||||
            iid = int(entry.get('id'))
 | 
			
		||||
            payload_by_id[iid] = int(entry.get('qty') or 1)
 | 
			
		||||
        except Exception:
 | 
			
		||||
            continue
 | 
			
		||||
 | 
			
		||||
    default_item_ids = set(Item.objects.filter(is_default_in_quotes=True).values_list('id', flat=True))
 | 
			
		||||
    if default_item_ids:
 | 
			
		||||
        for default_id in default_item_ids:
 | 
			
		||||
            if default_id not in payload_by_id:
 | 
			
		||||
                # مقدار پیش فرض را قرار بده
 | 
			
		||||
                default_qty = Item.objects.filter(id=default_id).values_list('default_quantity', flat=True).first() or 1
 | 
			
		||||
                payload_by_id[default_id] = int(default_qty)
 | 
			
		||||
 | 
			
		||||
    # بازسازی payload نهایی معتبر
 | 
			
		||||
    items_payload = [{'id': iid, 'qty': qty} for iid, qty in payload_by_id.items() if qty and qty > 0]
 | 
			
		||||
 | 
			
		||||
    if not items_payload:
 | 
			
		||||
        return JsonResponse({'success': False, 'message': 'هیچ آیتمی انتخاب نشده است'})
 | 
			
		||||
 | 
			
		||||
    # Create or reuse quote
 | 
			
		||||
    quote, _ = Quote.objects.get_or_create(
 | 
			
		||||
        process_instance=instance,
 | 
			
		||||
        defaults={
 | 
			
		||||
            'name': f"پیشفاکتور {instance.code}",
 | 
			
		||||
            'customer': instance.representative or request.user,
 | 
			
		||||
            'valid_until': timezone.now().date(),
 | 
			
		||||
            'created_by': request.user,
 | 
			
		||||
        }
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    # Replace quote items with submitted ones
 | 
			
		||||
    quote.items.all().delete()
 | 
			
		||||
    for entry in items_payload:
 | 
			
		||||
        try:
 | 
			
		||||
            item_id = int(entry.get('id'))
 | 
			
		||||
            qty = int(entry.get('qty') or 1)
 | 
			
		||||
        except (TypeError, ValueError):
 | 
			
		||||
            continue
 | 
			
		||||
        if qty <= 0:
 | 
			
		||||
            continue
 | 
			
		||||
        item = Item.objects.filter(id=item_id).first()
 | 
			
		||||
        if not item:
 | 
			
		||||
            continue
 | 
			
		||||
        QuoteItem.objects.create(
 | 
			
		||||
            quote=quote,
 | 
			
		||||
            item=item,
 | 
			
		||||
            quantity=qty,
 | 
			
		||||
            unit_price=item.unit_price,
 | 
			
		||||
            total_price=item.unit_price * qty,
 | 
			
		||||
        )
 | 
			
		||||
 | 
			
		||||
    quote.calculate_totals()
 | 
			
		||||
    
 | 
			
		||||
    # تکمیل مرحله
 | 
			
		||||
    step_instance, created = StepInstance.objects.get_or_create(
 | 
			
		||||
        process_instance=instance,
 | 
			
		||||
        step=step
 | 
			
		||||
    )
 | 
			
		||||
    step_instance.status = 'completed'
 | 
			
		||||
    step_instance.completed_at = timezone.now()
 | 
			
		||||
    step_instance.save()
 | 
			
		||||
    
 | 
			
		||||
    # انتقال به مرحله بعدی
 | 
			
		||||
    next_step = instance.process.steps.filter(order__gt=step.order).first()
 | 
			
		||||
    redirect_url = None
 | 
			
		||||
    if next_step:
 | 
			
		||||
        instance.current_step = next_step
 | 
			
		||||
        instance.save()
 | 
			
		||||
        # هدایت مستقیم به مرحله پیشنمایش پیشفاکتور
 | 
			
		||||
        redirect_url = reverse('invoices:quote_preview_step', args=[instance.id, next_step.id])
 | 
			
		||||
 | 
			
		||||
    return JsonResponse({'success': True, 'quote_id': quote.id, 'redirect': redirect_url})
 | 
			
		||||
 | 
			
		||||
@login_required
 | 
			
		||||
def quote_preview_step(request, instance_id, step_id):
 | 
			
		||||
    """مرحله صدور پیشفاکتور - نمایش و تایید فاکتور"""
 | 
			
		||||
    instance = get_object_or_404(
 | 
			
		||||
        ProcessInstance.objects.select_related('process', 'well', 'requester', 'representative', 'representative__profile'),
 | 
			
		||||
        id=instance_id
 | 
			
		||||
    )
 | 
			
		||||
    step = get_object_or_404(instance.process.steps, id=step_id)
 | 
			
		||||
    
 | 
			
		||||
    # بررسی دسترسی به مرحله
 | 
			
		||||
    if not instance.can_access_step(step):
 | 
			
		||||
        messages.error(request, 'شما به این مرحله دسترسی ندارید. ابتدا مراحل قبلی را تکمیل کنید.')
 | 
			
		||||
        return redirect('processes:request_list')
 | 
			
		||||
    
 | 
			
		||||
    # دریافت پیشفاکتور
 | 
			
		||||
    quote = get_object_or_404(Quote, process_instance=instance)
 | 
			
		||||
    
 | 
			
		||||
    step_instance = instance.step_instances.filter(step=step).first()
 | 
			
		||||
    
 | 
			
		||||
    # Navigation logic
 | 
			
		||||
    previous_step = instance.process.steps.filter(order__lt=step.order).last()
 | 
			
		||||
    next_step = instance.process.steps.filter(order__gt=step.order).first()
 | 
			
		||||
    
 | 
			
		||||
    return render(request, 'invoices/quote_preview_step.html', {
 | 
			
		||||
        'instance': instance,
 | 
			
		||||
        'step': step,
 | 
			
		||||
        'step_instance': step_instance,
 | 
			
		||||
        'quote': quote,
 | 
			
		||||
        'previous_step': previous_step,
 | 
			
		||||
        'next_step': next_step,
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
@login_required
 | 
			
		||||
def quote_print(request, instance_id):
 | 
			
		||||
    """صفحه پرینت پیشفاکتور"""
 | 
			
		||||
    instance = get_object_or_404(ProcessInstance, id=instance_id)
 | 
			
		||||
    quote = get_object_or_404(Quote, process_instance=instance)
 | 
			
		||||
    
 | 
			
		||||
    return render(request, 'invoices/quote_print.html', {
 | 
			
		||||
        'instance': instance,
 | 
			
		||||
        'quote': quote,
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
@require_POST
 | 
			
		||||
@login_required  
 | 
			
		||||
def approve_quote(request, instance_id, step_id):
 | 
			
		||||
    """تایید پیشفاکتور و انتقال به مرحله بعدی"""
 | 
			
		||||
    instance = get_object_or_404(ProcessInstance, id=instance_id)
 | 
			
		||||
    step = get_object_or_404(instance.process.steps, id=step_id)
 | 
			
		||||
    quote = get_object_or_404(Quote, process_instance=instance)
 | 
			
		||||
    
 | 
			
		||||
    # تایید پیشفاکتور
 | 
			
		||||
    quote.status = 'sent'
 | 
			
		||||
    quote.save()
 | 
			
		||||
    
 | 
			
		||||
    # تکمیل مرحله
 | 
			
		||||
    step_instance, created = StepInstance.objects.get_or_create(
 | 
			
		||||
        process_instance=instance,
 | 
			
		||||
        step=step
 | 
			
		||||
    )
 | 
			
		||||
    step_instance.status = 'completed'
 | 
			
		||||
    step_instance.completed_at = timezone.now()
 | 
			
		||||
    step_instance.save()
 | 
			
		||||
    
 | 
			
		||||
    # انتقال به مرحله بعدی
 | 
			
		||||
    next_step = instance.process.steps.filter(order__gt=step.order).first()
 | 
			
		||||
    redirect_url = None
 | 
			
		||||
    if next_step:
 | 
			
		||||
        instance.current_step = next_step
 | 
			
		||||
        instance.save()
 | 
			
		||||
        redirect_url = reverse('processes:step_detail', args=[instance.id, next_step.id])
 | 
			
		||||
    else:
 | 
			
		||||
        # در صورت نبود مرحله بعدی، بازگشت به لیست درخواستها
 | 
			
		||||
        redirect_url = reverse('processes:request_list')
 | 
			
		||||
 | 
			
		||||
    messages.success(request, 'پیشفاکتور با موفقیت تایید شد.')
 | 
			
		||||
    return JsonResponse({'success': True, 'message': 'پیشفاکتور با موفقیت تایید شد.', 'redirect': redirect_url})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@login_required
 | 
			
		||||
def quote_payment_step(request, instance_id, step_id):
 | 
			
		||||
    """مرحله سوم: ثبت فیشهای واریزی پیشفاکتور"""
 | 
			
		||||
    instance = get_object_or_404(
 | 
			
		||||
        ProcessInstance.objects.select_related('process', 'well', 'requester', 'representative', 'representative__profile'),
 | 
			
		||||
        id=instance_id
 | 
			
		||||
    )
 | 
			
		||||
    step = get_object_or_404(instance.process.steps, id=step_id)
 | 
			
		||||
 | 
			
		||||
    # بررسی دسترسی
 | 
			
		||||
    if not instance.can_access_step(step):
 | 
			
		||||
        messages.error(request, 'شما به این مرحله دسترسی ندارید. ابتدا مراحل قبلی را تکمیل کنید.')
 | 
			
		||||
        return redirect('processes:request_list')
 | 
			
		||||
 | 
			
		||||
    quote = get_object_or_404(Quote, process_instance=instance)
 | 
			
		||||
    invoice = Invoice.objects.filter(quote=quote).first()
 | 
			
		||||
    payments = invoice.payments.select_related('created_by').filter(is_deleted=False).all() if invoice else []
 | 
			
		||||
 | 
			
		||||
    previous_step = instance.process.steps.filter(order__lt=step.order).last()
 | 
			
		||||
    next_step = instance.process.steps.filter(order__gt=step.order).first()
 | 
			
		||||
 | 
			
		||||
    totals = {
 | 
			
		||||
        'final_amount': quote.final_amount,
 | 
			
		||||
        'paid_amount': quote.get_paid_amount(),
 | 
			
		||||
        'remaining_amount': quote.get_remaining_amount(),
 | 
			
		||||
        'is_fully_paid': quote.get_remaining_amount() <= 0,
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    step_instance = instance.step_instances.filter(step=step).first()
 | 
			
		||||
 | 
			
		||||
    return render(request, 'invoices/quote_payment_step.html', {
 | 
			
		||||
        'instance': instance,
 | 
			
		||||
        'step': step,
 | 
			
		||||
        'step_instance': step_instance,
 | 
			
		||||
        'quote': quote,
 | 
			
		||||
        'payments': payments,
 | 
			
		||||
        'totals': totals,
 | 
			
		||||
        'previous_step': previous_step,
 | 
			
		||||
        'next_step': next_step,
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@require_POST
 | 
			
		||||
@login_required
 | 
			
		||||
def add_quote_payment(request, instance_id, step_id):
 | 
			
		||||
    """افزودن فیش واریزی جدید برای پیشفاکتور"""
 | 
			
		||||
    instance = get_object_or_404(ProcessInstance, id=instance_id)
 | 
			
		||||
    step = get_object_or_404(instance.process.steps, id=step_id)
 | 
			
		||||
    quote = get_object_or_404(Quote, process_instance=instance)
 | 
			
		||||
    invoice, _ = Invoice.objects.get_or_create(
 | 
			
		||||
        process_instance=instance,
 | 
			
		||||
        quote=quote,
 | 
			
		||||
        defaults={
 | 
			
		||||
            'name': f"Invoice {quote.name}",
 | 
			
		||||
            'customer': quote.customer,
 | 
			
		||||
            'due_date': timezone.now().date(),
 | 
			
		||||
            'created_by': request.user,
 | 
			
		||||
        }
 | 
			
		||||
    )
 | 
			
		||||
 | 
			
		||||
    logger = logging.getLogger(__name__)
 | 
			
		||||
    try:
 | 
			
		||||
        amount = (request.POST.get('amount') or '').strip()
 | 
			
		||||
        payment_date = (request.POST.get('payment_date') or '').strip()
 | 
			
		||||
        payment_method = (request.POST.get('payment_method') or '').strip()
 | 
			
		||||
        reference_number = (request.POST.get('reference_number') or '').strip()
 | 
			
		||||
        notes = (request.POST.get('notes') or '').strip()
 | 
			
		||||
        receipt_image = request.FILES.get('receipt_image')
 | 
			
		||||
        # Server-side validation for required fields
 | 
			
		||||
        if not amount:
 | 
			
		||||
            return JsonResponse({'success': False, 'message': 'مبلغ را وارد کنید'})
 | 
			
		||||
        if not payment_date:
 | 
			
		||||
            return JsonResponse({'success': False, 'message': 'تاریخ پرداخت را وارد کنید'})
 | 
			
		||||
        if not payment_method:
 | 
			
		||||
            return JsonResponse({'success': False, 'message': 'روش پرداخت را انتخاب کنید'})
 | 
			
		||||
        if not reference_number:
 | 
			
		||||
            return JsonResponse({'success': False, 'message': 'شماره مرجع را وارد کنید'})
 | 
			
		||||
        if not receipt_image:
 | 
			
		||||
            return JsonResponse({'success': False, 'message': 'تصویر فیش را بارگذاری کنید'})
 | 
			
		||||
        # Normalize date to YYYY-MM-DD (accept YYYY/MM/DD from Persian datepicker)
 | 
			
		||||
        if '/' in payment_date:
 | 
			
		||||
            payment_date = payment_date.replace('/', '-')
 | 
			
		||||
 | 
			
		||||
        # Prevent overpayment
 | 
			
		||||
        try:
 | 
			
		||||
            amount_dec = Decimal(amount)
 | 
			
		||||
        except InvalidOperation:
 | 
			
		||||
            return JsonResponse({'success': False, 'message': 'مبلغ نامعتبر است'})
 | 
			
		||||
        remaining = quote.get_remaining_amount()
 | 
			
		||||
        if amount_dec > remaining:
 | 
			
		||||
            return JsonResponse({'success': False, 'message': 'مبلغ فیش بیشتر از مانده پیشفاکتور است'})
 | 
			
		||||
 | 
			
		||||
        Payment.objects.create(
 | 
			
		||||
            invoice=invoice,
 | 
			
		||||
            amount=amount_dec,
 | 
			
		||||
            payment_date=payment_date,
 | 
			
		||||
            payment_method=payment_method,
 | 
			
		||||
            reference_number=reference_number,
 | 
			
		||||
            receipt_image=receipt_image,
 | 
			
		||||
            notes=notes,
 | 
			
		||||
            created_by=request.user,
 | 
			
		||||
        )
 | 
			
		||||
    except Exception as e:
 | 
			
		||||
        logger.exception('Error adding quote payment (instance=%s, step=%s)', instance_id, step_id)
 | 
			
		||||
        return JsonResponse({'success': False, 'message': 'خطا در ثبت فیش', 'error': str(e)})
 | 
			
		||||
 | 
			
		||||
    redirect_url = reverse('invoices:quote_payment_step', args=[instance.id, step.id])
 | 
			
		||||
    return JsonResponse({'success': True, 'redirect': redirect_url})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@require_POST
 | 
			
		||||
@login_required
 | 
			
		||||
def update_quote_payment(request, instance_id, step_id, payment_id):
 | 
			
		||||
    instance = get_object_or_404(ProcessInstance, id=instance_id)
 | 
			
		||||
    step = get_object_or_404(instance.process.steps, id=step_id)
 | 
			
		||||
    quote = get_object_or_404(Quote, process_instance=instance)
 | 
			
		||||
    invoice = Invoice.objects.filter(quote=quote).first()
 | 
			
		||||
    if not invoice:
 | 
			
		||||
        return JsonResponse({'success': False, 'message': 'فاکتور یافت نشد'})
 | 
			
		||||
    payment = get_object_or_404(Payment, id=payment_id, invoice=invoice)
 | 
			
		||||
 | 
			
		||||
    try:
 | 
			
		||||
        amount = request.POST.get('amount')
 | 
			
		||||
        payment_date = request.POST.get('payment_date') or payment.payment_date
 | 
			
		||||
        payment_method = request.POST.get('payment_method') or payment.payment_method
 | 
			
		||||
        reference_number = request.POST.get('reference_number') or ''
 | 
			
		||||
        notes = request.POST.get('notes') or ''
 | 
			
		||||
        receipt_image = request.FILES.get('receipt_image')
 | 
			
		||||
        if amount:
 | 
			
		||||
            payment.amount = amount
 | 
			
		||||
        payment.payment_date = payment_date
 | 
			
		||||
        payment.payment_method = payment_method
 | 
			
		||||
        payment.reference_number = reference_number
 | 
			
		||||
        payment.notes = notes
 | 
			
		||||
        # اگر نیاز به ذخیره عکس در Payment دارید، فیلد آن اضافه شده است
 | 
			
		||||
        if receipt_image:
 | 
			
		||||
            payment.receipt_image = receipt_image
 | 
			
		||||
        payment.save()
 | 
			
		||||
    except Exception:
 | 
			
		||||
        return JsonResponse({'success': False, 'message': 'خطا در ویرایش فیش'})
 | 
			
		||||
 | 
			
		||||
    redirect_url = reverse('invoices:quote_payment_step', args=[instance.id, step.id])
 | 
			
		||||
    return JsonResponse({'success': True, 'redirect': redirect_url})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@require_POST
 | 
			
		||||
@login_required
 | 
			
		||||
def delete_quote_payment(request, instance_id, step_id, payment_id):
 | 
			
		||||
    instance = get_object_or_404(ProcessInstance, id=instance_id)
 | 
			
		||||
    step = get_object_or_404(instance.process.steps, id=step_id)
 | 
			
		||||
    quote = get_object_or_404(Quote, process_instance=instance)
 | 
			
		||||
    invoice = Invoice.objects.filter(quote=quote).first()
 | 
			
		||||
    if not invoice:
 | 
			
		||||
        return JsonResponse({'success': False, 'message': 'فاکتور یافت نشد'})
 | 
			
		||||
    payment = get_object_or_404(Payment, id=payment_id, invoice=invoice)
 | 
			
		||||
    try:
 | 
			
		||||
        # soft delete using project's BaseModel delete override
 | 
			
		||||
        payment.delete()
 | 
			
		||||
    except Exception:
 | 
			
		||||
        return JsonResponse({'success': False, 'message': 'خطا در حذف فیش'})
 | 
			
		||||
    redirect_url = reverse('invoices:quote_payment_step', args=[instance.id, step.id])
 | 
			
		||||
    return JsonResponse({'success': True, 'redirect': redirect_url})
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@require_POST
 | 
			
		||||
@login_required
 | 
			
		||||
def approve_payments(request, instance_id, step_id):
 | 
			
		||||
    """تایید مرحله پرداخت فیشها و انتقال به مرحله بعد"""
 | 
			
		||||
    instance = get_object_or_404(ProcessInstance, id=instance_id)
 | 
			
		||||
    step = get_object_or_404(instance.process.steps, id=step_id)
 | 
			
		||||
    quote = get_object_or_404(Quote, process_instance=instance)
 | 
			
		||||
 | 
			
		||||
    is_fully_paid = quote.get_remaining_amount() <= 0
 | 
			
		||||
 | 
			
		||||
    # تکمیل مرحله
 | 
			
		||||
    step_instance, _ = StepInstance.objects.get_or_create(process_instance=instance, step=step)
 | 
			
		||||
    step_instance.status = 'completed'
 | 
			
		||||
    step_instance.completed_at = timezone.now()
 | 
			
		||||
    step_instance.save()
 | 
			
		||||
 | 
			
		||||
    # حرکت به مرحله بعد
 | 
			
		||||
    next_step = instance.process.steps.filter(order__gt=step.order).first()
 | 
			
		||||
    redirect_url = reverse('processes:request_list')
 | 
			
		||||
    if next_step:
 | 
			
		||||
        instance.current_step = next_step
 | 
			
		||||
        instance.save()
 | 
			
		||||
        redirect_url = reverse('processes:step_detail', args=[instance.id, next_step.id])
 | 
			
		||||
 | 
			
		||||
    msg = 'پرداختها تایید شد'
 | 
			
		||||
    if is_fully_paid:
 | 
			
		||||
        msg += ' - مبلغ پیشفاکتور به طور کامل پرداخت شده است.'
 | 
			
		||||
    else:
 | 
			
		||||
        msg += ' - توجه: مبلغ پیشفاکتور به طور کامل پرداخت نشده است.'
 | 
			
		||||
 | 
			
		||||
    return JsonResponse({'success': True, 'message': msg, 'redirect': redirect_url, 'is_fully_paid': is_fully_paid})
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue