Add qoute step.
This commit is contained in:
		
							parent
							
								
									b71ea45681
								
							
						
					
					
						commit
						6ff4740d04
					
				
					 30 changed files with 3362 additions and 376 deletions
				
			
		
							
								
								
									
										402
									
								
								invoices/templates/invoices/quote_payment_step.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										402
									
								
								invoices/templates/invoices/quote_payment_step.html
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,402 @@
 | 
			
		|||
{% extends '_base.html' %}
 | 
			
		||||
{% load static %}
 | 
			
		||||
{% load processes_tags %}
 | 
			
		||||
{% load humanize %}
 | 
			
		||||
 | 
			
		||||
{% block sidebar %}
 | 
			
		||||
    {% include 'sidebars/admin.html' %}
 | 
			
		||||
{% endblock sidebar %}
 | 
			
		||||
 | 
			
		||||
{% block navbar %}
 | 
			
		||||
    {% include 'navbars/admin.html' %}
 | 
			
		||||
{% endblock navbar %}
 | 
			
		||||
 | 
			
		||||
{% block title %}{{ step.name }} - درخواست {{ instance.code }}{% endblock %}
 | 
			
		||||
 | 
			
		||||
{% block style %}
 | 
			
		||||
<link rel="stylesheet" href="{% static 'assets/vendor/libs/bs-stepper/bs-stepper.css' %}">
 | 
			
		||||
<!-- Persian Date Picker CSS -->
 | 
			
		||||
<link rel="stylesheet" href="https://unpkg.com/persian-datepicker@latest/dist/css/persian-datepicker.min.css">
 | 
			
		||||
<style>
 | 
			
		||||
@media print {
 | 
			
		||||
  .no-print { display: none !important; }
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 | 
			
		||||
{% block content %}
 | 
			
		||||
{% include '_toasts.html' %}
 | 
			
		||||
{% csrf_token %}
 | 
			
		||||
<div class="container-xxl flex-grow-1 container-p-y">
 | 
			
		||||
  <div class="row">
 | 
			
		||||
    <div class="col-12 mb-4">
 | 
			
		||||
      <div class="d-flex align-items-center justify-content-between mb-3 no-print">
 | 
			
		||||
        <div>
 | 
			
		||||
          <h4 class="mb-1">{{ step.name }}: {{ instance.process.name }}</h4>
 | 
			
		||||
          <small class="text-muted d-block">
 | 
			
		||||
            اشتراک آب: {{ instance.well.water_subscription_number|default:"-" }}
 | 
			
		||||
            | نماینده: {{ instance.representative.profile.national_code|default:"-" }}
 | 
			
		||||
          </small>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="d-flex gap-2">
 | 
			
		||||
          <a href="{% url 'invoices:quote_print' instance.id %}" target="_blank" class="btn btn-outline-secondary">
 | 
			
		||||
            <i class="bx bx-printer"></i> پرینت
 | 
			
		||||
          </a>
 | 
			
		||||
          <a href="{% url 'processes:request_list' %}" class="btn btn-outline-secondary">بازگشت</a>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
 | 
			
		||||
      <div class="bs-stepper wizard-vertical vertical mt-2 no-print">
 | 
			
		||||
        {% stepper_header instance step %}
 | 
			
		||||
        <div class="bs-stepper-content">
 | 
			
		||||
      
 | 
			
		||||
          <form id="formAddPayment" enctype="multipart/form-data" onsubmit="return false;">
 | 
			
		||||
            {% csrf_token %}
 | 
			
		||||
            <div class="content active dstepper-block">
 | 
			
		||||
              <div class="content-header mb-3">
 | 
			
		||||
                <h6 class="mb-0">{{ step.name }}</h6>
 | 
			
		||||
                <small>ثبت فیشهای واریزی برای پیشفاکتور</small>
 | 
			
		||||
              </div>
 | 
			
		||||
              
 | 
			
		||||
              <div class="row g-3">
 | 
			
		||||
                <div class="col-12 col-lg-5">
 | 
			
		||||
                  <div class="card h-100 border">
 | 
			
		||||
                    <div class="card-header">
 | 
			
		||||
                      <h5 class="card-title mb-0">ثبت فیش جدید</h5>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="card-body">
 | 
			
		||||
                      <div class="mb-3">
 | 
			
		||||
                        <label class="form-label">مبلغ (تومان)</label>
 | 
			
		||||
                        <input type="number" min="1" class="form-control" name="amount" id="id_amount" required>
 | 
			
		||||
                      </div>
 | 
			
		||||
                      <div class="mb-3">
 | 
			
		||||
                        <label class="form-label">تاریخ پرداخت</label>
 | 
			
		||||
                        <input type="text" class="form-control" id="id_payment_date" name="payment_date" placeholder="انتخاب تاریخ" readonly required>
 | 
			
		||||
                      </div>
 | 
			
		||||
                      <div class="mb-3">
 | 
			
		||||
                        <label class="form-label">روش پرداخت</label>
 | 
			
		||||
                        <select class="form-select" name="payment_method" id="id_payment_method" required>
 | 
			
		||||
                          <option value="bank_transfer">انتقال بانکی</option>
 | 
			
		||||
                          <option value="card">کارت بانکی</option>
 | 
			
		||||
                          <option value="cash">نقدی</option>
 | 
			
		||||
                          <option value="check">چک</option>
 | 
			
		||||
                          <option value="other">سایر</option>
 | 
			
		||||
                        </select>
 | 
			
		||||
                      </div>
 | 
			
		||||
                      <div class="mb-3">
 | 
			
		||||
                        <label class="form-label">شماره مرجع</label>
 | 
			
		||||
                        <input type="text" class="form-control" name="reference_number" id="id_reference_number" placeholder="..." required>
 | 
			
		||||
                      </div>
 | 
			
		||||
                      <div class="mb-3">
 | 
			
		||||
                        <label class="form-label">تصویر فیش</label>
 | 
			
		||||
                        <input type="file" class="form-control" name="receipt_image" id="id_receipt_image" accept="image/*" required>
 | 
			
		||||
                      </div>
 | 
			
		||||
                      <div class="mb-3">
 | 
			
		||||
                        <label class="form-label">توضیحات</label>
 | 
			
		||||
                        <textarea class="form-control" rows="2" name="notes" id="id_notes"></textarea>
 | 
			
		||||
                      </div>
 | 
			
		||||
                      <div class="d-flex justify-content-end">
 | 
			
		||||
                        <button type="button" id="btnAddPayment" class="btn btn-primary">افزودن فیش</button>
 | 
			
		||||
                      </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                  </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="col-12 col-lg-7">
 | 
			
		||||
                  <div class="card mb-3 border">
 | 
			
		||||
                    <div class="card-header d-flex justify-content-between">
 | 
			
		||||
                      <h5 class="card-title mb-0">وضعیت پیشفاکتور</h5>
 | 
			
		||||
                      <a href="{% url 'invoices:quote_preview_step' instance.id step.id|add:'-1' %}" class="btn btn-sm btn-label-secondary">مشاهده پیشفاکتور</a>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="card-body">
 | 
			
		||||
                      <div class="row g-3">
 | 
			
		||||
                        <div class="col-6">
 | 
			
		||||
                          <div class="border rounded p-3">
 | 
			
		||||
                            <div class="small text-muted">مبلغ نهایی پیشفاکتور</div>
 | 
			
		||||
                            <div class="h5 mt-1">{{ totals.final_amount|floatformat:0|intcomma:False }} تومان</div>
 | 
			
		||||
                          </div>
 | 
			
		||||
                        </div>
 | 
			
		||||
                        <div class="col-6">
 | 
			
		||||
                          <div class="border rounded p-3">
 | 
			
		||||
                            <div class="small text-muted">مبلغ پرداختشده</div>
 | 
			
		||||
                            <div class="h5 mt-1 text-success">{{ totals.paid_amount|floatformat:0|intcomma:False }} تومان</div>
 | 
			
		||||
                          </div>
 | 
			
		||||
                        </div>
 | 
			
		||||
                        <div class="col-6">
 | 
			
		||||
                          <div class="border rounded p-3">
 | 
			
		||||
                            <div class="small text-muted">مانده</div>
 | 
			
		||||
                            <div class="h5 mt-1 {% if totals.is_fully_paid %}text-success{% else %}text-danger{% endif %}">{{ totals.remaining_amount|floatformat:0|intcomma:False }} تومان</div>
 | 
			
		||||
                          </div>
 | 
			
		||||
                        </div>
 | 
			
		||||
                        <div class="col-6 d-flex align-items-center">
 | 
			
		||||
                          {% if totals.is_fully_paid %}
 | 
			
		||||
                            <span class="badge bg-success">تسویه کامل</span>
 | 
			
		||||
                          {% else %}
 | 
			
		||||
                            <span class="badge bg-warning text-dark">باقیمانده دارد</span>
 | 
			
		||||
                          {% endif %}
 | 
			
		||||
                        </div>
 | 
			
		||||
                      </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                  </div>
 | 
			
		||||
 | 
			
		||||
                  <div class="card border">
 | 
			
		||||
                    <div class="card-header">
 | 
			
		||||
                      <h5 class="card-title mb-0">فیشهای ثبت شده</h5>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="table-responsive">
 | 
			
		||||
                      <table class="table table-striped mb-0">
 | 
			
		||||
                        <thead>
 | 
			
		||||
                          <tr>
 | 
			
		||||
                            <th>مبلغ</th>
 | 
			
		||||
                            <th>تاریخ</th>
 | 
			
		||||
                            <th>روش</th>
 | 
			
		||||
                            <th>شماره مرجع</th>
 | 
			
		||||
                            <th>تصویر</th>
 | 
			
		||||
                            <th style="width:120px">عملیات</th>
 | 
			
		||||
                          </tr>
 | 
			
		||||
                        </thead>
 | 
			
		||||
                        <tbody>
 | 
			
		||||
                          {% for p in payments %}
 | 
			
		||||
                          <tr>
 | 
			
		||||
                            <td>{{ p.amount|floatformat:0|intcomma:False }} تومان</td>
 | 
			
		||||
                            <td>{{ p.payment_date|date:'Y/m/d' }}</td>
 | 
			
		||||
                            <td>{{ p.get_payment_method_display }}</td>
 | 
			
		||||
                            <td>{{ p.reference_number|default:'-' }}</td>
 | 
			
		||||
                            <td>
 | 
			
		||||
                              {% if p.receipt_image %}
 | 
			
		||||
                                <a href="{{ p.receipt_image.url }}" target="_blank" class="btn btn-sm btn-outline-secondary" title="مشاهده" aria-label="مشاهده">
 | 
			
		||||
                                  <i class="bx bx-show"></i>
 | 
			
		||||
                                </a>
 | 
			
		||||
                              {% else %}
 | 
			
		||||
                                -
 | 
			
		||||
                              {% endif %}
 | 
			
		||||
                            </td>
 | 
			
		||||
                            <td>
 | 
			
		||||
                              <div class="btn-group">
 | 
			
		||||
                                <button type="button" class="btn btn-sm btn-outline-primary" onclick="editPayment({{ p.id }})" title="ویرایش" aria-label="ویرایش">
 | 
			
		||||
                                  <i class="bx bx-edit"></i>
 | 
			
		||||
                                </button>
 | 
			
		||||
                                <button type="button" class="btn btn-sm btn-outline-danger" onclick="openDeleteModal({{ p.id }})" title="حذف" aria-label="حذف">
 | 
			
		||||
                                  <i class="bx bx-trash"></i>
 | 
			
		||||
                                </button>
 | 
			
		||||
                              </div>
 | 
			
		||||
                            </td>
 | 
			
		||||
                          </tr>
 | 
			
		||||
                          {% empty %}
 | 
			
		||||
                          <tr>
 | 
			
		||||
                            <td colspan="6" class="text-center text-muted">تا کنون فیشی ثبت نشده است</td>
 | 
			
		||||
                          </tr>
 | 
			
		||||
                          {% endfor %}
 | 
			
		||||
                        </tbody>
 | 
			
		||||
                      </table>
 | 
			
		||||
                    </div>
 | 
			
		||||
                  </div>
 | 
			
		||||
                </div>
 | 
			
		||||
 | 
			
		||||
                <div class="col-12 d-flex justify-content-between mt-3">
 | 
			
		||||
                  {% if previous_step %}
 | 
			
		||||
                    <a href="{% url 'processes:step_detail' instance.id previous_step.id %}" class="btn btn-label-secondary">
 | 
			
		||||
                      <i class="bx bx-chevron-right bx-sm me-sm-2"></i>
 | 
			
		||||
                      قبلی
 | 
			
		||||
                    </a>
 | 
			
		||||
                  {% else %}
 | 
			
		||||
                    <span></span>
 | 
			
		||||
                  {% endif %}
 | 
			
		||||
                  <button type="button" id="btnApprovePayments" class="btn btn-primary">  
 | 
			
		||||
                    تایید پرداختها
 | 
			
		||||
                    <i class="bx bx-chevron-left bx-sm ms-sm-2"></i>
 | 
			
		||||
                  </button>
 | 
			
		||||
                </div>
 | 
			
		||||
              </div>
 | 
			
		||||
            </div>
 | 
			
		||||
          </form>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
</div>
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 | 
			
		||||
{% block script %}
 | 
			
		||||
<script>
 | 
			
		||||
  const isFullyPaid = {{ totals.is_fully_paid|yesno:'true,false' }};
 | 
			
		||||
  function buildFormData(form) {
 | 
			
		||||
    const fd = new FormData(form);
 | 
			
		||||
    fd.append('csrfmiddlewaretoken', document.querySelector('input[name=csrfmiddlewaretoken]').value);
 | 
			
		||||
    return fd;
 | 
			
		||||
  }
 | 
			
		||||
  document.getElementById('btnAddPayment').addEventListener('click', function() {
 | 
			
		||||
    // Front-end validation
 | 
			
		||||
    const amount = document.getElementById('id_amount').value.trim();
 | 
			
		||||
    const payDate = document.getElementById('id_payment_date').value.trim();
 | 
			
		||||
    const method = document.getElementById('id_payment_method').value.trim();
 | 
			
		||||
    const ref = document.getElementById('id_reference_number').value.trim();
 | 
			
		||||
    const img = document.getElementById('id_receipt_image').files[0];
 | 
			
		||||
    const notes = document.getElementById('id_notes').value.trim();
 | 
			
		||||
    if (!amount || !payDate || !method || !ref || !img) {
 | 
			
		||||
      showToast('همه فیلدها الزامی است', 'danger');
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
    const form = document.getElementById('formAddPayment');
 | 
			
		||||
    const fd = buildFormData(form);
 | 
			
		||||
    fetch('{% url "invoices:add_quote_payment" instance.id step.id %}', {
 | 
			
		||||
      method: 'POST',
 | 
			
		||||
      body: fd
 | 
			
		||||
    }).then(r => r.json()).then(resp => {
 | 
			
		||||
      if (resp.success) {
 | 
			
		||||
        showToast('فیش با موفقیت ثبت شد', 'success');
 | 
			
		||||
        if (resp.redirect) {
 | 
			
		||||
          setTimeout(() => { window.location.href = resp.redirect; }, 700);
 | 
			
		||||
        }
 | 
			
		||||
      } else {
 | 
			
		||||
        showToast(resp.message || 'خطا در ثبت فیش', 'danger');
 | 
			
		||||
      }
 | 
			
		||||
    }).catch(() => showToast('خطا در ارتباط با سرور', 'danger'));
 | 
			
		||||
  });
 | 
			
		||||
 | 
			
		||||
  let deleteTargetId = null;
 | 
			
		||||
  function openDeleteModal(id) {
 | 
			
		||||
    deleteTargetId = id;
 | 
			
		||||
    const modal = new bootstrap.Modal(document.getElementById('deletePaymentModal'));
 | 
			
		||||
    modal.show();
 | 
			
		||||
  }
 | 
			
		||||
  function confirmDeletePayment() {
 | 
			
		||||
    if (!deleteTargetId) return;
 | 
			
		||||
    const fd = new FormData();
 | 
			
		||||
    fd.append('csrfmiddlewaretoken', document.querySelector('input[name=csrfmiddlewaretoken]').value);
 | 
			
		||||
    fetch(`{% url "invoices:delete_quote_payment" instance.id step.id 0 %}`.replace('/0/', `/${deleteTargetId}/`), {
 | 
			
		||||
      method: 'POST',
 | 
			
		||||
      body: fd
 | 
			
		||||
    }).then(r => r.json()).then(resp => {
 | 
			
		||||
      if (resp.success && resp.redirect) {
 | 
			
		||||
        showToast('فیش با موفقیت حذف شد', 'success');
 | 
			
		||||
        setTimeout(() => { window.location.href = resp.redirect; }, 700);
 | 
			
		||||
      } else {
 | 
			
		||||
        showToast(resp.message || 'خطا در حذف فیش', 'danger');
 | 
			
		||||
      }
 | 
			
		||||
    }).catch(() => showToast('خطا در ارتباط با سرور', 'danger'));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function editPayment(id) {
 | 
			
		||||
    // برای سادگی، همین فرم را استفاده نمیکنیم؛ میتوانید مدال ویرایش اضافه کنید
 | 
			
		||||
    alert('ویرایش فیش را بعدا با مدال تکمیل میکنیم. فعلا حذف و افزودن مجدد انجام دهید.');
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function performApprovePayments() {
 | 
			
		||||
    const fd = new FormData();
 | 
			
		||||
    fd.append('csrfmiddlewaretoken', document.querySelector('input[name=csrfmiddlewaretoken]').value);
 | 
			
		||||
    fetch('{% url "invoices:approve_payments" instance.id step.id %}', {
 | 
			
		||||
      method: 'POST',
 | 
			
		||||
      body: fd
 | 
			
		||||
    }).then(r => r.json()).then(resp => {
 | 
			
		||||
      if (resp.success && resp.redirect) {
 | 
			
		||||
        showToast(resp.message, 'success');
 | 
			
		||||
        setTimeout(() => { window.location.href = resp.redirect; }, 600);
 | 
			
		||||
      } else {
 | 
			
		||||
        showToast(resp.message || 'خطا در تایید پرداختها', 'danger');
 | 
			
		||||
      }
 | 
			
		||||
    }).catch(() => showToast('خطا در ارتباط با سرور', 'danger'));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  function openApproveModal() {
 | 
			
		||||
    const el = document.getElementById('approvePaymentsModal');
 | 
			
		||||
    const remEl = document.getElementById('remainingAmountText');
 | 
			
		||||
    if (remEl) {
 | 
			
		||||
      remEl.textContent = '{{ totals.remaining_amount|floatformat:0|intcomma:False }} تومان';
 | 
			
		||||
    }
 | 
			
		||||
    // Prefer jQuery plugin if available to avoid namespace issues
 | 
			
		||||
    if (window.$ && typeof $(el).modal === 'function') {
 | 
			
		||||
      $(el).modal('show');
 | 
			
		||||
    } else if (window.bootstrap && window.bootstrap.Modal) {
 | 
			
		||||
      const modal = new window.bootstrap.Modal(el);
 | 
			
		||||
      modal.show();
 | 
			
		||||
    } else {
 | 
			
		||||
      // fallback: force display
 | 
			
		||||
      el.classList.add('show');
 | 
			
		||||
      el.style.display = 'block';
 | 
			
		||||
      el.removeAttribute('aria-hidden');
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  document.getElementById('btnApprovePayments').addEventListener('click', function() {
 | 
			
		||||
    if (isFullyPaid) {
 | 
			
		||||
      performApprovePayments();
 | 
			
		||||
    } else {
 | 
			
		||||
      openApproveModal();
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<!-- Persian Date Picker JS -->
 | 
			
		||||
<script src="https://unpkg.com/persian-date@latest/dist/persian-date.min.js"></script>
 | 
			
		||||
<script src="https://unpkg.com/persian-datepicker@latest/dist/js/persian-datepicker.min.js"></script>
 | 
			
		||||
<script>
 | 
			
		||||
  (function initPersianDatePicker() {
 | 
			
		||||
    if (window.$ && $.fn.persianDatepicker && $('#id_payment_date').length) {
 | 
			
		||||
      try {
 | 
			
		||||
        $('#id_payment_date').persianDatepicker({
 | 
			
		||||
          format: 'YYYY/MM/DD',
 | 
			
		||||
          initialValue: false,
 | 
			
		||||
          autoClose: true,
 | 
			
		||||
          persianDigit: false,
 | 
			
		||||
          observer: true,
 | 
			
		||||
          calendar: { persian: { locale: 'fa', leapYearMode: 'astronomical' } },
 | 
			
		||||
          onSelect: function(unix) {
 | 
			
		||||
            const gregorianDate = new Date(unix);
 | 
			
		||||
            const year = gregorianDate.getFullYear();
 | 
			
		||||
            const month = String(gregorianDate.getMonth() + 1).padStart(2, '0');
 | 
			
		||||
            const day = String(gregorianDate.getDate()).padStart(2, '0');
 | 
			
		||||
            const gregorianDateString = `${year}-${month}-${day}`;
 | 
			
		||||
            if (window.persianDate) {
 | 
			
		||||
              const persianDate = new window.persianDate(unix);
 | 
			
		||||
              const persianDateString = persianDate.format('YYYY/MM/DD');
 | 
			
		||||
              $('#id_payment_date').val(persianDateString);
 | 
			
		||||
            } else {
 | 
			
		||||
              $('#id_payment_date').val(gregorianDateString);
 | 
			
		||||
            }
 | 
			
		||||
            $('#id_payment_date').attr('data-gregorian', gregorianDateString);
 | 
			
		||||
          }
 | 
			
		||||
        });
 | 
			
		||||
      } catch (e) { console.error('Error initializing Persian Date Picker:', e); }
 | 
			
		||||
    }
 | 
			
		||||
  })();
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<!-- Delete Confirmation Modal -->
 | 
			
		||||
<div class="modal fade" id="deletePaymentModal" tabindex="-1" aria-labelledby="deletePaymentModalLabel" aria-hidden="true">
 | 
			
		||||
  <div class="modal-dialog">
 | 
			
		||||
    <div class="modal-content">
 | 
			
		||||
      <div class="modal-header">
 | 
			
		||||
        <h5 class="modal-title" id="deletePaymentModalLabel">تایید حذف فیش</h5>
 | 
			
		||||
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="modal-body">
 | 
			
		||||
        آیا از حذف این فیش مطمئن هستید؟ این عمل قابل بازگشت نیست.
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="modal-footer">
 | 
			
		||||
        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">انصراف</button>
 | 
			
		||||
        <button type="button" class="btn btn-danger" onclick="confirmDeletePayment()" data-bs-dismiss="modal">حذف</button>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
</div>
 | 
			
		||||
<!-- Approve Confirmation Modal (shown when remaining amount > 0) -->
 | 
			
		||||
<div class="modal fade" id="approvePaymentsModal" tabindex="-1" aria-labelledby="approvePaymentsModalLabel" aria-hidden="true">
 | 
			
		||||
  <div class="modal-dialog">
 | 
			
		||||
    <div class="modal-content">
 | 
			
		||||
      <div class="modal-header">
 | 
			
		||||
        <h5 class="modal-title" id="approvePaymentsModalLabel">تایید نهایی پرداختها</h5>
 | 
			
		||||
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="modal-body">
 | 
			
		||||
        مبلغی از پیشفاکتور هنوز پرداخت نشده است.
 | 
			
		||||
        <div class="mt-2">مانده: <strong id="remainingAmountText"></strong></div>
 | 
			
		||||
        آیا مطمئن هستید که میخواهید مرحله را تایید و به مرحله بعد بروید؟
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="modal-footer">
 | 
			
		||||
        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">انصراف</button>
 | 
			
		||||
        <button type="button" class="btn btn-primary" data-bs-dismiss="modal" onclick="performApprovePayments()">بله، تایید</button>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
</div>
 | 
			
		||||
{% endblock %}
 | 
			
		||||
							
								
								
									
										287
									
								
								invoices/templates/invoices/quote_preview_step.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										287
									
								
								invoices/templates/invoices/quote_preview_step.html
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,287 @@
 | 
			
		|||
{% extends '_base.html' %}
 | 
			
		||||
{% load static %}
 | 
			
		||||
{% load processes_tags %}
 | 
			
		||||
{% load humanize %}
 | 
			
		||||
 | 
			
		||||
{% block sidebar %}
 | 
			
		||||
    {% include 'sidebars/admin.html' %}
 | 
			
		||||
{% endblock sidebar %}
 | 
			
		||||
 | 
			
		||||
{% block navbar %}
 | 
			
		||||
    {% include 'navbars/admin.html' %}
 | 
			
		||||
{% endblock navbar %}
 | 
			
		||||
 | 
			
		||||
{% block title %}{{ step.name }} - درخواست {{ instance.code }}{% endblock %}
 | 
			
		||||
 | 
			
		||||
{% block style %}
 | 
			
		||||
<link rel="stylesheet" href="{% static 'assets/vendor/libs/bs-stepper/bs-stepper.css' %}">
 | 
			
		||||
<style>
 | 
			
		||||
@media print {
 | 
			
		||||
  .no-print { display: none !important; }
 | 
			
		||||
}
 | 
			
		||||
</style>
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 | 
			
		||||
{% block content %}
 | 
			
		||||
{% include '_toasts.html' %}
 | 
			
		||||
{% csrf_token %}
 | 
			
		||||
<div class="container-xxl flex-grow-1 container-p-y">
 | 
			
		||||
  <div class="row">
 | 
			
		||||
    <div class="col-12 mb-4">
 | 
			
		||||
      <div class="d-flex align-items-center justify-content-between mb-3 no-print">
 | 
			
		||||
        <div>
 | 
			
		||||
          <h4 class="mb-1">{{ step.name }}: {{ instance.process.name }}</h4>
 | 
			
		||||
          <small class="text-muted d-block">
 | 
			
		||||
            اشتراک آب: {{ instance.well.water_subscription_number|default:"-" }}
 | 
			
		||||
            | نماینده: {{ instance.representative.profile.national_code|default:"-" }}
 | 
			
		||||
          </small>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="d-flex gap-2">
 | 
			
		||||
          <a href="{% url 'invoices:quote_print' instance.id %}" target="_blank" class="btn btn-outline-secondary">
 | 
			
		||||
            <i class="bx bx-printer"></i> پرینت
 | 
			
		||||
          </a>
 | 
			
		||||
          <a href="{% url 'processes:request_list' %}" class="btn btn-outline-secondary">بازگشت</a>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
 | 
			
		||||
      <div class="bs-stepper wizard-vertical vertical mt-2 no-print">
 | 
			
		||||
        {% stepper_header instance step %}
 | 
			
		||||
        <div class="bs-stepper-content">
 | 
			
		||||
            <!-- Invoice Preview Card -->
 | 
			
		||||
      <div class="card invoice-preview-card mt-4">
 | 
			
		||||
        <div class="card-body">
 | 
			
		||||
          <div class="d-flex justify-content-between flex-xl-row flex-md-column flex-sm-row flex-column p-sm-3 p-0">
 | 
			
		||||
            <div class="mb-xl-0 mb-4">
 | 
			
		||||
              <div class="d-flex svg-illustration mb-3 gap-2">
 | 
			
		||||
                <span class="app-brand-logo demo">
 | 
			
		||||
                  <svg width="25" viewBox="0 0 25 42" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
 | 
			
		||||
                    <defs>
 | 
			
		||||
                      <path d="M13.7918663,0.358365126 L3.39788168,7.44174259 C0.566865006,9.69408886 -0.379795268,12.4788597 0.557900856,15.7960551 C0.68998853,16.2305145 1.09562888,17.7872135 3.12357076,19.2293357 C3.8146334,19.7207684 5.32369333,20.3834223 7.65075054,21.2172976 L7.59773219,21.2525164 L2.63468769,24.5493413 C0.445452254,26.3002124 0.0884951797,28.5083815 1.56381646,31.1738486 C2.83770406,32.8170431 5.20850219,33.2640127 7.09180128,32.5391577 C8.347334,32.0559211 11.4559176,30.0011079 16.4175519,26.3747182 C18.0338572,24.4997857 18.6973423,22.4544883 18.4080071,20.2388261 C17.963753,17.5346866 16.1776345,15.5799961 13.0496516,14.3747546 L10.9194936,13.4715819 L18.6192054,7.984237 L13.7918663,0.358365126 Z" id="path-1"></path>
 | 
			
		||||
                      <path d="M5.47320593,6.00457225 C4.05321814,8.216144 4.36334763,10.0722806 6.40359441,11.5729822 C8.61520715,12.571656 10.0999176,13.2171421 10.8577257,13.5094407 L15.5088241,14.433041 L18.6192054,7.984237 C15.5364148,3.11535317 13.9273018,0.573395879 13.7918663,0.358365126 C13.5790555,0.511491653 10.8061687,2.3935607 5.47320593,6.00457225 Z" id="path-3"></path>
 | 
			
		||||
                      <path d="M7.50063644,21.2294429 L12.3234468,23.3159332 C14.1688022,24.7579751 14.397098,26.4880487 13.008334,28.506154 C11.6195701,30.5242593 10.3099883,31.790241 9.07958868,32.3040991 C5.78142938,33.4346997 4.13234973,34 4.13234973,34 C4.13234973,34 2.75489982,33.0538207 2.37032616e-14,31.1614621 C-0.55822714,27.8186216 -0.55822714,26.0572515 -4.05231404e-15,25.8773518 C0.83734071,25.6075023 2.77988457,22.8248993 3.3049379,22.52991 C3.65497346,22.3332504 5.05353963,21.8997614 7.50063644,21.2294429 Z" id="path-4"></path>
 | 
			
		||||
                      <path d="M20.6,7.13333333 L25.6,13.8 C26.2627417,14.6836556 26.0836556,15.9372583 25.2,16.6 C24.8538077,16.8596443 24.4327404,17 24,17 L14,17 C12.8954305,17 12,16.1045695 12,15 C12,14.5672596 12.1403557,14.1461923 12.4,13.8 L17.4,7.13333333 C18.0627417,6.24967773 19.3163444,6.07059163 20.2,6.73333333 C20.3516113,6.84704183 20.4862915,6.981722 20.6,7.13333333 Z" id="path-5"></path>
 | 
			
		||||
                    </defs>
 | 
			
		||||
                    <g id="g-app-brand" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
 | 
			
		||||
                      <g id="Brand-Logo" transform="translate(-27.000000, -15.000000)">
 | 
			
		||||
                        <g id="Icon" transform="translate(27.000000, 15.000000)">
 | 
			
		||||
                          <g id="Mask" transform="translate(0.000000, 8.000000)">
 | 
			
		||||
                            <mask id="mask-2" fill="white">
 | 
			
		||||
                              <use xlink:href="#path-1"></use>
 | 
			
		||||
                            </mask>
 | 
			
		||||
                            <use fill="#696cff" xlink:href="#path-1"></use>
 | 
			
		||||
                            <g id="Path-3" mask="url(#mask-2)">
 | 
			
		||||
                              <use fill="#696cff" xlink:href="#path-3"></use>
 | 
			
		||||
                              <use fill-opacity="0.2" fill="#FFFFFF" xlink:href="#path-3"></use>
 | 
			
		||||
                            </g>
 | 
			
		||||
                            <g id="Path-4" mask="url(#mask-2)">
 | 
			
		||||
                              <use fill="#696cff" xlink:href="#path-4"></use>
 | 
			
		||||
                              <use fill-opacity="0.2" fill="#FFFFFF" xlink:href="#path-4"></use>
 | 
			
		||||
                            </g>
 | 
			
		||||
                          </g>
 | 
			
		||||
                          <g id="Triangle" transform="translate(19.000000, 11.000000) rotate(-300.000000) translate(-19.000000, -11.000000) ">
 | 
			
		||||
                            <use fill="#696cff" xlink:href="#path-5"></use>
 | 
			
		||||
                            <use fill-opacity="0.2" fill="#FFFFFF" xlink:href="#path-5"></use>
 | 
			
		||||
                          </g>
 | 
			
		||||
                        </g>
 | 
			
		||||
                      </g>
 | 
			
		||||
                    </g>
 | 
			
		||||
                  </svg>
 | 
			
		||||
                </span>
 | 
			
		||||
                <span class="app-brand-text demo text-body fw-bold">شرکت آب منطقهای</span>
 | 
			
		||||
              </div>
 | 
			
		||||
              <p class="mb-1">دفتر مرکزی، خیابان اصلی</p>
 | 
			
		||||
              <p class="mb-1">تهران، ایران</p>
 | 
			
		||||
              <p class="mb-0">۰۲۱-۱۲۳۴۵۶۷۸</p>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div>
 | 
			
		||||
              <h4>پیشفاکتور #{{ quote.name }}</h4>
 | 
			
		||||
              <div class="mb-2">
 | 
			
		||||
                <span class="me-1">تاریخ صدور:</span>
 | 
			
		||||
                <span class="fw-medium">{{ quote.jcreated }}</span>
 | 
			
		||||
              </div>
 | 
			
		||||
              <div>
 | 
			
		||||
                <span class="me-1">معتبر تا:</span>
 | 
			
		||||
                <span class="fw-medium">{{ quote.valid_until|date:"Y/m/d" }}</span>
 | 
			
		||||
              </div>
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <hr class="my-0">
 | 
			
		||||
        <div class="card-body">
 | 
			
		||||
          <div class="row p-sm-3 p-0">
 | 
			
		||||
            <div class="col-xl-6 col-md-12 col-sm-5 col-12 mb-xl-0 mb-md-4 mb-sm-0 mb-4">
 | 
			
		||||
              <h6 class="pb-2">صادر شده برای:</h6>
 | 
			
		||||
              <p class="mb-1">{{ quote.customer.get_full_name }}</p>
 | 
			
		||||
              {% if instance.representative.profile %}
 | 
			
		||||
              <p class="mb-1">کد ملی: {{ instance.representative.profile.national_code }}</p>
 | 
			
		||||
              <p class="mb-1">{{ instance.representative.profile.address|default:"آدرس نامشخص" }}</p>
 | 
			
		||||
              <p class="mb-1">{{ instance.representative.profile.phone_number_1|default:"" }}</p>
 | 
			
		||||
              {% endif %}
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="col-xl-6 col-md-12 col-sm-7 col-12">
 | 
			
		||||
              <h6 class="pb-2">اطلاعات چاه:</h6>
 | 
			
		||||
              <table>
 | 
			
		||||
                <tbody>
 | 
			
		||||
                  <tr>
 | 
			
		||||
                    <td class="pe-3">شماره اشتراک آب:</td>
 | 
			
		||||
                    <td>{{ instance.well.water_subscription_number }}</td>
 | 
			
		||||
                  </tr>
 | 
			
		||||
                  <tr>
 | 
			
		||||
                    <td class="pe-3">شماره اشتراک برق:</td>
 | 
			
		||||
                    <td>{{ instance.well.electricity_subscription_number|default:"-" }}</td>
 | 
			
		||||
                  </tr>
 | 
			
		||||
                  <tr>
 | 
			
		||||
                    <td class="pe-3">سریال کنتور:</td>
 | 
			
		||||
                    <td>{{ instance.well.water_meter_serial_number|default:"-" }}</td>
 | 
			
		||||
                  </tr>
 | 
			
		||||
                  <tr>
 | 
			
		||||
                    <td class="pe-3">قدرت چاه:</td>
 | 
			
		||||
                    <td>{{ instance.well.well_power|default:"-" }}</td>
 | 
			
		||||
                  </tr>
 | 
			
		||||
                  <tr>
 | 
			
		||||
                    <td class="pe-3">کد درخواست:</td>
 | 
			
		||||
                    <td>{{ instance.code }}</td>
 | 
			
		||||
                  </tr>
 | 
			
		||||
                </tbody>
 | 
			
		||||
              </table>
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="table-responsive">
 | 
			
		||||
          <table class="table border-top m-0">
 | 
			
		||||
            <thead>
 | 
			
		||||
              <tr>
 | 
			
		||||
                <th>آیتم</th>
 | 
			
		||||
                <th>توضیحات</th>
 | 
			
		||||
                <th>قیمت واحد</th>
 | 
			
		||||
                <th>تعداد</th>
 | 
			
		||||
                <th>قیمت کل</th>
 | 
			
		||||
              </tr>
 | 
			
		||||
            </thead>
 | 
			
		||||
            <tbody>
 | 
			
		||||
              {% for quote_item in quote.items.all %}
 | 
			
		||||
              <tr>
 | 
			
		||||
                <td class="text-nowrap">{{ quote_item.item.name }}</td>
 | 
			
		||||
                <td class="text-nowrap">{{ quote_item.item.description|default:"-" }}</td>
 | 
			
		||||
                <td>{{ quote_item.unit_price|floatformat:0|intcomma:False }} تومان</td>
 | 
			
		||||
                <td>{{ quote_item.quantity }}</td>
 | 
			
		||||
                <td>{{ quote_item.total_price|floatformat:0|intcomma:False }} تومان</td>
 | 
			
		||||
              </tr>
 | 
			
		||||
              {% endfor %}
 | 
			
		||||
              <tr>
 | 
			
		||||
                <td colspan="3" class="align-top px-4 py-5">
 | 
			
		||||
                  <p class="mb-2">
 | 
			
		||||
                    <span class="me-1 fw-medium">صادر کننده:</span>
 | 
			
		||||
                    <span>{{ quote.created_by.get_full_name }}</span>
 | 
			
		||||
                  </p>
 | 
			
		||||
                  <span>با تشکر از انتخاب شما</span>
 | 
			
		||||
                </td>
 | 
			
		||||
                <td class="text-end px-4 py-5">
 | 
			
		||||
                  <p class="mb-2">جمع کل:</p>
 | 
			
		||||
                  {% if quote.discount_amount > 0 %}
 | 
			
		||||
                  <p class="mb-2">تخفیف:</p>
 | 
			
		||||
                  {% endif %}
 | 
			
		||||
                  <p class="mb-0 fw-bold">مبلغ نهایی:</p>
 | 
			
		||||
                </td>
 | 
			
		||||
                <td class="px-4 py-5">
 | 
			
		||||
                  <p class="fw-medium mb-2">{{ quote.total_amount|floatformat:0|intcomma:False }} تومان</p>
 | 
			
		||||
                  {% if quote.discount_amount > 0 %}
 | 
			
		||||
                  <p class="fw-medium mb-2">{{ quote.discount_amount|floatformat:0|intcomma:False }} تومان</p>
 | 
			
		||||
                  {% endif %}
 | 
			
		||||
                  <p class="fw-bold mb-0">{{ quote.final_amount|floatformat:0|intcomma:False }} تومان</p>
 | 
			
		||||
                </td>
 | 
			
		||||
              </tr>
 | 
			
		||||
            </tbody>
 | 
			
		||||
          </table>
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        {% if quote.notes %}
 | 
			
		||||
        <div class="card-body">
 | 
			
		||||
          <div class="row">
 | 
			
		||||
            <div class="col-12">
 | 
			
		||||
              <span class="fw-medium">یادداشت:</span>
 | 
			
		||||
              <span>{{ quote.notes }}</span>
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        {% endif %}
 | 
			
		||||
      </div>
 | 
			
		||||
      
 | 
			
		||||
      <!-- Action Buttons -->
 | 
			
		||||
      <div class="row mt-4 no-print">
 | 
			
		||||
        <div class="col-12">
 | 
			
		||||
          <div class="d-flex justify-content-between">
 | 
			
		||||
            {% if previous_step %}
 | 
			
		||||
              <a href="{% url 'processes:step_detail' instance.id previous_step.id %}" 
 | 
			
		||||
                 class="btn btn-label-secondary">
 | 
			
		||||
                <i class="bx bx-chevron-right bx-sm ms-sm-n2"></i>
 | 
			
		||||
                <span class="align-middle d-sm-inline-block d-none">ویرایش اقلام</span>
 | 
			
		||||
              </a>
 | 
			
		||||
            {% else %}
 | 
			
		||||
              <span></span>
 | 
			
		||||
            {% endif %}
 | 
			
		||||
            
 | 
			
		||||
            {% if step_instance.status == 'completed' %}
 | 
			
		||||
              {% if next_step %}
 | 
			
		||||
                <a href="{% url 'processes:step_detail' instance.id next_step.id %}" 
 | 
			
		||||
                   class="btn btn-primary">
 | 
			
		||||
                  <span class="align-middle d-sm-inline-block d-none me-sm-1">بعدی</span>
 | 
			
		||||
                  <i class="bx bx-chevron-left bx-sm me-sm-n2"></i>
 | 
			
		||||
                </a>
 | 
			
		||||
              {% else %}
 | 
			
		||||
                <button class="btn btn-success" type="button">اتمام</button>
 | 
			
		||||
              {% endif %}
 | 
			
		||||
            {% else %}
 | 
			
		||||
              <button type="button" class="btn btn-primary" id="btnApproveQuote">
 | 
			
		||||
                تایید پیشفاکتور
 | 
			
		||||
              </button>
 | 
			
		||||
            {% endif %}
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
      
 | 
			
		||||
      
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
</div>
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 | 
			
		||||
{% block script %}
 | 
			
		||||
<script src="{% static 'assets/vendor/libs/bs-stepper/bs-stepper.js' %}"></script>
 | 
			
		||||
<script>
 | 
			
		||||
  document.addEventListener('DOMContentLoaded', function () {
 | 
			
		||||
    // Quote approval
 | 
			
		||||
    const btnApproveQuote = document.getElementById('btnApproveQuote');
 | 
			
		||||
    if (btnApproveQuote) {
 | 
			
		||||
      btnApproveQuote.addEventListener('click', function() {
 | 
			
		||||
        btnApproveQuote.disabled = true;
 | 
			
		||||
        fetch('{% url "invoices:approve_quote" instance.id step.id %}', {
 | 
			
		||||
          method: 'POST',
 | 
			
		||||
          headers: {
 | 
			
		||||
            'X-CSRFToken': document.querySelector('[name=csrfmiddlewaretoken]').value,
 | 
			
		||||
            'Content-Type': 'application/x-www-form-urlencoded',
 | 
			
		||||
          }
 | 
			
		||||
        }).then(r => r.json()).then(resp => {
 | 
			
		||||
          if (resp.success) {
 | 
			
		||||
            showToast('پیشفاکتور با موفقیت تایید شد', 'success');
 | 
			
		||||
            if (resp.redirect) {
 | 
			
		||||
              window.location.href = resp.redirect;
 | 
			
		||||
              return;
 | 
			
		||||
            }
 | 
			
		||||
            setTimeout(() => { window.location.reload(); }, 800);
 | 
			
		||||
          } else {
 | 
			
		||||
            showToast(resp.message || 'خطا در تایید پیشفاکتور', 'danger');
 | 
			
		||||
            btnApproveQuote.disabled = false;
 | 
			
		||||
          }
 | 
			
		||||
        }).catch(() => {
 | 
			
		||||
          showToast('خطا در ارتباط با سرور', 'danger');
 | 
			
		||||
          btnApproveQuote.disabled = false;
 | 
			
		||||
        });
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
</script>
 | 
			
		||||
{% endblock %}
 | 
			
		||||
							
								
								
									
										283
									
								
								invoices/templates/invoices/quote_print.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										283
									
								
								invoices/templates/invoices/quote_print.html
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,283 @@
 | 
			
		|||
<!DOCTYPE html>
 | 
			
		||||
<html lang="fa" dir="rtl">
 | 
			
		||||
<head>
 | 
			
		||||
    <meta charset="utf-8">
 | 
			
		||||
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
 | 
			
		||||
    <title>پیشفاکتور {{ quote.name }} - {{ instance.code }}</title>
 | 
			
		||||
    
 | 
			
		||||
    <!-- Bootstrap CSS -->
 | 
			
		||||
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet">
 | 
			
		||||
    
 | 
			
		||||
    <style>
 | 
			
		||||
        @page {
 | 
			
		||||
            size: A4;
 | 
			
		||||
            margin: 1cm;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        body {
 | 
			
		||||
            font-family: 'Vazirmatn', sans-serif;
 | 
			
		||||
            font-size: 14px;
 | 
			
		||||
            line-height: 1.6;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        @media print {
 | 
			
		||||
            body { print-color-adjust: exact; }
 | 
			
		||||
            .page-break { page-break-before: always; }
 | 
			
		||||
            .no-print { display: none !important; }
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        .invoice-header {
 | 
			
		||||
            border-bottom: 2px solid #696cff;
 | 
			
		||||
            padding-bottom: 20px;
 | 
			
		||||
            margin-bottom: 30px;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        .company-logo {
 | 
			
		||||
            font-size: 24px;
 | 
			
		||||
            font-weight: bold;
 | 
			
		||||
            color: #696cff;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        .invoice-title {
 | 
			
		||||
            font-size: 28px;
 | 
			
		||||
            font-weight: bold;
 | 
			
		||||
            color: #333;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        .info-table td {
 | 
			
		||||
            padding: 5px 10px;
 | 
			
		||||
            border: none;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        .items-table {
 | 
			
		||||
            border: 1px solid #dee2e6;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        .items-table th {
 | 
			
		||||
            background-color: #f8f9fa;
 | 
			
		||||
            border-bottom: 2px solid #dee2e6;
 | 
			
		||||
            font-weight: bold;
 | 
			
		||||
            text-align: center;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        .items-table td {
 | 
			
		||||
            border-bottom: 1px solid #dee2e6;
 | 
			
		||||
            text-align: center;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        .total-section {
 | 
			
		||||
            background-color: #f8f9fa;
 | 
			
		||||
            font-weight: bold;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        .signature-section {
 | 
			
		||||
            margin-top: 50px;
 | 
			
		||||
            border-top: 1px solid #dee2e6;
 | 
			
		||||
            padding-top: 30px;
 | 
			
		||||
        }
 | 
			
		||||
        
 | 
			
		||||
        .signature-box {
 | 
			
		||||
            border: 1px dashed #ccc;
 | 
			
		||||
            height: 80px;
 | 
			
		||||
            text-align: center;
 | 
			
		||||
            display: flex;
 | 
			
		||||
            align-items: center;
 | 
			
		||||
            justify-content: center;
 | 
			
		||||
            color: #666;
 | 
			
		||||
        }
 | 
			
		||||
    </style>
 | 
			
		||||
</head>
 | 
			
		||||
<body>
 | 
			
		||||
    <div class="container-fluid">
 | 
			
		||||
        <!-- Print Button (hidden in print) -->
 | 
			
		||||
        <div class="no-print mb-3">
 | 
			
		||||
            <button onclick="window.print()" class="btn btn-primary">
 | 
			
		||||
                <i class="bi bi-printer"></i> پرینت
 | 
			
		||||
            </button>
 | 
			
		||||
            <button onclick="window.close()" class="btn btn-secondary">
 | 
			
		||||
                بستن
 | 
			
		||||
            </button>
 | 
			
		||||
        </div>
 | 
			
		||||
        
 | 
			
		||||
        <!-- Invoice Header -->
 | 
			
		||||
        <div class="invoice-header">
 | 
			
		||||
            <div class="row">
 | 
			
		||||
                <div class="col-6">
 | 
			
		||||
                    <div class="company-logo mb-3">
 | 
			
		||||
                        شرکت آب منطقهای
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="company-info">
 | 
			
		||||
                        <p class="mb-1">دفتر مرکزی، خیابان اصلی</p>
 | 
			
		||||
                        <p class="mb-1">تهران، ایران</p>
 | 
			
		||||
                        <p class="mb-1">تلفن: ۰۲۱-۱۲۳۴۵۶۷۸</p>
 | 
			
		||||
                        <p class="mb-0">ایمیل: info@watercompany.ir</p>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="col-6 text-end">
 | 
			
		||||
                    <div class="invoice-title">پیشفاکتور</div>
 | 
			
		||||
                    <div class="mt-3">
 | 
			
		||||
                        <table class="info-table">
 | 
			
		||||
                            <tr>
 | 
			
		||||
                                <td><strong>شماره پیشفاکتور:</strong></td>
 | 
			
		||||
                                <td>{{ quote.name }}</td>
 | 
			
		||||
                            </tr>
 | 
			
		||||
                            <tr>
 | 
			
		||||
                                <td><strong>کد درخواست:</strong></td>
 | 
			
		||||
                                <td>{{ instance.code }}</td>
 | 
			
		||||
                            </tr>
 | 
			
		||||
                            <tr>
 | 
			
		||||
                                <td><strong>تاریخ صدور:</strong></td>
 | 
			
		||||
                                <td>{{ quote.created|date:"Y/m/d" }}</td>
 | 
			
		||||
                            </tr>
 | 
			
		||||
                            <tr>
 | 
			
		||||
                                <td><strong>معتبر تا:</strong></td>
 | 
			
		||||
                                <td>{{ quote.valid_until|date:"Y/m/d" }}</td>
 | 
			
		||||
                            </tr>
 | 
			
		||||
                        </table>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        
 | 
			
		||||
        <!-- Customer & Well Info -->
 | 
			
		||||
        <div class="row mb-4">
 | 
			
		||||
            <div class="col-6">
 | 
			
		||||
                <h6 class="fw-bold mb-3">مشخصات مشترک:</h6>
 | 
			
		||||
                <table class="info-table">
 | 
			
		||||
                    <tr>
 | 
			
		||||
                        <td><strong>نام و نام خانوادگی:</strong></td>
 | 
			
		||||
                        <td>{{ quote.customer.get_full_name }}</td>
 | 
			
		||||
                    </tr>
 | 
			
		||||
                    {% if instance.representative.profile %}
 | 
			
		||||
                    <tr>
 | 
			
		||||
                        <td><strong>کد ملی:</strong></td>
 | 
			
		||||
                        <td>{{ instance.representative.profile.national_code }}</td>
 | 
			
		||||
                    </tr>
 | 
			
		||||
                    <tr>
 | 
			
		||||
                        <td><strong>تلفن:</strong></td>
 | 
			
		||||
                        <td>{{ instance.representative.profile.phone_number_1|default:"-" }}</td>
 | 
			
		||||
                    </tr>
 | 
			
		||||
                    <tr>
 | 
			
		||||
                        <td><strong>آدرس:</strong></td>
 | 
			
		||||
                        <td>{{ instance.representative.profile.address|default:"آدرس نامشخص" }}</td>
 | 
			
		||||
                    </tr>
 | 
			
		||||
                    {% endif %}
 | 
			
		||||
                </table>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="col-6">
 | 
			
		||||
                <h6 class="fw-bold mb-3">مشخصات چاه:</h6>
 | 
			
		||||
                <table class="info-table">
 | 
			
		||||
                    <tr>
 | 
			
		||||
                        <td><strong>شماره اشتراک آب:</strong></td>
 | 
			
		||||
                        <td>{{ instance.well.water_subscription_number }}</td>
 | 
			
		||||
                    </tr>
 | 
			
		||||
                    <tr>
 | 
			
		||||
                        <td><strong>شماره اشتراک برق:</strong></td>
 | 
			
		||||
                        <td>{{ instance.well.electricity_subscription_number|default:"-" }}</td>
 | 
			
		||||
                    </tr>
 | 
			
		||||
                    <tr>
 | 
			
		||||
                        <td><strong>سریال کنتور:</strong></td>
 | 
			
		||||
                        <td>{{ instance.well.water_meter_serial_number|default:"-" }}</td>
 | 
			
		||||
                    </tr>
 | 
			
		||||
                    <tr>
 | 
			
		||||
                        <td><strong>قدرت چاه:</strong></td>
 | 
			
		||||
                        <td>{{ instance.well.well_power|default:"-" }}</td>
 | 
			
		||||
                    </tr>
 | 
			
		||||
                </table>
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        
 | 
			
		||||
        <!-- Items Table -->
 | 
			
		||||
        <div class="mb-4">
 | 
			
		||||
            <table class="table items-table">
 | 
			
		||||
                <thead>
 | 
			
		||||
                    <tr>
 | 
			
		||||
                        <th style="width: 5%">ردیف</th>
 | 
			
		||||
                        <th style="width: 30%">شرح کالا/خدمات</th>
 | 
			
		||||
                        <th style="width: 30%">توضیحات</th>
 | 
			
		||||
                        <th style="width: 10%">تعداد</th>
 | 
			
		||||
                        <th style="width: 12.5%">قیمت واحد (تومان)</th>
 | 
			
		||||
                        <th style="width: 12.5%">قیمت کل (تومان)</th>
 | 
			
		||||
                    </tr>
 | 
			
		||||
                </thead>
 | 
			
		||||
                <tbody>
 | 
			
		||||
                    {% for quote_item in quote.items.all %}
 | 
			
		||||
                    <tr>
 | 
			
		||||
                        <td>{{ forloop.counter }}</td>
 | 
			
		||||
                        <td class="text-start">{{ quote_item.item.name }}</td>
 | 
			
		||||
                        <td class="text-start">{{ quote_item.item.description|default:"-" }}</td>
 | 
			
		||||
                        <td>{{ quote_item.quantity }}</td>
 | 
			
		||||
                        <td>{{ quote_item.unit_price|floatformat:0 }}</td>
 | 
			
		||||
                        <td>{{ quote_item.total_price|floatformat:0 }}</td>
 | 
			
		||||
                    </tr>
 | 
			
		||||
                    {% endfor %}
 | 
			
		||||
                </tbody>
 | 
			
		||||
                <tfoot>
 | 
			
		||||
                    <tr class="total-section">
 | 
			
		||||
                        <td colspan="5" class="text-end"><strong>جمع کل:</strong></td>
 | 
			
		||||
                        <td><strong>{{ quote.total_amount|floatformat:0 }} تومان</strong></td>
 | 
			
		||||
                    </tr>
 | 
			
		||||
                    {% if quote.discount_amount > 0 %}
 | 
			
		||||
                    <tr class="total-section">
 | 
			
		||||
                        <td colspan="5" class="text-end"><strong>تخفیف:</strong></td>
 | 
			
		||||
                        <td><strong>{{ quote.discount_amount|floatformat:0 }} تومان</strong></td>
 | 
			
		||||
                    </tr>
 | 
			
		||||
                    {% endif %}
 | 
			
		||||
                    <tr class="total-section border-top border-2">
 | 
			
		||||
                        <td colspan="5" class="text-end"><strong>مبلغ نهایی:</strong></td>
 | 
			
		||||
                        <td><strong>{{ quote.final_amount|floatformat:0 }} تومان</strong></td>
 | 
			
		||||
                    </tr>
 | 
			
		||||
                </tfoot>
 | 
			
		||||
            </table>
 | 
			
		||||
        </div>
 | 
			
		||||
        
 | 
			
		||||
        <!-- Notes -->
 | 
			
		||||
        {% if quote.notes %}
 | 
			
		||||
        <div class="mb-4">
 | 
			
		||||
            <h6 class="fw-bold">یادداشت:</h6>
 | 
			
		||||
            <p>{{ quote.notes }}</p>
 | 
			
		||||
        </div>
 | 
			
		||||
        {% endif %}
 | 
			
		||||
        
 | 
			
		||||
        <!-- Additional Info -->
 | 
			
		||||
        <div class="mb-4">
 | 
			
		||||
            <p><strong>صادر کننده:</strong> {{ quote.created_by.get_full_name }}</p>
 | 
			
		||||
            <p class="text-muted">این پیشفاکتور تا تاریخ {{ quote.valid_until|date:"Y/m/d" }} معتبر است.</p>
 | 
			
		||||
        </div>
 | 
			
		||||
        
 | 
			
		||||
        <!-- Signature Section -->
 | 
			
		||||
        <div class="signature-section">
 | 
			
		||||
            <div class="row">
 | 
			
		||||
                <div class="col-6">
 | 
			
		||||
                    <div class="text-center">
 | 
			
		||||
                        <p class="mb-2"><strong>امضای مشترک</strong></p>
 | 
			
		||||
                        <div class="signature-box">
 | 
			
		||||
                            امضا و مهر
 | 
			
		||||
                        </div>
 | 
			
		||||
                        <p class="mt-2 small">تاریخ: ____/____/____</p>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="col-6">
 | 
			
		||||
                    <div class="text-center">
 | 
			
		||||
                        <p class="mb-2"><strong>امضای شرکت</strong></p>
 | 
			
		||||
                        <div class="signature-box">
 | 
			
		||||
                            امضا و مهر
 | 
			
		||||
                        </div>
 | 
			
		||||
                        <p class="mt-2 small">تاریخ: ____/____/____</p>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </div>
 | 
			
		||||
            </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        
 | 
			
		||||
        <!-- Footer -->
 | 
			
		||||
        <div class="text-center mt-4 small text-muted">
 | 
			
		||||
            این پیشفاکتور توسط سیستم مدیریت فرآیندها تولید شده است.
 | 
			
		||||
        </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    
 | 
			
		||||
    <script>
 | 
			
		||||
        // Auto print on load (optional)
 | 
			
		||||
        // window.onload = function() { window.print(); }
 | 
			
		||||
    </script>
 | 
			
		||||
</body>
 | 
			
		||||
</html>
 | 
			
		||||
							
								
								
									
										204
									
								
								invoices/templates/invoices/quote_step.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										204
									
								
								invoices/templates/invoices/quote_step.html
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,204 @@
 | 
			
		|||
{% extends '_base.html' %}
 | 
			
		||||
{% load static %}
 | 
			
		||||
{% load processes_tags %}
 | 
			
		||||
{% load humanize %}
 | 
			
		||||
 | 
			
		||||
{% block sidebar %}
 | 
			
		||||
    {% include 'sidebars/admin.html' %}
 | 
			
		||||
{% endblock sidebar %}
 | 
			
		||||
 | 
			
		||||
{% block navbar %}
 | 
			
		||||
    {% include 'navbars/admin.html' %}
 | 
			
		||||
{% endblock navbar %}
 | 
			
		||||
 | 
			
		||||
{% block title %}{{ step.name }} - درخواست {{ instance.code }}{% endblock %}
 | 
			
		||||
 | 
			
		||||
{% block style %}
 | 
			
		||||
<link rel="stylesheet" href="{% static 'assets/vendor/libs/bs-stepper/bs-stepper.css' %}">
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 | 
			
		||||
{% block content %}
 | 
			
		||||
{% include '_toasts.html' %}
 | 
			
		||||
<div class="container-xxl flex-grow-1 container-p-y">
 | 
			
		||||
  <div class="row">
 | 
			
		||||
    <div class="col-12 mb-4">
 | 
			
		||||
      <div class="d-flex align-items-center justify-content-between mb-3">
 | 
			
		||||
        <div>
 | 
			
		||||
          <h4 class="mb-1">{{ step.name }}: {{ instance.process.name }}</h4>
 | 
			
		||||
          <small class="text-muted d-block">
 | 
			
		||||
            اشتراک آب: {{ instance.well.water_subscription_number|default:"-" }}
 | 
			
		||||
            | نماینده: {{ instance.representative.profile.national_code|default:"-" }}
 | 
			
		||||
          </small>
 | 
			
		||||
        </div>
 | 
			
		||||
        <a href="{% url 'processes:request_list' %}" class="btn btn-outline-secondary">بازگشت</a>
 | 
			
		||||
      </div>
 | 
			
		||||
 | 
			
		||||
      <div class="bs-stepper wizard-vertical vertical mt-2">
 | 
			
		||||
        {% stepper_header instance step %}
 | 
			
		||||
        
 | 
			
		||||
        <div class="bs-stepper-content">
 | 
			
		||||
          <form>
 | 
			
		||||
            {% csrf_token %}
 | 
			
		||||
            <div class="content active dstepper-block">
 | 
			
		||||
              <div class="content-header mb-3">
 | 
			
		||||
                <h6 class="mb-0">{{ step.name }}</h6>
 | 
			
		||||
                <small>{{ step.description|default:' ' }}</small>
 | 
			
		||||
              </div>
 | 
			
		||||
              
 | 
			
		||||
              <div class="row g-3">
 | 
			
		||||
                {% if existing_quote %}
 | 
			
		||||
                <div class="col-12 mb-3">
 | 
			
		||||
                  <div class="alert alert-info">
 | 
			
		||||
                    <h6>پیشفاکتور موجود</h6>
 | 
			
		||||
                    <span class="mb-1">نام: {{ existing_quote.name }} | </span>
 | 
			
		||||
                    <span class="mb-1">مبلغ کل: {{ existing_quote.final_amount|floatformat:0|intcomma:False }} تومان | </span>
 | 
			
		||||
                    <span class="mb-0">وضعیت: {{ existing_quote.get_status_display_with_color|safe }}</span>
 | 
			
		||||
                  </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                {% endif %}
 | 
			
		||||
                
 | 
			
		||||
                <div class="col-12">
 | 
			
		||||
                  <div class="table-responsive">
 | 
			
		||||
                    <table class="table table-sm align-middle">
 | 
			
		||||
                      <thead>
 | 
			
		||||
                        <tr>
 | 
			
		||||
                          <th style="width:40px"></th>
 | 
			
		||||
                          <th>آیتم</th>
 | 
			
		||||
                          <th>قیمت واحد</th>
 | 
			
		||||
                          <th style="width:140px">تعداد</th>
 | 
			
		||||
                        </tr>
 | 
			
		||||
                      </thead>
 | 
			
		||||
                      <tbody>
 | 
			
		||||
                        {% for item in items %}
 | 
			
		||||
                        {% with selected_qty=existing_quote_items|get_item:item.id %}
 | 
			
		||||
                        <tr>
 | 
			
		||||
                          <td>
 | 
			
		||||
                            <input class="form-check-input quote-item-check" type="checkbox"
 | 
			
		||||
                                   data-item-id="{{ item.id }}"
 | 
			
		||||
                                   data-is-default="{% if item.is_default_in_quotes %}1{% else %}0{% endif %}"
 | 
			
		||||
                                   {% if selected_qty %}checked{% elif item.is_default_in_quotes %}checked{% endif %}
 | 
			
		||||
                                   {% if item.is_default_in_quotes %}disabled title="آیتم پیشفرض است و قابل حذف نیست"{% endif %}>
 | 
			
		||||
                          </td>
 | 
			
		||||
                          <td>
 | 
			
		||||
                            <div class="d-flex flex-column">
 | 
			
		||||
                              <span class="fw-semibold">{{ item.name }}
 | 
			
		||||
                                {% if item.is_default_in_quotes %}
 | 
			
		||||
                                <span class="badge bg-label-primary me-2">پیشفرض</span>
 | 
			
		||||
                              {% endif %}
 | 
			
		||||
                              </span>
 | 
			
		||||
                              
 | 
			
		||||
                              {% if item.description %}<small class="text-muted">{{ item.description }}</small>{% endif %}
 | 
			
		||||
                            </div>
 | 
			
		||||
                          </td>
 | 
			
		||||
                          <td>{{ item.unit_price|floatformat:0|intcomma:False }} تومان</td>
 | 
			
		||||
                          <td>
 | 
			
		||||
                            <input type="number" class="form-control form-control-sm quote-item-qty" min="1" 
 | 
			
		||||
                                   data-item-id="{{ item.id }}" 
 | 
			
		||||
                                   value="{% if selected_qty %}{{ selected_qty }}{% else %}{{ item.default_quantity }}{% endif %}">
 | 
			
		||||
                          </td>
 | 
			
		||||
                        </tr>
 | 
			
		||||
                        {% endwith %}
 | 
			
		||||
                        {% endfor %}
 | 
			
		||||
                      </tbody>
 | 
			
		||||
                    </table>
 | 
			
		||||
                  </div>
 | 
			
		||||
                  
 | 
			
		||||
                  
 | 
			
		||||
                </div>
 | 
			
		||||
                
 | 
			
		||||
                <div class="col-12 d-flex justify-content-between">
 | 
			
		||||
                  {% if previous_step %}
 | 
			
		||||
                    <a href="{% url 'processes:step_detail' instance.id previous_step.id %}" 
 | 
			
		||||
                       class="btn btn-label-secondary">
 | 
			
		||||
                      <i class="bx bx-chevron-left bx-sm ms-sm-n2"></i>
 | 
			
		||||
                      <span class="align-middle d-sm-inline-block d-none">قبلی</span>
 | 
			
		||||
                    </a>
 | 
			
		||||
                  {% else %}
 | 
			
		||||
                    <span></span>
 | 
			
		||||
                  {% endif %}
 | 
			
		||||
                  
 | 
			
		||||
                  
 | 
			
		||||
                  {% if step_instance.status == 'completed' %}
 | 
			
		||||
                    {% if next_step %}
 | 
			
		||||
                    <div class="d-flex justify-content-end mt-3">
 | 
			
		||||
                      <button type="button" class="btn btn-primary" id="btnCreateQuote">
 | 
			
		||||
                        
 | 
			
		||||
                        {% if existing_quote %}بروزرسانی پیشفاکتور{% else %}ثبت پیشفاکتور{% endif %}
 | 
			
		||||
                        و بعدی
 | 
			
		||||
                        <i class="bx bx-chevron-left bx-sm me-sm-n2"></i>
 | 
			
		||||
                      </button>
 | 
			
		||||
                    </div>
 | 
			
		||||
 | 
			
		||||
                    {% else %}
 | 
			
		||||
                      <button class="btn btn-success" type="button">اتمام</button>
 | 
			
		||||
                    {% endif %}
 | 
			
		||||
                  {% else %}
 | 
			
		||||
                  <button type="button" class="btn btn-primary" id="btnCreateQuote">
 | 
			
		||||
                        
 | 
			
		||||
                    {% if existing_quote %}بروزرسانی پیشفاکتور{% else %}ثبت پیشفاکتور{% endif %}
 | 
			
		||||
                    و بعدی
 | 
			
		||||
                    <i class="bx bx-chevron-left bx-sm me-sm-n2"></i>
 | 
			
		||||
                  </button>
 | 
			
		||||
                  {% endif %}
 | 
			
		||||
                </div>
 | 
			
		||||
              </div>
 | 
			
		||||
            </div>
 | 
			
		||||
          </form>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
</div>
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 | 
			
		||||
{% block script %}
 | 
			
		||||
<script src="{% static 'assets/vendor/libs/bs-stepper/bs-stepper.js' %}"></script>
 | 
			
		||||
<script>
 | 
			
		||||
  document.addEventListener('DOMContentLoaded', function () {
 | 
			
		||||
    // Quote creation
 | 
			
		||||
    const btnCreateQuote = document.getElementById('btnCreateQuote');
 | 
			
		||||
    if (btnCreateQuote) {
 | 
			
		||||
      btnCreateQuote.addEventListener('click', function() {
 | 
			
		||||
        const selections = [];
 | 
			
		||||
        document.querySelectorAll('.quote-item-check').forEach(chk => {
 | 
			
		||||
          if (chk.checked) {
 | 
			
		||||
            const id = chk.getAttribute('data-item-id');
 | 
			
		||||
            const isDefault = chk.getAttribute('data-is-default') === '1';
 | 
			
		||||
            const qtyInput = document.querySelector(`.quote-item-qty[data-item-id="${id}"]`);
 | 
			
		||||
            const qty = qtyInput ? parseInt(qtyInput.value || '1', 10) : 1;
 | 
			
		||||
            selections.push({ id, qty, isDefault });
 | 
			
		||||
          }
 | 
			
		||||
        });
 | 
			
		||||
        if (selections.length === 0) {
 | 
			
		||||
          showToast('حداقل یک آیتم را انتخاب کنید', 'danger');
 | 
			
		||||
          return;
 | 
			
		||||
        }
 | 
			
		||||
        const payload = new FormData();
 | 
			
		||||
        payload.append('csrfmiddlewaretoken', document.querySelector('input[name=csrfmiddlewaretoken]').value);
 | 
			
		||||
        payload.append('items', JSON.stringify(selections));
 | 
			
		||||
        
 | 
			
		||||
        btnCreateQuote.disabled = true;
 | 
			
		||||
        fetch('{% url "invoices:create_quote" instance.id step.id %}', {
 | 
			
		||||
          method: 'POST',
 | 
			
		||||
          body: payload
 | 
			
		||||
        }).then(r => r.json()).then(resp => {
 | 
			
		||||
          if (resp.success) {
 | 
			
		||||
            showToast('پیشفاکتور با موفقیت ثبت شد', 'success');
 | 
			
		||||
            if (resp.redirect) {
 | 
			
		||||
              window.location.href = resp.redirect;
 | 
			
		||||
            } else {
 | 
			
		||||
              setTimeout(() => { window.location.reload(); }, 800);
 | 
			
		||||
            }
 | 
			
		||||
          } else {
 | 
			
		||||
            showToast(resp.message || 'خطا در ثبت پیشفاکتور', 'danger');
 | 
			
		||||
            btnCreateQuote.disabled = false;
 | 
			
		||||
          }
 | 
			
		||||
        }).catch(() => {
 | 
			
		||||
          showToast('خطا در ارتباط با سرور', 'danger');
 | 
			
		||||
          btnCreateQuote.disabled = false;
 | 
			
		||||
        });
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
</script>
 | 
			
		||||
{% endblock %}
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue