Add confirmation and summary
This commit is contained in:
		
							parent
							
								
									9b3973805e
								
							
						
					
					
						commit
						35799b7754
					
				
					 25 changed files with 1419 additions and 265 deletions
				
			
		| 
						 | 
				
			
			@ -50,7 +50,9 @@
 | 
			
		|||
      <div class="card border">
 | 
			
		||||
        <div class="card-header d-flex justify-content-between align-items-center">
 | 
			
		||||
          <h5 class="mb-0">فاکتور نهایی</h5>
 | 
			
		||||
          <button type="button" class="btn btn-sm btn-outline-primary" onclick="openSpecialChargeModal()"><i class="bx bx-plus"></i> افزودن هزینه تعمیر/تعویض</button>
 | 
			
		||||
          {% if is_manager %}
 | 
			
		||||
            <button type="button" class="btn btn-sm btn-outline-primary" onclick="openSpecialChargeModal()"><i class="bx bx-plus"></i> افزودن هزینه تعمیر/تعویض</button>
 | 
			
		||||
          {% endif %}
 | 
			
		||||
        </div>
 | 
			
		||||
 | 
			
		||||
        <div class="card-body">
 | 
			
		||||
| 
						 | 
				
			
			@ -127,7 +129,9 @@
 | 
			
		|||
                  <td class="text-end">{{ si.unit_price|floatformat:0|intcomma:False }}</td>
 | 
			
		||||
                  <td class="text-end">
 | 
			
		||||
                    {{ si.total_price|floatformat:0|intcomma:False }}
 | 
			
		||||
                    <button type="button" class="btn btn-sm btn-outline-danger ms-2" onclick="deleteSpecial('{{ si.id }}')" title="حذف"><i class="bx bx-trash"></i></button>
 | 
			
		||||
                    {% if is_manager %}
 | 
			
		||||
                      <button type="button" class="btn btn-sm btn-outline-danger ms-2" onclick="deleteSpecial('{{ si.id }}')" title="حذف"><i class="bx bx-trash"></i></button>
 | 
			
		||||
                    {% endif %}
 | 
			
		||||
                  </td>
 | 
			
		||||
                </tr>
 | 
			
		||||
                {% endfor %}
 | 
			
		||||
| 
						 | 
				
			
			@ -164,7 +168,11 @@
 | 
			
		|||
            <span></span>
 | 
			
		||||
          {% endif %}
 | 
			
		||||
          {% if next_step %}
 | 
			
		||||
            <button type="button" class="btn btn-primary" id="btnApproveFinalInvoice">تایید و ادامه</button>
 | 
			
		||||
            {% if is_manager %}
 | 
			
		||||
              <button type="button" class="btn btn-primary" id="btnApproveFinalInvoice">تایید و ادامه</button>
 | 
			
		||||
            {% else %}
 | 
			
		||||
            <a href="{% url 'processes:step_detail' instance.id next_step.id %}" class="btn btn-primary">بعدی</a>
 | 
			
		||||
            {% endif %}
 | 
			
		||||
          {% endif %}
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,6 +2,7 @@
 | 
			
		|||
{% load static %}
 | 
			
		||||
{% load processes_tags %}
 | 
			
		||||
{% load common_tags %}
 | 
			
		||||
{% load accounts_tags %}
 | 
			
		||||
{% load humanize %}
 | 
			
		||||
 | 
			
		||||
{% block sidebar %}
 | 
			
		||||
| 
						 | 
				
			
			@ -46,6 +47,7 @@
 | 
			
		|||
        <div class="bs-stepper-content">
 | 
			
		||||
 | 
			
		||||
      <div class="row g-3">
 | 
			
		||||
        {% if is_broker %}
 | 
			
		||||
        <div class="col-12 col-lg-5">
 | 
			
		||||
          <div class="card border h-100">
 | 
			
		||||
            <div class="card-header"><h5 class="mb-0">ثبت تراکنش تسویه</h5></div>
 | 
			
		||||
| 
						 | 
				
			
			@ -78,11 +80,11 @@
 | 
			
		|||
                  </select>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="mb-3">
 | 
			
		||||
                  <label class="form-label">شماره مرجع</label>
 | 
			
		||||
                  <label class="form-label">شماره مرجع/چک</label>
 | 
			
		||||
                  <input type="text" class="form-control" name="reference_number" id="id_reference_number" required>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="mb-3">
 | 
			
		||||
                  <label class="form-label">تصویر فیش</label>
 | 
			
		||||
                  <label class="form-label">تصویر فیش/چک</label>
 | 
			
		||||
                  <input type="file" class="form-control" name="receipt_image" id="id_receipt_image" accept="image/*" required>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="d-flex justify-content-end">
 | 
			
		||||
| 
						 | 
				
			
			@ -92,23 +94,39 @@
 | 
			
		|||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="col-12 col-lg-7">
 | 
			
		||||
        {% endif %}
 | 
			
		||||
        <div class="col-12 {% if is_broker %}col-lg-7{% else %}col-lg-12{% endif %}">
 | 
			
		||||
          <div class="card mb-3 border">
 | 
			
		||||
            <div class="card-header"><h5 class="mb-0">وضعیت فاکتور</h5></div>
 | 
			
		||||
            <div class="card-header d-flex justify-content-between">
 | 
			
		||||
                <h5 class="mb-0">وضعیت فاکتور</h5>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="card-body">
 | 
			
		||||
              <div class="row g-3">
 | 
			
		||||
                <div class="col-6">
 | 
			
		||||
                  <div class="border rounded p-3">
 | 
			
		||||
                <div class="col-6 col-md-4">
 | 
			
		||||
                  <div class="border rounded p-3 h-100">
 | 
			
		||||
                    <div class="small text-muted">مبلغ نهایی</div>
 | 
			
		||||
                    <div class="h5 mt-1">{{ invoice.final_amount|floatformat:0|intcomma:False }} تومان</div>
 | 
			
		||||
                  </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="col-6">
 | 
			
		||||
                  <div class="border rounded p-3">
 | 
			
		||||
                <div class="col-6 col-md-4">
 | 
			
		||||
                  <div class="border rounded p-3 h-100">
 | 
			
		||||
                    <div class="small text-muted">پرداختیها</div>
 | 
			
		||||
                    <div class="h5 mt-1 text-success">{{ invoice.paid_amount|floatformat:0|intcomma:False }} تومان</div>
 | 
			
		||||
                  </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="col-6 col-md-4">
 | 
			
		||||
                  <div class="border rounded p-3 h-100">
 | 
			
		||||
                    <div class="small text-muted">مانده</div>
 | 
			
		||||
                    <div class="h5 mt-1 {% if invoice.remaining_amount <= 0 %}text-success{% else %}text-danger{% endif %}">{{ invoice.remaining_amount|floatformat:0|intcomma:False }} تومان</div>
 | 
			
		||||
                  </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="col-6 d-flex align-items-center">
 | 
			
		||||
                  {% if invoice.remaining_amount <= 0 %}
 | 
			
		||||
                    <span class="badge bg-success">تسویه کامل</span>
 | 
			
		||||
                  {% else %}
 | 
			
		||||
                    <span class="badge bg-warning text-dark">باقیمانده دارد</span>
 | 
			
		||||
                  {% endif %}
 | 
			
		||||
                </div>
 | 
			
		||||
              </div>
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
| 
						 | 
				
			
			@ -123,8 +141,8 @@
 | 
			
		|||
                    <th>مبلغ</th>
 | 
			
		||||
                    <th>تاریخ</th>
 | 
			
		||||
                    <th>روش</th>
 | 
			
		||||
                    <th>شماره مرجع</th>
 | 
			
		||||
                    <th style="width:150px">عملیات</th>
 | 
			
		||||
                    <th class="text-nowrap">شماره مرجع/چک</th>
 | 
			
		||||
                    <th>عملیات</th>
 | 
			
		||||
                  </tr>
 | 
			
		||||
                </thead>
 | 
			
		||||
                <tbody>
 | 
			
		||||
| 
						 | 
				
			
			@ -132,7 +150,7 @@
 | 
			
		|||
                  <tr>
 | 
			
		||||
                    <td>{% if p.direction == 'in' %}<span class="badge bg-success">دریافتی{% else %}<span class="badge bg-warning text-dark">پرداختی{% endif %}</span></td>
 | 
			
		||||
                    <td>{{ p.amount|floatformat:0|intcomma:False }} تومان</td>
 | 
			
		||||
                    <td>{{ p.payment_date|to_jalali }}</td>
 | 
			
		||||
                    <td>{{ p.payment_date|date:'Y/m/d' }}</td>
 | 
			
		||||
                    <td>{{ p.get_payment_method_display }}</td>
 | 
			
		||||
                    <td>{{ p.reference_number|default:'-' }}</td>
 | 
			
		||||
                    <td>
 | 
			
		||||
| 
						 | 
				
			
			@ -142,7 +160,9 @@
 | 
			
		|||
                            <i class="bx bx-show"></i>
 | 
			
		||||
                          </a>
 | 
			
		||||
                        {% endif %}
 | 
			
		||||
                        <button type="button" class="btn btn-sm btn-outline-danger" onclick="deleteFinalPayment({{ p.id }})" title="حذف" aria-label="حذف"><i class="bx bx-trash"></i></button>
 | 
			
		||||
                        {% if is_broker %}
 | 
			
		||||
                          <button type="button" class="btn btn-sm btn-outline-danger" onclick="openDeleteModal('{{ p.id }}')" title="حذف" aria-label="حذف"><i class="bx bx-trash"></i></button>
 | 
			
		||||
                        {% endif %}
 | 
			
		||||
                      </div>
 | 
			
		||||
                    </td>
 | 
			
		||||
                  </tr>
 | 
			
		||||
| 
						 | 
				
			
			@ -152,20 +172,141 @@
 | 
			
		|||
                </tbody>
 | 
			
		||||
              </table>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="card-footer d-flex justify-content-between">
 | 
			
		||||
              {% if previous_step %}
 | 
			
		||||
                <a href="{% url 'processes:step_detail' instance.id previous_step.id %}" class="btn btn-label-secondary">قبلی</a>
 | 
			
		||||
              {% else %}
 | 
			
		||||
                <span></span>
 | 
			
		||||
              {% endif %}
 | 
			
		||||
              <button type="button" id="btnApproveFinalSettlement" class="btn btn-primary">تایید و ادامه</button>
 | 
			
		||||
            </div>
 | 
			
		||||
            
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
      {% if approver_statuses %}
 | 
			
		||||
      <div class="card border mt-2">
 | 
			
		||||
        <div class="card-header d-flex justify-content-between align-items-center">
 | 
			
		||||
          <h6 class="mb-0">وضعیت تاییدها</h6>
 | 
			
		||||
          {% if can_approve_reject %}
 | 
			
		||||
          <div class="d-flex gap-2">
 | 
			
		||||
            <button type="button" class="btn btn-success btn-sm" data-bs-toggle="modal" data-bs-target="#approveFinalSettleModal" {% if step_instance.status == 'completed' %}disabled{% endif %}>تایید</button>
 | 
			
		||||
            <button type="button" class="btn btn-danger btn-sm" data-bs-toggle="modal" data-bs-target="#rejectFinalSettleModal">رد</button>
 | 
			
		||||
          </div>
 | 
			
		||||
          {% endif %}
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="card-body py-3">
 | 
			
		||||
          <div class="row g-2">
 | 
			
		||||
            {% for st in approver_statuses %}
 | 
			
		||||
            <div class="col-12 col-md-6 col-lg-4">
 | 
			
		||||
              <div class="d-flex flex-column border rounded px-2 py-1">
 | 
			
		||||
                <div class="d-flex align-items-center gap-2">
 | 
			
		||||
                  <span class="badge bg-light text-dark">{{ st.role.name }}</span>
 | 
			
		||||
                  {% if st.status == 'approved' %}
 | 
			
		||||
                    <span class="badge bg-success">تایید شد</span>
 | 
			
		||||
                  {% elif st.status == 'rejected' %}
 | 
			
		||||
                    <span class="badge bg-danger">رد شد</span>
 | 
			
		||||
                  {% else %}
 | 
			
		||||
                    <span class="badge bg-warning text-dark">در انتظار</span>
 | 
			
		||||
                  {% endif %}
 | 
			
		||||
                </div>
 | 
			
		||||
                {% if st.status == 'rejected' and st.reason %}
 | 
			
		||||
                  <div class="mt-1 small text-danger">علت: {{ st.reason }}</div>
 | 
			
		||||
                {% endif %}
 | 
			
		||||
              </div>
 | 
			
		||||
            </div>
 | 
			
		||||
            {% endfor %}
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
      {% endif %}
 | 
			
		||||
      <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">قبلی</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">بعدی</a>
 | 
			
		||||
          {% else %}
 | 
			
		||||
            <a href="{% url 'processes:request_list' %}" class="btn btn-success">اتمام</a>
 | 
			
		||||
          {% endif %}
 | 
			
		||||
        {% endif %}
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<!-- Delete Confirmation Modal (final settlement payments) -->
 | 
			
		||||
<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 Final Settlement Modal -->
 | 
			
		||||
<div class="modal fade" id="approveFinalSettleModal" tabindex="-1" aria-hidden="true">
 | 
			
		||||
  <div class="modal-dialog">
 | 
			
		||||
    <div class="modal-content">
 | 
			
		||||
      <form method="post">
 | 
			
		||||
        {% csrf_token %}
 | 
			
		||||
        <input type="hidden" name="action" value="approve">
 | 
			
		||||
        <div class="modal-header">
 | 
			
		||||
          <h5 class="modal-title">تایید تسویه نهایی</h5>
 | 
			
		||||
          <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="modal-body">
 | 
			
		||||
          {% if invoice.remaining_amount != 0 %}
 | 
			
		||||
            <div class="alert alert-warning" role="alert">
 | 
			
		||||
              مانده فاکتور صفر نیست: <strong>{{ invoice.remaining_amount|floatformat:0|intcomma:False }} تومان</strong><br>
 | 
			
		||||
              تا صفر نشود امکان تایید نیست.
 | 
			
		||||
            </div>
 | 
			
		||||
          {% else %}
 | 
			
		||||
            آیا از تایید این مرحله اطمینان دارید؟
 | 
			
		||||
          {% endif %}
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="modal-footer">
 | 
			
		||||
          <button type="button" class="btn btn-label-secondary" data-bs-dismiss="modal">انصراف</button>
 | 
			
		||||
          <button type="submit" class="btn btn-success" {% if invoice.remaining_amount != 0 %}disabled{% endif %}>تایید</button>
 | 
			
		||||
        </div>
 | 
			
		||||
      </form>
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
<!-- Reject Final Settlement Modal -->
 | 
			
		||||
<div class="modal fade" id="rejectFinalSettleModal" tabindex="-1" aria-hidden="true">
 | 
			
		||||
  <div class="modal-dialog">
 | 
			
		||||
    <div class="modal-content">
 | 
			
		||||
      <form method="post">
 | 
			
		||||
        {% csrf_token %}
 | 
			
		||||
        <input type="hidden" name="action" value="reject">
 | 
			
		||||
        <div class="modal-header">
 | 
			
		||||
          <h5 class="modal-title">رد تسویه نهایی</h5>
 | 
			
		||||
          <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="modal-body">
 | 
			
		||||
          <div class="mb-2">
 | 
			
		||||
            <label class="form-label">علت رد</label>
 | 
			
		||||
            <textarea class="form-control" name="reject_reason" rows="3" required></textarea>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="modal-footer">
 | 
			
		||||
          <button type="button" class="btn btn-label-secondary" data-bs-dismiss="modal">انصراف</button>
 | 
			
		||||
          <button type="submit" class="btn btn-danger">ثبت رد</button>
 | 
			
		||||
        </div>
 | 
			
		||||
      </form>
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 | 
			
		||||
{% block script %}
 | 
			
		||||
| 
						 | 
				
			
			@ -191,8 +332,11 @@
 | 
			
		|||
    if (g) { fd.set('payment_date', g); }
 | 
			
		||||
    return fd;
 | 
			
		||||
  }
 | 
			
		||||
  document.getElementById('btnAddFinalPayment').addEventListener('click', function(){
 | 
			
		||||
    const fd = buildForm();
 | 
			
		||||
  (function(){
 | 
			
		||||
    const btn = document.getElementById('btnAddFinalPayment');
 | 
			
		||||
    if (!btn) return;
 | 
			
		||||
    btn.addEventListener('click', function(){
 | 
			
		||||
      const fd = buildForm();
 | 
			
		||||
    // Frontend validation
 | 
			
		||||
    const amount = document.getElementById('id_amount').value.trim();
 | 
			
		||||
    const payDate = document.getElementById('id_payment_date').value.trim();
 | 
			
		||||
| 
						 | 
				
			
			@ -204,7 +348,7 @@
 | 
			
		|||
      showToast('همه فیلدها الزامی است', 'danger');
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
    fetch('{% url "invoices:add_final_payment" instance.id step.id %}', { method:'POST', body: fd })
 | 
			
		||||
      fetch('{% url "invoices:add_final_payment" instance.id step.id %}', { method:'POST', body: fd })
 | 
			
		||||
      .then(r=>r.json()).then(resp=>{
 | 
			
		||||
        if (resp.success) {
 | 
			
		||||
          showToast('تراکنش ثبت شد', 'success');
 | 
			
		||||
| 
						 | 
				
			
			@ -213,12 +357,20 @@
 | 
			
		|||
          showToast(resp.message || 'خطا در ثبت تراکنش', 'danger');
 | 
			
		||||
        }
 | 
			
		||||
      }).catch(()=> showToast('خطا در ارتباط با سرور', 'danger'));
 | 
			
		||||
  });
 | 
			
		||||
    });
 | 
			
		||||
  })();
 | 
			
		||||
 | 
			
		||||
  function deleteFinalPayment(id){
 | 
			
		||||
  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_final_payment" instance.id step.id 0 %}`.replace('/0/', `/${id}/`), { method:'POST', body: fd })
 | 
			
		||||
    fetch(`{% url "invoices:delete_final_payment" instance.id step.id 0 %}`.replace('/0/', `/${deleteTargetId}/`), { method:'POST', body: fd })
 | 
			
		||||
      .then(r=>r.json()).then(resp=>{
 | 
			
		||||
        if (resp.success) {
 | 
			
		||||
          showToast('حذف شد', 'success');
 | 
			
		||||
| 
						 | 
				
			
			@ -229,20 +381,7 @@
 | 
			
		|||
      }).catch(()=> showToast('خطا در ارتباط با سرور', 'danger'));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  document.getElementById('btnApproveFinalSettlement').addEventListener('click', function(){
 | 
			
		||||
    const fd = new FormData();
 | 
			
		||||
    fd.append('csrfmiddlewaretoken', document.querySelector('input[name=csrfmiddlewaretoken]').value);
 | 
			
		||||
    fetch('{% url "invoices:approve_final_settlement" instance.id step.id %}', { method:'POST', body: fd })
 | 
			
		||||
      .then(r=>r.json()).then(resp=>{
 | 
			
		||||
        if (resp.success) {
 | 
			
		||||
          showToast(resp.message || 'تایید شد', 'success');
 | 
			
		||||
          if (resp.redirect) setTimeout(()=>{ window.location.href = resp.redirect; }, 600);
 | 
			
		||||
        } else {
 | 
			
		||||
          showToast(resp.message || 'خطا در تایید', 'danger');
 | 
			
		||||
        }
 | 
			
		||||
      }).catch(()=> showToast('خطا در ارتباط با سرور', 'danger'));
 | 
			
		||||
  });
 | 
			
		||||
  // Legacy approve button removed; using modal forms below
 | 
			
		||||
</script>
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,7 @@
 | 
			
		|||
{% extends '_base.html' %}
 | 
			
		||||
{% load static %}
 | 
			
		||||
{% load processes_tags %}
 | 
			
		||||
{% load accounts_tags %}
 | 
			
		||||
{% load humanize %}
 | 
			
		||||
 | 
			
		||||
{% block sidebar %}
 | 
			
		||||
| 
						 | 
				
			
			@ -55,14 +56,15 @@
 | 
			
		|||
            <div class="content active dstepper-block">
 | 
			
		||||
              <div class="content-header mb-3">
 | 
			
		||||
                <h6 class="mb-0">{{ step.name }}</h6>
 | 
			
		||||
                <small>ثبت فیشهای واریزی برای پیشفاکتور</small>
 | 
			
		||||
                <small>ثبت فیشها/چکهای واریزی برای پیشفاکتور</small>
 | 
			
		||||
              </div>
 | 
			
		||||
              
 | 
			
		||||
              <div class="row g-3">
 | 
			
		||||
                {% if can_manage_payments %}
 | 
			
		||||
                <div class="col-12 col-lg-5">
 | 
			
		||||
                  <div class="card h-100 border">
 | 
			
		||||
                    <div class="card-header">
 | 
			
		||||
                      <h5 class="card-title mb-0">ثبت فیش جدید</h5>
 | 
			
		||||
                      <h5 class="card-title mb-0">ثبت فیش/چک جدید</h5>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="card-body">
 | 
			
		||||
                      <div class="mb-3">
 | 
			
		||||
| 
						 | 
				
			
			@ -84,11 +86,11 @@
 | 
			
		|||
                        </select>
 | 
			
		||||
                      </div>
 | 
			
		||||
                      <div class="mb-3">
 | 
			
		||||
                        <label class="form-label">شماره مرجع</label>
 | 
			
		||||
                        <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>
 | 
			
		||||
                        <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">
 | 
			
		||||
| 
						 | 
				
			
			@ -96,16 +98,16 @@
 | 
			
		|||
                        <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>
 | 
			
		||||
                        <button type="button" id="btnAddPayment" class="btn btn-primary">افزودن فیش/چک</button>
 | 
			
		||||
                      </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                  </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="col-12 col-lg-7">
 | 
			
		||||
                {% endif %}
 | 
			
		||||
                <div class="col-12 {% if can_manage_payments %}col-lg-7{% else %}col-lg-12{% endif %}">
 | 
			
		||||
                  <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>
 | 
			
		||||
                        <h5 class="card-title mb-0">وضعیت پیشفاکتور</h5>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="card-body">
 | 
			
		||||
                      <div class="row g-3">
 | 
			
		||||
| 
						 | 
				
			
			@ -139,8 +141,10 @@
 | 
			
		|||
                  </div>
 | 
			
		||||
 | 
			
		||||
                  <div class="card border">
 | 
			
		||||
                    <div class="card-header">
 | 
			
		||||
                      <h5 class="card-title mb-0">فیشهای ثبت شده</h5>
 | 
			
		||||
                    <div class="card-header d-flex justify-content-between align-items-center">
 | 
			
		||||
                      <div>
 | 
			
		||||
                        <h5 class="card-title mb-0">فیشها/چکهای ثبت شده</h5>
 | 
			
		||||
                      </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="table-responsive">
 | 
			
		||||
                      <table class="table table-striped mb-0">
 | 
			
		||||
| 
						 | 
				
			
			@ -149,9 +153,8 @@
 | 
			
		|||
                            <th>مبلغ</th>
 | 
			
		||||
                            <th>تاریخ</th>
 | 
			
		||||
                            <th>روش</th>
 | 
			
		||||
                            <th>شماره مرجع</th>
 | 
			
		||||
                            <th>تصویر</th>
 | 
			
		||||
                            <th style="width:120px">عملیات</th>
 | 
			
		||||
                            <th>شماره مرجع/چک</th>
 | 
			
		||||
                            <th>عملیات</th>
 | 
			
		||||
                          </tr>
 | 
			
		||||
                        </thead>
 | 
			
		||||
                        <tbody>
 | 
			
		||||
| 
						 | 
				
			
			@ -162,28 +165,23 @@
 | 
			
		|||
                            <td>{{ p.get_payment_method_display }}</td>
 | 
			
		||||
                            <td>{{ p.reference_number|default:'-' }}</td>
 | 
			
		||||
                            <td>
 | 
			
		||||
                              {% if p.receipt_image %}
 | 
			
		||||
                              <div class="btn-group">
 | 
			
		||||
                                {% 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="حذف">
 | 
			
		||||
                                {% endif %}
 | 
			
		||||
                                {% if can_manage_payments %}
 | 
			
		||||
                                <button type="button" class="btn btn-sm btn-outline-danger" onclick="openDeleteModal('{{ p.id }}')" title="حذف" aria-label="حذف">
 | 
			
		||||
                                  <i class="bx bx-trash"></i>
 | 
			
		||||
                                </button>
 | 
			
		||||
                                {% endif %}
 | 
			
		||||
                              </div>
 | 
			
		||||
                            </td>
 | 
			
		||||
                          </tr>
 | 
			
		||||
                          {% empty %}
 | 
			
		||||
                          <tr>
 | 
			
		||||
                            <td colspan="6" class="text-center text-muted">تا کنون فیشی ثبت نشده است</td>
 | 
			
		||||
                            <td colspan="6" class="text-center text-muted">تا کنون فیش/چکی ثبت نشده است</td>
 | 
			
		||||
                          </tr>
 | 
			
		||||
                          {% endfor %}
 | 
			
		||||
                        </tbody>
 | 
			
		||||
| 
						 | 
				
			
			@ -191,6 +189,42 @@
 | 
			
		|||
                    </div>
 | 
			
		||||
                  </div>
 | 
			
		||||
                </div>
 | 
			
		||||
                {% if approver_statuses %}
 | 
			
		||||
                  <div class="card border mt-2">
 | 
			
		||||
                    <div class="card-header d-flex justify-content-between align-items-center">
 | 
			
		||||
                      <h6 class="mb-0">وضعیت تاییدها</h6>
 | 
			
		||||
                      {% if can_approve_reject %}
 | 
			
		||||
                      <div class="d-flex gap-2">
 | 
			
		||||
                        <button type="button" class="btn btn-success btn-sm" data-bs-toggle="modal" data-bs-target="#approvePaymentsModal2" {% if step_instance.status == 'completed' %}disabled{% endif %}>تایید</button>
 | 
			
		||||
                        <button type="button" class="btn btn-danger btn-sm" data-bs-toggle="modal" data-bs-target="#rejectPaymentsModal">رد</button>
 | 
			
		||||
                      </div>
 | 
			
		||||
                      {% endif %}
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <div class="card-body py-3">
 | 
			
		||||
                      <div class="row g-2">
 | 
			
		||||
                        {% for st in approver_statuses %}
 | 
			
		||||
                        <div class="col-12 col-md-6 col-lg-4">
 | 
			
		||||
                          <div class="d-flex flex-column border rounded px-2 py-1">
 | 
			
		||||
                            <div class="d-flex align-items-center gap-2">
 | 
			
		||||
                              <span class="badge bg-light text-dark">{{ st.role.name }}</span>
 | 
			
		||||
                              {% if st.status == 'approved' %}
 | 
			
		||||
                                <span class="badge bg-success">تایید شد</span>
 | 
			
		||||
                              {% elif st.status == 'rejected' %}
 | 
			
		||||
                                <span class="badge bg-danger">رد شد</span>
 | 
			
		||||
                              {% else %}
 | 
			
		||||
                                <span class="badge bg-warning text-dark">در انتظار</span>
 | 
			
		||||
                              {% endif %}
 | 
			
		||||
                            </div>
 | 
			
		||||
                            {% if st.status == 'rejected' and st.reason %}
 | 
			
		||||
                              <div class="mt-1 small text-danger">علت: {{ st.reason }}</div>
 | 
			
		||||
                            {% endif %}
 | 
			
		||||
                          </div>
 | 
			
		||||
                        </div>
 | 
			
		||||
                        {% endfor %}
 | 
			
		||||
                      </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                  </div>
 | 
			
		||||
                {% endif %}
 | 
			
		||||
 | 
			
		||||
                <div class="col-12 d-flex justify-content-between mt-3">
 | 
			
		||||
                  {% if previous_step %}
 | 
			
		||||
| 
						 | 
				
			
			@ -201,30 +235,114 @@
 | 
			
		|||
                  {% 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>
 | 
			
		||||
                  {% 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 %}
 | 
			
		||||
                      <a href="{% url 'processes:request_list' %}" class="btn btn-success">اتمام</a>
 | 
			
		||||
                    {% endif %}
 | 
			
		||||
                  {% endif %}
 | 
			
		||||
                </div>
 | 
			
		||||
              </div>
 | 
			
		||||
            </div>
 | 
			
		||||
          </form>
 | 
			
		||||
          
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
<!-- 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>
 | 
			
		||||
<!-- Removed legacy approvePaymentsModal; using approvePaymentsModal2 with form POST -->
 | 
			
		||||
<!-- Approve Modal 2 (direct approve button in header) -->
 | 
			
		||||
<div class="modal fade" id="approvePaymentsModal2" tabindex="-1" aria-hidden="true">
 | 
			
		||||
  <div class="modal-dialog">
 | 
			
		||||
    <div class="modal-content">
 | 
			
		||||
      <form method="post">
 | 
			
		||||
        {% csrf_token %}
 | 
			
		||||
        <input type="hidden" name="action" value="approve">
 | 
			
		||||
        <div class="modal-header">
 | 
			
		||||
          <h5 class="modal-title">تایید پرداختها</h5>
 | 
			
		||||
          <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="modal-body">
 | 
			
		||||
          {% if not totals.is_fully_paid %}
 | 
			
		||||
            <div class="alert alert-warning" role="alert">
 | 
			
		||||
              مبلغی از پیشفاکتور هنوز پرداخت نشده است.
 | 
			
		||||
              <div class="mt-1">مانده: <strong>{{ totals.remaining_amount|floatformat:0|intcomma:False }} تومان</strong></div>
 | 
			
		||||
            </div>
 | 
			
		||||
            آیا مطمئن هستید که میخواهید مرحله را تایید کنید؟
 | 
			
		||||
          {% else %}
 | 
			
		||||
            آیا از تایید این مرحله اطمینان دارید؟
 | 
			
		||||
          {% endif %}
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="modal-footer">
 | 
			
		||||
          <button type="button" class="btn btn-label-secondary" data-bs-dismiss="modal">انصراف</button>
 | 
			
		||||
          <button type="submit" class="btn btn-success">تایید</button>
 | 
			
		||||
        </div>
 | 
			
		||||
      </form>
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
</div>
 | 
			
		||||
<!-- Reject Modal for payments step -->
 | 
			
		||||
<div class="modal fade" id="rejectPaymentsModal" tabindex="-1" aria-hidden="true">
 | 
			
		||||
  <div class="modal-dialog">
 | 
			
		||||
    <div class="modal-content">
 | 
			
		||||
      <form method="post">
 | 
			
		||||
        {% csrf_token %}
 | 
			
		||||
        <input type="hidden" name="action" value="reject">
 | 
			
		||||
        <div class="modal-header">
 | 
			
		||||
          <h5 class="modal-title">رد مرحله پرداختها</h5>
 | 
			
		||||
          <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="modal-body">
 | 
			
		||||
          <div class="mb-2">
 | 
			
		||||
            <label class="form-label">علت رد</label>
 | 
			
		||||
            <textarea class="form-control" name="reject_reason" rows="3" required></textarea>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="modal-footer">
 | 
			
		||||
          <button type="button" class="btn btn-label-secondary" data-bs-dismiss="modal">انصراف</button>
 | 
			
		||||
          <button type="submit" class="btn btn-danger">ثبت رد</button>
 | 
			
		||||
        </div>
 | 
			
		||||
      </form>
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
</div>
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 | 
			
		||||
{% block script %}
 | 
			
		||||
<script>
 | 
			
		||||
  const isFullyPaid = {{ totals.is_fully_paid|yesno:'true,false' }};
 | 
			
		||||
  // Removed legacy isFullyPaid-driven approve flow; approval now via modal submit
 | 
			
		||||
  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() {
 | 
			
		||||
  const btnAddPayment = document.getElementById('btnAddPayment');
 | 
			
		||||
  if (btnAddPayment) btnAddPayment.addEventListener('click', function() {
 | 
			
		||||
    // Front-end validation
 | 
			
		||||
    const amount = document.getElementById('id_amount').value.trim();
 | 
			
		||||
    const payDate = document.getElementById('id_payment_date').value.trim();
 | 
			
		||||
| 
						 | 
				
			
			@ -283,51 +401,7 @@
 | 
			
		|||
    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) {
 | 
			
		||||
        showToast(resp.message || 'پرداختها تایید شد', 'success');
 | 
			
		||||
        if (resp.redirect) {
 | 
			
		||||
          setTimeout(() => { window.location.href = resp.redirect; }, 600);
 | 
			
		||||
        }
 | 
			
		||||
      } else {
 | 
			
		||||
        showToast(resp.message || resp.error || 'خطا در تایید پرداختها', '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();
 | 
			
		||||
    }
 | 
			
		||||
  });
 | 
			
		||||
  // Legacy approve JS removed; approval handled by modal forms in header
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
<!-- Persian Date Picker JS -->
 | 
			
		||||
| 
						 | 
				
			
			@ -365,42 +439,4 @@
 | 
			
		|||
  })();
 | 
			
		||||
</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 %}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -221,20 +221,32 @@
 | 
			
		|||
              <span></span>
 | 
			
		||||
            {% endif %}
 | 
			
		||||
            
 | 
			
		||||
            {% if step_instance.status == 'completed' %}
 | 
			
		||||
            {% if is_broker %}
 | 
			
		||||
              {% 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 %}
 | 
			
		||||
            {% else %}
 | 
			
		||||
              {% 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>
 | 
			
		||||
                   class="btn btn-label-primary">
 | 
			
		||||
                  مرحله بعد
 | 
			
		||||
                  <i class="bx bx-chevron-left bx-sm me-sm-n2"></i>
 | 
			
		||||
                </a>
 | 
			
		||||
              {% else %}
 | 
			
		||||
                <button class="btn btn-success" type="button">اتمام</button>
 | 
			
		||||
                <a href="{% url 'processes:request_list' %}" class="btn btn-success">اتمام</a>
 | 
			
		||||
              {% endif %}
 | 
			
		||||
            {% else %}
 | 
			
		||||
              <button type="button" class="btn btn-primary" id="btnApproveQuote">
 | 
			
		||||
                تایید پیشفاکتور
 | 
			
		||||
              </button>
 | 
			
		||||
            {% endif %}
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -58,6 +58,7 @@
 | 
			
		|||
                {% endif %}
 | 
			
		||||
                
 | 
			
		||||
                <div class="col-12">
 | 
			
		||||
                  {% if is_broker or existing_quote %}
 | 
			
		||||
                  <div class="table-responsive">
 | 
			
		||||
                    <table class="table table-sm align-middle">
 | 
			
		||||
                      <thead>
 | 
			
		||||
| 
						 | 
				
			
			@ -77,7 +78,8 @@
 | 
			
		|||
                                   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 %}>
 | 
			
		||||
                                   {% if item.is_default_in_quotes or not is_broker %}disabled{% endif %}
 | 
			
		||||
                                   {% if item.is_default_in_quotes %}title="آیتم پیشفرض است و قابل حذف نیست"{% elif not is_broker %}title="فقط کارگزار مجاز به تغییر اقلام است"{% endif %}>
 | 
			
		||||
                          </td>
 | 
			
		||||
                          <td>
 | 
			
		||||
                            <div class="d-flex flex-column">
 | 
			
		||||
| 
						 | 
				
			
			@ -86,15 +88,15 @@
 | 
			
		|||
                                <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 %}">
 | 
			
		||||
                            <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 %}"
 | 
			
		||||
                                   {% if not is_broker %}disabled title="فقط کارگزار مجاز به تغییر تعداد است"{% endif %}>
 | 
			
		||||
                          </td>
 | 
			
		||||
                        </tr>
 | 
			
		||||
                        {% endwith %}
 | 
			
		||||
| 
						 | 
				
			
			@ -102,8 +104,9 @@
 | 
			
		|||
                      </tbody>
 | 
			
		||||
                    </table>
 | 
			
		||||
                  </div>
 | 
			
		||||
                  
 | 
			
		||||
                  
 | 
			
		||||
                  {% else %}
 | 
			
		||||
                  <div class="alert alert-warning mb-0">شما دسترسی به ثبت اقلام ندارید.</div>
 | 
			
		||||
                  {% endif %}
 | 
			
		||||
                </div>
 | 
			
		||||
                
 | 
			
		||||
                <div class="col-12 d-flex justify-content-between">
 | 
			
		||||
| 
						 | 
				
			
			@ -118,27 +121,35 @@
 | 
			
		|||
                  {% 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>
 | 
			
		||||
 | 
			
		||||
                  {% if is_broker %}
 | 
			
		||||
                    {% 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 class="btn btn-success" type="button">اتمام</button>
 | 
			
		||||
                    <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 %}
 | 
			
		||||
                  {% 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>
 | 
			
		||||
                    {% if next_step %}
 | 
			
		||||
                      <a href="{% url 'processes:step_detail' instance.id next_step.id %}" class="btn btn-label-primary">
 | 
			
		||||
                        مرحله بعد
 | 
			
		||||
                        <i class="bx bx-chevron-left bx-sm me-sm-n2"></i>
 | 
			
		||||
                      </a>
 | 
			
		||||
                    {% else %}
 | 
			
		||||
                      <a href="{% url 'processes:request_list' %}" class="btn btn-success">اتمام</a>
 | 
			
		||||
                    {% endif %}
 | 
			
		||||
                  {% endif %}
 | 
			
		||||
                </div>
 | 
			
		||||
              </div>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue