Add qoute step.
This commit is contained in:
		
							parent
							
								
									b71ea45681
								
							
						
					
					
						commit
						6ff4740d04
					
				
					 30 changed files with 3362 additions and 376 deletions
				
			
		
							
								
								
									
										54
									
								
								processes/templates/processes/includes/stepper_header.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										54
									
								
								processes/templates/processes/includes/stepper_header.html
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,54 @@
 | 
			
		|||
{% load static %}
 | 
			
		||||
 | 
			
		||||
<div class="bs-stepper-header">
 | 
			
		||||
  {% for item in steps_context %}
 | 
			
		||||
    {% with step=item.step status=item.status can_access=item.can_access is_selected=item.is_selected is_todo=item.is_todo %}
 | 
			
		||||
    <div class="step 
 | 
			
		||||
      {% if not can_access %}disabled
 | 
			
		||||
      {% elif status == 'completed' %}completed
 | 
			
		||||
      {% elif is_todo %}active
 | 
			
		||||
      {% endif %}
 | 
			
		||||
      {% if is_selected %} selected{% endif %}" 
 | 
			
		||||
      data-target="#step-{{ step.id }}">
 | 
			
		||||
      
 | 
			
		||||
      {% if can_access %}
 | 
			
		||||
        <a href="{% url 'processes:step_detail' instance.id step.id %}" 
 | 
			
		||||
           class="step-trigger text-decoration-none p-0" 
 | 
			
		||||
           aria-selected="{% if is_selected %}true{% else %}false{% endif %}">
 | 
			
		||||
      {% else %}
 | 
			
		||||
        <span class="step-trigger">
 | 
			
		||||
      {% endif %}
 | 
			
		||||
      
 | 
			
		||||
        <span class="bs-stepper-circle">{{ forloop.counter }}</span>
 | 
			
		||||
        <span class="bs-stepper-label mt-1">
 | 
			
		||||
          <span class="bs-stepper-title">{{ step.name }}</span>
 | 
			
		||||
          <span class="bs-stepper-subtitle">{{ step.description|default:' ' }}</span>
 | 
			
		||||
        </span>
 | 
			
		||||
        
 | 
			
		||||
      {% if can_access %}
 | 
			
		||||
        </a>
 | 
			
		||||
      {% else %}
 | 
			
		||||
        </span>
 | 
			
		||||
      {% endif %}
 | 
			
		||||
    </div>
 | 
			
		||||
    {% endwith %}
 | 
			
		||||
    {% if not forloop.last %}<div class="line"></div>{% endif %}
 | 
			
		||||
  {% endfor %}
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
<style>
 | 
			
		||||
.step.disabled .step-trigger { opacity: 0.5; cursor: not-allowed; }
 | 
			
		||||
.step.disabled .bs-stepper-circle { background-color: #6c757d; }
 | 
			
		||||
 | 
			
		||||
/* تکمیل شده */
 | 
			
		||||
.step.completed .bs-stepper-circle { background-color: #28a745 !important; color: #fff !important; border-color: #28a745 !important; }
 | 
			
		||||
.step.completed .bs-stepper-title { color: #28a745 !important; }
 | 
			
		||||
 | 
			
		||||
/* مرحلهای که باید انجام شود (فعلی سیستم) */
 | 
			
		||||
.step.active .bs-stepper-circle { background-color: #696cff; color: #fff; }
 | 
			
		||||
.step.active .bs-stepper-title { color: #696cff; }
 | 
			
		||||
 | 
			
		||||
/* مرحله انتخابشده (نمایش فعلی صفحه) */
 | 
			
		||||
.step.selected { outline: 1px solid #696cff; border-radius: 8px; }
 | 
			
		||||
.step.selected .bs-stepper-circle { box-shadow: 0 0 0 3px rgba(13,202,240,.25); }
 | 
			
		||||
</style>
 | 
			
		||||
							
								
								
									
										774
									
								
								processes/templates/processes/request_list.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										774
									
								
								processes/templates/processes/request_list.html
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,774 @@
 | 
			
		|||
{% extends '_base.html' %}
 | 
			
		||||
{% load static %}
 | 
			
		||||
 | 
			
		||||
{% block sidebar %}
 | 
			
		||||
    {% include 'sidebars/admin.html' %}
 | 
			
		||||
{% endblock sidebar %}
 | 
			
		||||
 | 
			
		||||
{% block navbar %}
 | 
			
		||||
    {% include 'navbars/admin.html' %}
 | 
			
		||||
{% endblock navbar %}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
{% block title %}درخواستها{% endblock %}
 | 
			
		||||
 | 
			
		||||
{% block style %}
 | 
			
		||||
<!-- DataTables CSS -->
 | 
			
		||||
<link rel="stylesheet" href="{% static 'assets/vendor/libs/datatables-bs5/datatables.bootstrap5.css' %}">
 | 
			
		||||
<link rel="stylesheet" href="{% static 'assets/vendor/libs/datatables-responsive-bs5/responsive.bootstrap5.css' %}">
 | 
			
		||||
<link rel="stylesheet" href="{% static 'assets/vendor/libs/datatables-buttons-bs5/buttons.bootstrap5.css' %}">
 | 
			
		||||
<!-- Persian Date Picker CSS -->
 | 
			
		||||
<link rel="stylesheet" href="https://unpkg.com/persian-datepicker@latest/dist/css/persian-datepicker.min.css">
 | 
			
		||||
 | 
			
		||||
{% endblock style %}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
{% block content %}
 | 
			
		||||
{% include '_toasts.html' %}
 | 
			
		||||
 | 
			
		||||
<div class="container-xxl flex-grow-1 container-p-y">
 | 
			
		||||
 | 
			
		||||
  <div class="d-flex align-items-center justify-content-between mb-3">
 | 
			
		||||
    <h4 class="mb-0">درخواستها</h4>
 | 
			
		||||
    <button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#requestModal">
 | 
			
		||||
      <i class="bx bx-plus"></i>
 | 
			
		||||
      درخواست جدید
 | 
			
		||||
    </button>
 | 
			
		||||
  </div>
 | 
			
		||||
 | 
			
		||||
  <div class="card">
 | 
			
		||||
    <div class="table-responsive">
 | 
			
		||||
      <table id="requestsTable" class="table table-striped">
 | 
			
		||||
        <thead>
 | 
			
		||||
          <tr>
 | 
			
		||||
            <th>شناسه</th>
 | 
			
		||||
            <th>فرآیند</th>
 | 
			
		||||
            <th>شماره اشتراک آب</th>
 | 
			
		||||
            <th>نماینده</th>
 | 
			
		||||
            <th>درخواستکننده</th>
 | 
			
		||||
            <th>اولویت</th>
 | 
			
		||||
            <th>وضعیت</th>
 | 
			
		||||
            <th>تاریخ ایجاد</th>
 | 
			
		||||
            <th>عملیات</th>
 | 
			
		||||
          </tr>
 | 
			
		||||
        </thead>
 | 
			
		||||
        <tbody>
 | 
			
		||||
          {% for inst in instances %}
 | 
			
		||||
          <tr>
 | 
			
		||||
            <td>{{ inst.code }}</td>
 | 
			
		||||
            <td>{{ inst.process.name }}</td>
 | 
			
		||||
            <td>{{ inst.well.water_subscription_number }}</td>
 | 
			
		||||
            <td>{% if inst.representative %}{{ inst.representative.get_full_name }}{% else %}-{% endif %}</td>
 | 
			
		||||
            <td>{% if inst.requester %}{{ inst.requester.get_full_name }}{% else %}-{% endif %}</td>
 | 
			
		||||
            <td>{{ inst.get_priority_display }}</td>
 | 
			
		||||
            <td>{{ inst.get_status_display }}</td>
 | 
			
		||||
            <td>{{ inst.jcreated }}</td>
 | 
			
		||||
            <td>
 | 
			
		||||
              <div class="d-inline-block">
 | 
			
		||||
                <a href="javascript:;" class="btn btn-icon dropdown-toggle hide-arrow" data-bs-toggle="dropdown">
 | 
			
		||||
                  <i class="icon-base bx bx-dots-vertical-rounded"></i>
 | 
			
		||||
                </a>
 | 
			
		||||
                <ul class="dropdown-menu dropdown-menu-end m-0">
 | 
			
		||||
                  <li>
 | 
			
		||||
                    <a href="{% url 'processes:instance_steps' inst.id %}" class="dropdown-item">
 | 
			
		||||
                      <i class="bx bx-show me-1"></i>مشاهده جزئیات
 | 
			
		||||
                    </a>
 | 
			
		||||
                  </li>
 | 
			
		||||
                  <div class="dropdown-divider"></div>
 | 
			
		||||
                  <li>
 | 
			
		||||
                    <a href="#" class="dropdown-item text-danger" data-instance-id="{{ inst.id }}" data-instance-code="{{ inst.code }}" onclick="deleteRequest(this.getAttribute('data-instance-id'), this.getAttribute('data-instance-code'))">
 | 
			
		||||
                      <i class="bx bx-trash me-1"></i>حذف
 | 
			
		||||
                    </a>
 | 
			
		||||
                  </li>
 | 
			
		||||
                </ul>
 | 
			
		||||
              </div>
 | 
			
		||||
            </td>
 | 
			
		||||
          </tr>
 | 
			
		||||
          {% empty %}
 | 
			
		||||
          <tr>
 | 
			
		||||
            <td colspan="9" class="text-center text-muted">موردی ثبت نشده است</td>
 | 
			
		||||
          </tr>
 | 
			
		||||
          {% endfor %}
 | 
			
		||||
        </tbody>
 | 
			
		||||
      </table>
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
 | 
			
		||||
  <!-- Modal -->
 | 
			
		||||
  <div class="modal fade" id="requestModal" tabindex="-1" aria-hidden="true">
 | 
			
		||||
    <div class="modal-dialog modal-lg modal-dialog-centered">
 | 
			
		||||
      <div class="modal-content">
 | 
			
		||||
        <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">
 | 
			
		||||
          <form id="requestForm">
 | 
			
		||||
            {% csrf_token %}
 | 
			
		||||
            <div class="row g-3">
 | 
			
		||||
              <div class="col-sm-12">
 | 
			
		||||
                <label class="form-label">فرآیند</label>
 | 
			
		||||
                <select class="form-select" name="process" id="req_process" required>
 | 
			
		||||
                  {% for process in processes %}
 | 
			
		||||
                  <option value="{{ process.id }}">{{ process.name }}</option>
 | 
			
		||||
                  {% endfor %}
 | 
			
		||||
                </select>
 | 
			
		||||
              </div>
 | 
			
		||||
              <hr class="mt-3 border border-dashed">
 | 
			
		||||
              <div class="col-sm-12">
 | 
			
		||||
                <label class="form-label">شماره اشتراک آب</label>
 | 
			
		||||
                <div class="input-group">
 | 
			
		||||
                  <input type="text" class="form-control" id="req_water_sub" placeholder="مثال: 12345" required>
 | 
			
		||||
                  <button class="btn btn-outline-secondary" type="button" id="btnLookupWell">
 | 
			
		||||
                    بررسی/افزودن چاه
 | 
			
		||||
                  </button>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="form-text" id="wellStatus"></div>
 | 
			
		||||
              </div>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
              <!-- Well form fields (from WellForm) -->
 | 
			
		||||
              <div id="wellFormBlock" class="col-sm-12" style="display:none;">
 | 
			
		||||
                <div class="row g-3">
 | 
			
		||||
                  <div class="col-sm-6">
 | 
			
		||||
                    <label class="form-label" for="id_electricity_subscription_number">{{ well_form.electricity_subscription_number.label }}</label>
 | 
			
		||||
                    {{ well_form.electricity_subscription_number }}
 | 
			
		||||
                  </div>
 | 
			
		||||
                  <div class="col-sm-6">
 | 
			
		||||
                    <label class="form-label" for="id_water_meter_manufacturer">{{ well_form.water_meter_manufacturer.label }}</label>
 | 
			
		||||
                    <div class="input-group">
 | 
			
		||||
                      <select name="water_meter_manufacturer" class="form-select" id="id_water_meter_manufacturer">
 | 
			
		||||
                        <option value="" selected="">انتخاب شرکت سازنده</option>
 | 
			
		||||
                        {% for manufacturer in manufacturers %}
 | 
			
		||||
                        <option value="{{ manufacturer.id }}">{{ manufacturer.name }}</option>
 | 
			
		||||
                        {% endfor %}
 | 
			
		||||
                      </select>
 | 
			
		||||
                      <input type="text" class="form-control" id="id_new_manufacturer" name="new_manufacturer" placeholder="شرکت سازنده جدید" style="display:none;">
 | 
			
		||||
                      <button class="btn btn-outline-primary" type="button" id="btnToggleManufacturer">
 | 
			
		||||
                        <i class="bx bx-plus"></i>
 | 
			
		||||
                      </button>
 | 
			
		||||
                    </div>
 | 
			
		||||
                  </div>
 | 
			
		||||
                  <div class="col-sm-6">
 | 
			
		||||
                    <label class="form-label" for="id_water_meter_serial_number">{{ well_form.water_meter_serial_number.label }}</label>
 | 
			
		||||
                    {{ well_form.water_meter_serial_number }}
 | 
			
		||||
                  </div>
 | 
			
		||||
                  <div class="col-sm-6">
 | 
			
		||||
                    <label class="form-label" for="id_water_meter_old_serial_number">{{ well_form.water_meter_old_serial_number.label }}</label>
 | 
			
		||||
                    {{ well_form.water_meter_old_serial_number }}
 | 
			
		||||
                  </div>
 | 
			
		||||
                  <div class="col-sm-6">
 | 
			
		||||
                    <label class="form-label" for="id_utm_x">{{ well_form.utm_x.label }}</label>
 | 
			
		||||
                    {{ well_form.utm_x }}
 | 
			
		||||
                  </div>
 | 
			
		||||
                  <div class="col-sm-6">
 | 
			
		||||
                    <label class="form-label" for="id_utm_y">{{ well_form.utm_y.label }}</label>
 | 
			
		||||
                    {{ well_form.utm_y }}
 | 
			
		||||
                  </div>
 | 
			
		||||
                  <div class="col-sm-6">
 | 
			
		||||
                    <label class="form-label" for="id_utm_zone">{{ well_form.utm_zone.label }}</label>
 | 
			
		||||
                    {{ well_form.utm_zone }}
 | 
			
		||||
                  </div>
 | 
			
		||||
                  <div class="col-sm-6">
 | 
			
		||||
                    <label class="form-label" for="id_utm_hemisphere">{{ well_form.utm_hemisphere.label }}</label>
 | 
			
		||||
                    {{ well_form.utm_hemisphere }}
 | 
			
		||||
                  </div>
 | 
			
		||||
                  <div class="col-sm-6">
 | 
			
		||||
                    <label class="form-label" for="id_well_power">{{ well_form.well_power.label }}</label>
 | 
			
		||||
                    {{ well_form.well_power }}
 | 
			
		||||
                  </div>
 | 
			
		||||
                  <div class="col-sm-6"></div>
 | 
			
		||||
                  <div class="col-sm-6">
 | 
			
		||||
                    <label class="form-label" for="id_reference_letter_number">{{ well_form.reference_letter_number.label }}</label>
 | 
			
		||||
                    {{ well_form.reference_letter_number }}
 | 
			
		||||
                  </div>
 | 
			
		||||
                  <div class="col-sm-6">
 | 
			
		||||
                    <label class="form-label" for="id_reference_letter_date">{{ well_form.reference_letter_date.label }}</label>
 | 
			
		||||
                    <input type="text" class="form-control" id="id_reference_letter_date" name="reference_letter_date" placeholder="انتخاب تاریخ" readonly>
 | 
			
		||||
                  </div>
 | 
			
		||||
                  <div class="col-sm-12">
 | 
			
		||||
                    <label class="form-label" for="id_representative_letter_file">{{ well_form.representative_letter_file.label }}</label>
 | 
			
		||||
                    {{ well_form.representative_letter_file }}
 | 
			
		||||
                    <!-- نمایش فایل موجود -->
 | 
			
		||||
                    <div id="current-file-display" style="display: none; margin-top: 10px;">
 | 
			
		||||
                      <div class="alert alert-info d-flex align-items-center justify-content-between">
 | 
			
		||||
                        <div class="d-flex align-items-center">
 | 
			
		||||
                          <i class="bx bx-file me-2"></i>
 | 
			
		||||
                          <span id="current-file-name" class="text-truncate" style="max-width: 200px;" title=""></span>
 | 
			
		||||
                        </div>
 | 
			
		||||
                        <button type="button" class="btn btn-sm btn-outline-danger" onclick="removeCurrentFile()">
 | 
			
		||||
                          <i class="bx bx-trash me-1"></i>حذف
 | 
			
		||||
                        </button>
 | 
			
		||||
                      </div>
 | 
			
		||||
                    </div>
 | 
			
		||||
                    <input type="hidden" id="remove-file" name="remove_file" value="false">
 | 
			
		||||
                  </div>
 | 
			
		||||
                </div>
 | 
			
		||||
              </div>
 | 
			
		||||
              <hr class="mt-3 border border-dashed">
 | 
			
		||||
              <div class="col-sm-12">
 | 
			
		||||
                <label class="form-label">کد ملی نماینده</label>
 | 
			
		||||
                <div class="input-group">
 | 
			
		||||
                  <input type="text" class="form-control" id="rep_national_code" placeholder="مثال: 0012345678">
 | 
			
		||||
                  <button class="btn btn-outline-secondary" type="button" id="btnLookupRep">
 | 
			
		||||
                    بررسی/افزودن نماینده
 | 
			
		||||
                  </button>
 | 
			
		||||
                </div>
 | 
			
		||||
                <div class="form-text" id="repStatus"></div>
 | 
			
		||||
              </div>
 | 
			
		||||
 | 
			
		||||
              <div id="repNewFields" class="col-sm-12" style="display:none;">
 | 
			
		||||
                <div class="row g-3">
 | 
			
		||||
                  <div class="col-sm-6">
 | 
			
		||||
                    <label class="form-label" for="id_first_name">{{ customer_form.first_name.label }}</label>
 | 
			
		||||
                    {{ customer_form.first_name }}
 | 
			
		||||
                  </div>
 | 
			
		||||
                  <div class="col-sm-6">
 | 
			
		||||
                    <label class="form-label" for="id_last_name">{{ customer_form.last_name.label }}</label>
 | 
			
		||||
                    {{ customer_form.last_name }}
 | 
			
		||||
                  </div>
 | 
			
		||||
                  <div class="col-sm-6">
 | 
			
		||||
                    <label class="form-label" for="id_phone_number_1">{{ customer_form.phone_number_1.label }}</label>
 | 
			
		||||
                    {{ customer_form.phone_number_1 }}
 | 
			
		||||
                  </div>
 | 
			
		||||
                  <div class="col-sm-6">
 | 
			
		||||
                    <label class="form-label" for="id_phone_number_2">{{ customer_form.phone_number_2.label }}</label>
 | 
			
		||||
                    {{ customer_form.phone_number_2 }}
 | 
			
		||||
                  </div>
 | 
			
		||||
                  <div class="col-sm-6">
 | 
			
		||||
                    <label class="form-label" for="id_national_code">{{ customer_form.national_code.label }}</label>
 | 
			
		||||
                    {{ customer_form.national_code }}
 | 
			
		||||
                  </div>
 | 
			
		||||
                  <div class="col-sm-6">
 | 
			
		||||
                    <label class="form-label" for="id_card_number">{{ customer_form.card_number.label }}</label>
 | 
			
		||||
                    {{ customer_form.card_number }}
 | 
			
		||||
                  </div>
 | 
			
		||||
                  <div class="col-sm-6">
 | 
			
		||||
                    <label class="form-label" for="id_account_number">{{ customer_form.account_number.label }}</label>
 | 
			
		||||
                    {{ customer_form.account_number }}
 | 
			
		||||
                  </div>
 | 
			
		||||
                  <div class="col-sm-12">
 | 
			
		||||
                    <label class="form-label" for="id_address">{{ customer_form.address.label }}</label>
 | 
			
		||||
                    {{ customer_form.address }}
 | 
			
		||||
                  </div>
 | 
			
		||||
                </div>
 | 
			
		||||
              </div>
 | 
			
		||||
              <hr class="mt-3 border border-dashed">
 | 
			
		||||
              <div class="col-sm-12">
 | 
			
		||||
                <label class="form-label">توضیحات</label>
 | 
			
		||||
                <textarea class="form-control" rows="3" id="req_description"></textarea>
 | 
			
		||||
              </div>
 | 
			
		||||
            </div>
 | 
			
		||||
          </form>
 | 
			
		||||
        </div>
 | 
			
		||||
        <div class="modal-footer">
 | 
			
		||||
          <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">بستن</button>
 | 
			
		||||
          <button type="button" class="btn btn-primary" id="btnSaveRequest" disabled>ذخیره</button>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
</div>
 | 
			
		||||
 | 
			
		||||
<!-- Delete Confirmation Modal -->
 | 
			
		||||
<div class="modal fade" id="deleteConfirmModal" tabindex="-1" aria-labelledby="deleteConfirmModalLabel" aria-hidden="true">
 | 
			
		||||
  <div class="modal-dialog">
 | 
			
		||||
    <div class="modal-content">
 | 
			
		||||
      <div class="modal-header">
 | 
			
		||||
        <h5 class="modal-title" id="deleteConfirmModalLabel">تایید حذف</h5>
 | 
			
		||||
        <button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="modal-body">
 | 
			
		||||
        <p id="deleteConfirmText">آیا از حذف این درخواست اطمینان دارید؟</p>
 | 
			
		||||
      </div>
 | 
			
		||||
      <div class="modal-footer">
 | 
			
		||||
        <button type="button" class="btn btn-secondary" data-bs-dismiss="modal">انصراف</button>
 | 
			
		||||
        <button type="button" class="btn btn-danger" id="confirmDeleteBtn">حذف</button>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
</div>
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 | 
			
		||||
{% block script %}
 | 
			
		||||
<!-- DataTables JS -->
 | 
			
		||||
<script src="{% static 'assets/vendor/libs/datatables-bs5/datatables-bootstrap5.js' %}"></script>
 | 
			
		||||
<!-- Persian DataTable defaults -->
 | 
			
		||||
<script src="{% static 'assets/js/persian-datatable.js' %}"></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 to initialize Persian Date Picker
 | 
			
		||||
  function initPersianDatePicker() {
 | 
			
		||||
    if ($.fn.persianDatepicker && $('#id_reference_letter_date').length) {
 | 
			
		||||
      try {
 | 
			
		||||
        $('#id_reference_letter_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_reference_letter_date').val(persianDateString);
 | 
			
		||||
            } else {
 | 
			
		||||
              // اگر persianDate در دسترس نبود، تاریخ میلادی را نمایش بده
 | 
			
		||||
              $('#id_reference_letter_date').val(gregorianDateString);
 | 
			
		||||
            }
 | 
			
		||||
            
 | 
			
		||||
            // ذخیره تاریخ میلادی در فیلد مخفی برای ارسال به سرور
 | 
			
		||||
            $('#id_reference_letter_date').attr('data-gregorian', gregorianDateString);
 | 
			
		||||
          }
 | 
			
		||||
        });
 | 
			
		||||
      } catch (e) {
 | 
			
		||||
        console.error('Error initializing Persian Date Picker:', e);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  $(function() {
 | 
			
		||||
    // if ($.fn.DataTable) {
 | 
			
		||||
    //   try {
 | 
			
		||||
    //     $('#requestsTable').DataTable({
 | 
			
		||||
    //       pageLength: 10,
 | 
			
		||||
    //       order: [[0, 'desc']]
 | 
			
		||||
    //     });
 | 
			
		||||
    //   } catch (e) {
 | 
			
		||||
    //     console.error('DataTable init failed', e);
 | 
			
		||||
    //   }
 | 
			
		||||
    // } else {
 | 
			
		||||
    //   console.warn('DataTables library not loaded');
 | 
			
		||||
    // }
 | 
			
		||||
 | 
			
		||||
    let currentWellId = null;
 | 
			
		||||
    let currentRepId = null;
 | 
			
		||||
    let wellChecked = false;
 | 
			
		||||
    let repChecked = false;
 | 
			
		||||
 | 
			
		||||
    function setStatus(el, text, type) {
 | 
			
		||||
      $(el).text(text).removeClass('text-danger text-success text-muted').addClass(type ? 'text-' + type : 'text-muted');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function checkSaveButton() {
 | 
			
		||||
      const canSave = wellChecked && repChecked;
 | 
			
		||||
      $('#btnSaveRequest').prop('disabled', !canSave);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Inline error helpers
 | 
			
		||||
    function clearInlineErrors() {
 | 
			
		||||
      $('#requestModal .is-invalid').removeClass('is-invalid');
 | 
			
		||||
      $('#requestModal .invalid-feedback.inline-error').remove();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function applyErrorTo(selector, message) {
 | 
			
		||||
      const $el = $(selector);
 | 
			
		||||
      if (!$el.length) return false;
 | 
			
		||||
      $el.addClass('is-invalid');
 | 
			
		||||
      const $feedback = $('<div class="invalid-feedback inline-error"></div>').text(message);
 | 
			
		||||
      const $grp = $el.closest('.input-group');
 | 
			
		||||
      if ($grp.length) {
 | 
			
		||||
        $feedback.insertAfter($grp);
 | 
			
		||||
      } else {
 | 
			
		||||
        $feedback.insertAfter($el);
 | 
			
		||||
      }
 | 
			
		||||
      return true;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function mapWellFieldToSelector(field) {
 | 
			
		||||
      switch (field) {
 | 
			
		||||
        case 'water_subscription_number': return '#req_water_sub';
 | 
			
		||||
        case 'electricity_subscription_number': return '#id_electricity_subscription_number';
 | 
			
		||||
        case 'water_meter_serial_number': return '#id_water_meter_serial_number';
 | 
			
		||||
        case 'water_meter_old_serial_number': return '#id_water_meter_old_serial_number';
 | 
			
		||||
        case 'water_meter_manufacturer': return '#id_water_meter_manufacturer';
 | 
			
		||||
        case 'new_manufacturer': return '#id_new_manufacturer';
 | 
			
		||||
        case 'utm_x': return '#id_utm_x';
 | 
			
		||||
        case 'utm_y': return '#id_utm_y';
 | 
			
		||||
        case 'utm_zone': return '#id_utm_zone';
 | 
			
		||||
        case 'utm_hemisphere': return '#id_utm_hemisphere';
 | 
			
		||||
        case 'well_power': return '#id_well_power';
 | 
			
		||||
        case 'reference_letter_number': return '#id_reference_letter_number';
 | 
			
		||||
        case 'reference_letter_date': return '#id_reference_letter_date';
 | 
			
		||||
        case 'representative_letter_file': return '#id_representative_letter_file';
 | 
			
		||||
        case 'representative': return '#rep_national_code';
 | 
			
		||||
        default: return '#id_' + field;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function mapCustomerFieldToSelector(field) {
 | 
			
		||||
      switch (field) {
 | 
			
		||||
        case 'national_code': return $('#id_national_code').length ? '#id_national_code' : '#rep_national_code';
 | 
			
		||||
        case 'first_name': return '#id_first_name';
 | 
			
		||||
        case 'last_name': return '#id_last_name';
 | 
			
		||||
        case 'phone_number_1': return '#id_phone_number_1';
 | 
			
		||||
        case 'phone_number_2': return '#id_phone_number_2';
 | 
			
		||||
        case 'card_number': return '#id_card_number';
 | 
			
		||||
        case 'account_number': return '#id_account_number';
 | 
			
		||||
        case 'address': return '#id_address';
 | 
			
		||||
        default: return '#id_' + field;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function showInlineErrors(errors) {
 | 
			
		||||
      if (!errors) return;
 | 
			
		||||
      let nonFieldWell = '';
 | 
			
		||||
      let nonFieldCustomer = '';
 | 
			
		||||
      if (errors.well) {
 | 
			
		||||
        for (const key in errors.well) {
 | 
			
		||||
          const msgs = Array.isArray(errors.well[key]) ? errors.well[key] : [errors.well[key]];
 | 
			
		||||
          if (key === '__all__' || key === 'non_field_errors') { nonFieldWell = msgs.join('، '); continue; }
 | 
			
		||||
          const sel = mapWellFieldToSelector(key);
 | 
			
		||||
          applyErrorTo(sel, msgs[0]);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      if (errors.customer) {
 | 
			
		||||
        for (const key in errors.customer) {
 | 
			
		||||
          const msgs = Array.isArray(errors.customer[key]) ? errors.customer[key] : [errors.customer[key]];
 | 
			
		||||
          if (key === '__all__' || key === 'non_field_errors') { nonFieldCustomer = msgs.join('، '); continue; }
 | 
			
		||||
          const sel = mapCustomerFieldToSelector(key);
 | 
			
		||||
          applyErrorTo(sel, msgs[0]);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      if (nonFieldWell) setStatus('#wellStatus', nonFieldWell, 'danger');
 | 
			
		||||
      if (nonFieldCustomer) setStatus('#repStatus', nonFieldCustomer, 'danger');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    $('#btnLookupWell').on('click', function() {
 | 
			
		||||
      const sub = $('#req_water_sub').val().trim();
 | 
			
		||||
      if (!sub) { setStatus('#wellStatus', 'لطفا شماره اشتراک آب را وارد کنید', 'danger'); return; }
 | 
			
		||||
      setStatus('#wellStatus', 'در حال بررسی...', 'muted');
 | 
			
		||||
      wellChecked = true;
 | 
			
		||||
      checkSaveButton();
 | 
			
		||||
      $.get('{% url "processes:lookup_well_by_subscription" %}', { water_subscription_number: sub })
 | 
			
		||||
        .done(function(resp){
 | 
			
		||||
            if (resp.exists) {
 | 
			
		||||
            currentWellId = resp.well.id;
 | 
			
		||||
            $('#wellFormBlock').show();
 | 
			
		||||
            // Initialize Persian Date Picker after well form is shown
 | 
			
		||||
            setTimeout(initPersianDatePicker, 100);
 | 
			
		||||
 | 
			
		||||
            // Prefill well form
 | 
			
		||||
            $('#id_electricity_subscription_number').val(resp.well.electricity_subscription_number || '');
 | 
			
		||||
            $('#id_water_meter_serial_number').val(resp.well.water_meter_serial_number || '');
 | 
			
		||||
            $('#id_water_meter_old_serial_number').val(resp.well.water_meter_old_serial_number || '');
 | 
			
		||||
            $('#id_water_meter_manufacturer').val(resp.well.water_meter_manufacturer || '');
 | 
			
		||||
            $('#id_utm_x').val(resp.well.utm_x || '');
 | 
			
		||||
            $('#id_utm_y').val(resp.well.utm_y || '');
 | 
			
		||||
            $('#id_utm_zone').val(resp.well.utm_zone || '');
 | 
			
		||||
            $('#id_utm_hemisphere').val(resp.well.utm_hemisphere || '');
 | 
			
		||||
            $('#id_well_power').val(resp.well.well_power || '');
 | 
			
		||||
            $('#id_reference_letter_number').val(resp.well.reference_letter_number || '');
 | 
			
		||||
            // Prefill date: show Persian in input, keep Gregorian in data attribute
 | 
			
		||||
            if (resp.well.reference_letter_date) {
 | 
			
		||||
              try {
 | 
			
		||||
                if (window.persianDate) {
 | 
			
		||||
                  const gregorianDate = new Date(resp.well.reference_letter_date);
 | 
			
		||||
                  const persianDateObj = new window.persianDate(gregorianDate);
 | 
			
		||||
                  const persianDateString = persianDateObj.format('YYYY/MM/DD');
 | 
			
		||||
                  $('#id_reference_letter_date').val(persianDateString);
 | 
			
		||||
                } else {
 | 
			
		||||
                  $('#id_reference_letter_date').val(resp.well.reference_letter_date);
 | 
			
		||||
                }
 | 
			
		||||
                $('#id_reference_letter_date').attr('data-gregorian', resp.well.reference_letter_date);
 | 
			
		||||
              } catch (e) {
 | 
			
		||||
                $('#id_reference_letter_date').val(resp.well.reference_letter_date);
 | 
			
		||||
              }
 | 
			
		||||
            } else {
 | 
			
		||||
              $('#id_reference_letter_date').val('');
 | 
			
		||||
              $('#id_reference_letter_date').removeAttr('data-gregorian');
 | 
			
		||||
            }
 | 
			
		||||
              // Existing representative letter file display
 | 
			
		||||
              if (resp.well.representative_letter_file_url) {
 | 
			
		||||
                $('#current-file-display').show();
 | 
			
		||||
                const fileName = resp.well.representative_letter_file_name || 'فایل موجود';
 | 
			
		||||
                $('#current-file-name').text(fileName).attr('title', fileName);
 | 
			
		||||
                $('#id_representative_letter_file').hide();
 | 
			
		||||
                $('#remove-file').val('false');
 | 
			
		||||
              } else {
 | 
			
		||||
                $('#current-file-display').hide();
 | 
			
		||||
                $('#id_representative_letter_file').show();
 | 
			
		||||
                $('#remove-file').val('false');
 | 
			
		||||
              }
 | 
			
		||||
            setStatus('#wellStatus', 'چاه یافت شد', 'success');
 | 
			
		||||
          } else {
 | 
			
		||||
            currentWellId = null;
 | 
			
		||||
            $('#wellFormBlock').show();
 | 
			
		||||
            $('#wellFormBlock').find('input, select').val('');
 | 
			
		||||
            $('#id_reference_letter_date').removeAttr('data-gregorian');
 | 
			
		||||
              // Reset file UI for new well
 | 
			
		||||
              $('#current-file-display').hide();
 | 
			
		||||
              $('#id_representative_letter_file').show().val('');
 | 
			
		||||
              $('#remove-file').val('false');
 | 
			
		||||
            // Initialize Persian Date Picker after well form is shown
 | 
			
		||||
            setTimeout(initPersianDatePicker, 100);
 | 
			
		||||
            setStatus('#wellStatus', 'چاه یافت نشد. با ذخیره، ایجاد خواهد شد.', 'danger');
 | 
			
		||||
          }
 | 
			
		||||
        })
 | 
			
		||||
        .fail(function(){ setStatus('#wellStatus', 'خطا در بررسی چاه', 'danger'); });
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    $('#btnLookupRep').on('click', function() {
 | 
			
		||||
      const nc = $('#rep_national_code').val().trim();
 | 
			
		||||
      if (!nc) { setStatus('#repStatus', 'لطفا کد ملی نماینده را وارد کنید', 'danger'); return; }
 | 
			
		||||
      setStatus('#repStatus', 'در حال بررسی...', 'muted');
 | 
			
		||||
      repChecked = true;
 | 
			
		||||
      checkSaveButton();
 | 
			
		||||
      $.get('{% url "processes:lookup_representative_by_national_code" %}', { national_code: nc })
 | 
			
		||||
        .done(function(resp){
 | 
			
		||||
          if (resp.exists) {
 | 
			
		||||
            currentRepId = resp.user.id;
 | 
			
		||||
            $('#repNewFields').show();
 | 
			
		||||
            // Prefill customer form fields for editing
 | 
			
		||||
            $('#id_first_name').val(resp.user.first_name || '');
 | 
			
		||||
            $('#id_last_name').val(resp.user.last_name || '');
 | 
			
		||||
            if (resp.user.profile) {
 | 
			
		||||
              $('#id_national_code').val(resp.user.profile.national_code || nc);
 | 
			
		||||
              $('#id_phone_number_1').val(resp.user.profile.phone_number_1 || '');
 | 
			
		||||
              $('#id_phone_number_2').val(resp.user.profile.phone_number_2 || '');
 | 
			
		||||
              $('#id_card_number').val(resp.user.profile.card_number || '');
 | 
			
		||||
              $('#id_account_number').val(resp.user.profile.account_number || '');
 | 
			
		||||
              $('#id_address').val(resp.user.profile.address || '');
 | 
			
		||||
            } else {
 | 
			
		||||
              $('#id_national_code').val(nc);
 | 
			
		||||
              $('#id_phone_number_1').val('');
 | 
			
		||||
              $('#id_phone_number_2').val('');
 | 
			
		||||
              $('#id_card_number').val('');
 | 
			
		||||
              $('#id_account_number').val('');
 | 
			
		||||
              $('#id_address').val('');
 | 
			
		||||
            }
 | 
			
		||||
            setStatus('#repStatus', 'نماینده یافت شد.', 'success');
 | 
			
		||||
          } else {
 | 
			
		||||
            currentRepId = null;
 | 
			
		||||
            $('#repNewFields').show();
 | 
			
		||||
            // Clear form and prefill national code
 | 
			
		||||
            $('#id_first_name').val('');
 | 
			
		||||
            $('#id_last_name').val('');
 | 
			
		||||
            $('#id_national_code').val(nc);
 | 
			
		||||
            $('#id_phone_number_1').val('');
 | 
			
		||||
            $('#id_phone_number_2').val('');
 | 
			
		||||
            $('#id_card_number').val('');
 | 
			
		||||
            $('#id_account_number').val('');
 | 
			
		||||
            $('#id_address').val('');
 | 
			
		||||
            setStatus('#repStatus', 'نماینده یافت نشد. لطفا اطلاعات را تکمیل کنید.', 'danger');
 | 
			
		||||
          }
 | 
			
		||||
        })
 | 
			
		||||
        .fail(function(){ setStatus('#repStatus', 'خطا در بررسی نماینده', 'danger'); });
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    $('#btnSaveRequest').on('click', function(){
 | 
			
		||||
      const formData = new FormData();
 | 
			
		||||
      formData.append('csrfmiddlewaretoken', $('input[name=csrfmiddlewaretoken]').val());
 | 
			
		||||
      formData.append('process', $('#req_process').val());
 | 
			
		||||
      formData.append('description', $('#req_description').val());
 | 
			
		||||
      formData.append('water_subscription_number', $('#req_water_sub').val().trim());
 | 
			
		||||
      if (currentWellId) formData.append('well_id', currentWellId);
 | 
			
		||||
      if (currentRepId) formData.append('representative_id', currentRepId);
 | 
			
		||||
      // Send fields using CustomerForm names if visible
 | 
			
		||||
      const ncField = $('#id_national_code').length ? $('#id_national_code').val() : '';
 | 
			
		||||
      formData.append('national_code', (ncField || $('#rep_national_code').val().trim()));
 | 
			
		||||
      formData.append('first_name', $('#id_first_name').val() || '');
 | 
			
		||||
      formData.append('last_name', $('#id_last_name').val() || '');
 | 
			
		||||
      formData.append('phone_number_1', $('#id_phone_number_1').val() || '');
 | 
			
		||||
      formData.append('phone_number_2', $('#id_phone_number_2').val() || '');
 | 
			
		||||
      formData.append('card_number', $('#id_card_number').val() || '');
 | 
			
		||||
      formData.append('account_number', $('#id_account_number').val() || '');
 | 
			
		||||
      formData.append('address', $('#id_address').val() || '');
 | 
			
		||||
 | 
			
		||||
      // Include WellForm fields so edits are saved
 | 
			
		||||
      if ($('#wellFormBlock').is(':visible')) {
 | 
			
		||||
        formData.append('electricity_subscription_number', $('#id_electricity_subscription_number').val() || '');
 | 
			
		||||
        formData.append('water_meter_serial_number', $('#id_water_meter_serial_number').val() || '');
 | 
			
		||||
        formData.append('water_meter_old_serial_number', $('#id_water_meter_old_serial_number').val() || '');
 | 
			
		||||
        formData.append('water_meter_manufacturer', $('#id_water_meter_manufacturer').is(':visible') ? ($('#id_water_meter_manufacturer').val() || '') : '');
 | 
			
		||||
        formData.append('new_manufacturer', $('#id_new_manufacturer').is(':visible') ? ($('#id_new_manufacturer').val() || '') : '');
 | 
			
		||||
        formData.append('utm_x', $('#id_utm_x').val() || '');
 | 
			
		||||
        formData.append('utm_y', $('#id_utm_y').val() || '');
 | 
			
		||||
        formData.append('utm_zone', $('#id_utm_zone').val() || '');
 | 
			
		||||
        formData.append('utm_hemisphere', $('#id_utm_hemisphere').val() || '');
 | 
			
		||||
        formData.append('well_power', $('#id_well_power').val() || '');
 | 
			
		||||
        formData.append('reference_letter_number', $('#id_reference_letter_number').val() || '');
 | 
			
		||||
        // Use gregorian date if available, otherwise use the field value
 | 
			
		||||
        const gregorianDate = $('#id_reference_letter_date').attr('data-gregorian');
 | 
			
		||||
        formData.append('reference_letter_date', gregorianDate || $('#id_reference_letter_date').val() || '');
 | 
			
		||||
        // Remove flag
 | 
			
		||||
        formData.append('remove_file', $('#remove-file').val() || 'false');
 | 
			
		||||
        const repFile = document.getElementById('id_representative_letter_file');
 | 
			
		||||
        if (repFile && repFile.files && repFile.files[0]) {
 | 
			
		||||
          formData.append('representative_letter_file', repFile.files[0]);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      const $btn = $(this).prop('disabled', true).text('در حال ذخیره...');
 | 
			
		||||
      $.ajax({
 | 
			
		||||
        url: '{% url "processes:create_request_with_entities" %}',
 | 
			
		||||
        method: 'POST',
 | 
			
		||||
        data: formData,
 | 
			
		||||
        processData: false,
 | 
			
		||||
        contentType: false,
 | 
			
		||||
      }).done(function(resp){
 | 
			
		||||
        if (resp.ok) {
 | 
			
		||||
          showToast('درخواست با موفقیت ثبت شد', 'success');
 | 
			
		||||
          if (resp.redirect) {
 | 
			
		||||
            setTimeout(function(){ window.location.href = resp.redirect; }, 800);
 | 
			
		||||
          } else {
 | 
			
		||||
            setTimeout(function(){ location.reload(); }, 1200);
 | 
			
		||||
          }
 | 
			
		||||
        } else {
 | 
			
		||||
          const msg = buildErrorMessage(resp);
 | 
			
		||||
          showToast(msg, 'danger');
 | 
			
		||||
        }
 | 
			
		||||
      }).fail(function(xhr){
 | 
			
		||||
        let msg = 'خطا در ذخیره';
 | 
			
		||||
        try {
 | 
			
		||||
          const resp = JSON.parse(xhr.responseText);
 | 
			
		||||
          msg = buildErrorMessage(resp) || msg;
 | 
			
		||||
        } catch(e) {}
 | 
			
		||||
        showToast(msg, 'danger');
 | 
			
		||||
      }).always(function(){
 | 
			
		||||
        $btn.prop('disabled', false).text('ذخیره');
 | 
			
		||||
      });
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    function buildErrorMessage(resp){
 | 
			
		||||
      if (!resp) return '';
 | 
			
		||||
      if (resp.error) return resp.error;
 | 
			
		||||
      if (resp.errors) {
 | 
			
		||||
        // Collect form-related errors
 | 
			
		||||
        const parts = [];
 | 
			
		||||
        if (resp.errors.customer) {
 | 
			
		||||
          parts.push('خطای نماینده: ' + flattenErrors(resp.errors.customer));
 | 
			
		||||
        }
 | 
			
		||||
        if (resp.errors.well) {
 | 
			
		||||
          parts.push('خطای چاه: ' + flattenErrors(resp.errors.well));
 | 
			
		||||
        }
 | 
			
		||||
        return parts.join(' | ');
 | 
			
		||||
      }
 | 
			
		||||
      return '';
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function flattenErrors(errorsObj){
 | 
			
		||||
      if (typeof errorsObj === 'string') return errorsObj;
 | 
			
		||||
      try {
 | 
			
		||||
        const parts = [];
 | 
			
		||||
        for (const k in errorsObj){
 | 
			
		||||
          const v = errorsObj[k];
 | 
			
		||||
          if (Array.isArray(v)) parts.push(`${k}: ${v[0]}`);
 | 
			
		||||
          else if (typeof v === 'string') parts.push(`${k}: ${v}`);
 | 
			
		||||
        }
 | 
			
		||||
        return parts.join('، ');
 | 
			
		||||
      } catch(e){
 | 
			
		||||
        return '';
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    $('#btnToggleManufacturer').on('click', function() {
 | 
			
		||||
      const $select = $('#id_water_meter_manufacturer');
 | 
			
		||||
      const $input = $('#id_new_manufacturer');
 | 
			
		||||
      const $btn = $(this);
 | 
			
		||||
      
 | 
			
		||||
      if ($select.is(':visible')) {
 | 
			
		||||
        $select.hide();
 | 
			
		||||
        $input.show().focus();
 | 
			
		||||
        $btn.html('<i class="bx bx-check"></i>');
 | 
			
		||||
      } else {
 | 
			
		||||
        $input.hide();
 | 
			
		||||
        $select.show();
 | 
			
		||||
        $btn.html('<i class="bx bx-plus"></i>');
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    $('#requestModal').on('hidden.bs.modal', function(){
 | 
			
		||||
      $('#requestForm')[0].reset();
 | 
			
		||||
      $('#wellFormBlock').hide();
 | 
			
		||||
      $('#repNewFields').hide();
 | 
			
		||||
      $('#id_reference_letter_date').removeAttr('data-gregorian');
 | 
			
		||||
      // Reset file UI
 | 
			
		||||
      $('#current-file-display').hide();
 | 
			
		||||
      $('#id_representative_letter_file').show().val('');
 | 
			
		||||
      $('#remove-file').val('false');
 | 
			
		||||
      setStatus('#wellStatus', '', '');
 | 
			
		||||
      setStatus('#repStatus', '', '');
 | 
			
		||||
      currentWellId = null;
 | 
			
		||||
      currentRepId = null;
 | 
			
		||||
      wellChecked = false;
 | 
			
		||||
      repChecked = false;
 | 
			
		||||
      checkSaveButton();
 | 
			
		||||
      clearInlineErrors(); // Clear inline errors on modal close
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    // Handle selecting a new file: hide existing file display and cancel removal flag
 | 
			
		||||
    $('#id_representative_letter_file').on('change', function() {
 | 
			
		||||
      if (this.files && this.files.length > 0) {
 | 
			
		||||
        $('#current-file-display').hide();
 | 
			
		||||
        $('#remove-file').val('false');
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    // Expose remove function
 | 
			
		||||
    window.removeCurrentFile = function() {
 | 
			
		||||
      $('#current-file-display').hide();
 | 
			
		||||
      $('#remove-file').val('true');
 | 
			
		||||
      $('#id_representative_letter_file').show().val('');
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    // Delete request function
 | 
			
		||||
    window.deleteRequest = function(instanceId, instanceCode) {
 | 
			
		||||
      // Set modal content
 | 
			
		||||
      document.getElementById('deleteConfirmText').textContent = `آیا از حذف درخواست ${instanceCode} اطمینان دارید؟`;
 | 
			
		||||
      
 | 
			
		||||
      // Show modal
 | 
			
		||||
      const modal = new bootstrap.Modal(document.getElementById('deleteConfirmModal'));
 | 
			
		||||
      modal.show();
 | 
			
		||||
      
 | 
			
		||||
      // Handle confirm button click
 | 
			
		||||
      document.getElementById('confirmDeleteBtn').onclick = function() {
 | 
			
		||||
        $.ajax({
 | 
			
		||||
          url: '{% url "processes:delete_request" 0 %}'.replace('0', instanceId),
 | 
			
		||||
          type: 'POST',
 | 
			
		||||
          data: {
 | 
			
		||||
            'csrfmiddlewaretoken': $('[name=csrfmiddlewaretoken]').val()
 | 
			
		||||
          },
 | 
			
		||||
          success: function(response) {
 | 
			
		||||
            if (response.success) {
 | 
			
		||||
              showToast(response.message, 'success');
 | 
			
		||||
              modal.hide();
 | 
			
		||||
              setTimeout(() => {
 | 
			
		||||
                window.location.reload();
 | 
			
		||||
              }, 1500);
 | 
			
		||||
            } else {
 | 
			
		||||
              showToast(response.message, 'danger');
 | 
			
		||||
            }
 | 
			
		||||
          },
 | 
			
		||||
          error: function() {
 | 
			
		||||
            showToast('خطا در ارتباط با سرور', 'danger');
 | 
			
		||||
          }
 | 
			
		||||
        });
 | 
			
		||||
      };
 | 
			
		||||
    };
 | 
			
		||||
  });
 | 
			
		||||
</script>
 | 
			
		||||
{% endblock %}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										97
									
								
								processes/templates/processes/step_detail.html
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										97
									
								
								processes/templates/processes/step_detail.html
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,97 @@
 | 
			
		|||
{% extends '_base.html' %}
 | 
			
		||||
{% load static %}
 | 
			
		||||
{% load processes_tags %}
 | 
			
		||||
 | 
			
		||||
{% 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">
 | 
			
		||||
          <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">
 | 
			
		||||
              <div class="col-12">
 | 
			
		||||
                <div class="alert alert-info">
 | 
			
		||||
                  <h6>وضعیت مرحله: 
 | 
			
		||||
                    {% if step_instance %}
 | 
			
		||||
                      {{ step_instance.get_status_display_with_color|safe }}
 | 
			
		||||
                    {% else %}
 | 
			
		||||
                      <span class="badge bg-secondary">در انتظار</span>
 | 
			
		||||
                    {% endif %}
 | 
			
		||||
                  </h6>
 | 
			
		||||
                  <p class="mb-0">فرم این مرحله بعداً پیادهسازی میشود.</p>
 | 
			
		||||
                  
 | 
			
		||||
                  {% if step_instance and step_instance.notes %}
 | 
			
		||||
                    <hr>
 | 
			
		||||
                    <strong>یادداشتها:</strong>
 | 
			
		||||
                    <p class="mb-0">{{ step_instance.notes }}</p>
 | 
			
		||||
                  {% endif %}
 | 
			
		||||
                </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 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-right bx-sm me-sm-n2"></i>
 | 
			
		||||
                  </a>
 | 
			
		||||
                {% else %}
 | 
			
		||||
                  <button class="btn btn-success" type="button">اتمام</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>
 | 
			
		||||
{% endblock %}
 | 
			
		||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue