clean up proccess and req_list app.
This commit is contained in:
		
							parent
							
								
									35799b7754
								
							
						
					
					
						commit
						6f3ce51ab9
					
				
					 26 changed files with 287 additions and 744 deletions
				
			
		| 
						 | 
				
			
			@ -28,17 +28,113 @@
 | 
			
		|||
 | 
			
		||||
<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 class="row py-3 mb-4 card-header flex-column flex-md-row pb-0">
 | 
			
		||||
    <div class="d-md-flex justify-content-between align-items-center dt-layout-start col-md-auto me-auto mt-0">
 | 
			
		||||
      <h5 class="card-title mb-0 text-md-start text-center fw-bold">لیست درخواستها</h5>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="d-md-flex justify-content-between align-items-center dt-layout-end col-md-auto ms-auto mt-0">
 | 
			
		||||
      <div class="dt-buttons btn-group flex-wrap mb-0">
 | 
			
		||||
        <div class="btn-group">
 | 
			
		||||
          <button class="btn buttons-collection btn-label-primary dropdown-toggle me-4 d-none" type="button">
 | 
			
		||||
            <span>
 | 
			
		||||
              <span class="d-flex align-items-center gap-2">
 | 
			
		||||
                <i class="icon-base bx bx-export me-sm-1"></i>
 | 
			
		||||
                <span class="d-none d-sm-inline-block">خروجی</span>
 | 
			
		||||
              </span>
 | 
			
		||||
            </span>
 | 
			
		||||
          </button>
 | 
			
		||||
          <button class="btn btn-primary" data-bs-toggle="modal" data-bs-target="#requestModal">
 | 
			
		||||
            <i class="bx bx-plus me-1"></i>
 | 
			
		||||
            درخواست جدید
 | 
			
		||||
          </button>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
 | 
			
		||||
  <!-- Summary Cards -->
 | 
			
		||||
  <div class="row g-4 mb-4">
 | 
			
		||||
    <div class="col-sm-6 col-xl-3">
 | 
			
		||||
      <div class="card">
 | 
			
		||||
        <div class="card-body">
 | 
			
		||||
          <div class="d-flex align-items-start justify-content-between">
 | 
			
		||||
            <div class="content-left">
 | 
			
		||||
              <span>کل درخواستها</span>
 | 
			
		||||
              <div class="d-flex align-items-end mt-2">
 | 
			
		||||
                <h4 class="mb-0 me-2">{{ total_count }}</h4>
 | 
			
		||||
              </div>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="avatar">
 | 
			
		||||
              <span class="avatar-initial rounded bg-label-primary">
 | 
			
		||||
                <i class="bx bx-list-ul bx-sm"></i>
 | 
			
		||||
              </span>
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="col-sm-6 col-xl-3">
 | 
			
		||||
      <div class="card">
 | 
			
		||||
        <div class="card-body">
 | 
			
		||||
          <div class="d-flex align-items-start justify-content-between">
 | 
			
		||||
            <div class="content-left">
 | 
			
		||||
              <span>تکمیلشده</span>
 | 
			
		||||
              <div class="d-flex align-items-end mt-2">
 | 
			
		||||
                <h4 class="mb-0 me-2">{{ completed_count }}</h4>
 | 
			
		||||
              </div>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="avatar">
 | 
			
		||||
              <span class="avatar-initial rounded bg-label-success">
 | 
			
		||||
                <i class="bx bx-badge-check bx-sm"></i>
 | 
			
		||||
              </span>
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="col-sm-6 col-xl-3">
 | 
			
		||||
      <div class="card">
 | 
			
		||||
        <div class="card-body">
 | 
			
		||||
          <div class="d-flex align-items-start justify-content-between">
 | 
			
		||||
            <div class="content-left">
 | 
			
		||||
              <span>در حال انجام</span>
 | 
			
		||||
              <div class="d-flex align-items-end mt-2">
 | 
			
		||||
                <h4 class="mb-0 me-2">{{ in_progress_count }}</h4>
 | 
			
		||||
              </div>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="avatar">
 | 
			
		||||
              <span class="avatar-initial rounded bg-label-info">
 | 
			
		||||
                <i class="bx bx-loader-circle bx-sm"></i>
 | 
			
		||||
              </span>
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
    <div class="col-sm-6 col-xl-3">
 | 
			
		||||
      <div class="card">
 | 
			
		||||
        <div class="card-body">
 | 
			
		||||
          <div class="d-flex align-items-start justify-content-between">
 | 
			
		||||
            <div class="content-left">
 | 
			
		||||
              <span>در انتظار</span>
 | 
			
		||||
              <div class="d-flex align-items-end mt-2">
 | 
			
		||||
                <h4 class="mb-0 me-2">{{ pending_count }}</h4>
 | 
			
		||||
              </div>
 | 
			
		||||
            </div>
 | 
			
		||||
            <div class="avatar">
 | 
			
		||||
              <span class="avatar-initial rounded bg-label-warning">
 | 
			
		||||
                <i class="bx bx-time bx-sm"></i>
 | 
			
		||||
              </span>
 | 
			
		||||
            </div>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
 | 
			
		||||
  <div class="card">
 | 
			
		||||
    <div class="table-responsive">
 | 
			
		||||
      <table id="requestsTable" class="table table-striped">
 | 
			
		||||
    <div class="card-datatable table-responsive">
 | 
			
		||||
      <table id="requests-table" class="datatables-basic table border-top">
 | 
			
		||||
        <thead>
 | 
			
		||||
          <tr>
 | 
			
		||||
            <th>شناسه</th>
 | 
			
		||||
| 
						 | 
				
			
			@ -46,8 +142,8 @@
 | 
			
		|||
            <th>مرحله فعلی</th>
 | 
			
		||||
            <th>شماره اشتراک آب</th>
 | 
			
		||||
            <th>نماینده</th>
 | 
			
		||||
            <th>درخواستکننده</th>
 | 
			
		||||
            <th>اولویت</th>
 | 
			
		||||
            <th>استان</th>
 | 
			
		||||
            <th>امور</th>
 | 
			
		||||
            <th>وضعیت</th>
 | 
			
		||||
            <th>تاریخ ایجاد</th>
 | 
			
		||||
            <th>عملیات</th>
 | 
			
		||||
| 
						 | 
				
			
			@ -61,9 +157,9 @@
 | 
			
		|||
            <td class="text-primary">{{ inst.current_step.name|default:"--" }}</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>{% if inst.well and inst.well.county %}{{ inst.well.county }}{% else %}-{% endif %}</td>
 | 
			
		||||
            <td>{% if inst.well and inst.well.affairs %}{{ inst.well.affairs }}{% else %}-{% endif %}</td>
 | 
			
		||||
            <td>{{ inst.get_status_display_with_color|safe }}</td>
 | 
			
		||||
            <td>{{ inst.jcreated }}</td>
 | 
			
		||||
            <td>
 | 
			
		||||
              <div class="d-inline-block">
 | 
			
		||||
| 
						 | 
				
			
			@ -126,7 +222,7 @@
 | 
			
		|||
              <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>
 | 
			
		||||
                  <input type="text" class="form-control" id="req_water_sub" name="water_subscription_number" data-field="water_subscription_number" placeholder="مثال: 12345" required>
 | 
			
		||||
                  <button class="btn btn-outline-secondary" type="button" id="btnLookupWell">
 | 
			
		||||
                    بررسی/افزودن چاه
 | 
			
		||||
                  </button>
 | 
			
		||||
| 
						 | 
				
			
			@ -217,7 +313,7 @@
 | 
			
		|||
              <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">
 | 
			
		||||
                  <input type="text" class="form-control" id="rep_national_code" data-field="national_code" placeholder="مثال: 0012345678" maxlength="10" inputmode="numeric" pattern="\d*">
 | 
			
		||||
                  <button class="btn btn-outline-secondary" type="button" id="btnLookupRep">
 | 
			
		||||
                    بررسی/افزودن نماینده
 | 
			
		||||
                  </button>
 | 
			
		||||
| 
						 | 
				
			
			@ -268,7 +364,7 @@
 | 
			
		|||
              <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>
 | 
			
		||||
                <textarea class="form-control" rows="3" id="req_description" name="description"></textarea>
 | 
			
		||||
              </div>
 | 
			
		||||
            </div>
 | 
			
		||||
          </form>
 | 
			
		||||
| 
						 | 
				
			
			@ -361,19 +457,13 @@
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
  $(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');
 | 
			
		||||
    // }
 | 
			
		||||
 | 
			
		||||
    // Initialize DataTable similar to customer_list
 | 
			
		||||
    $('#requests-table').DataTable({
 | 
			
		||||
      pageLength: 10,
 | 
			
		||||
      lengthMenu: [[10, 25, 50, -1], [10, 25, 50, "همه"]],
 | 
			
		||||
      order: [[0, 'desc']],
 | 
			
		||||
      responsive: true,
 | 
			
		||||
    });
 | 
			
		||||
    let currentWellId = null;
 | 
			
		||||
    let currentRepId = null;
 | 
			
		||||
    let wellChecked = false;
 | 
			
		||||
| 
						 | 
				
			
			@ -399,7 +489,7 @@
 | 
			
		|||
      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');
 | 
			
		||||
      const $grp = $el.closest('.input-group, .form-group, .mb-3');
 | 
			
		||||
      if ($grp.length) {
 | 
			
		||||
        $feedback.insertAfter($grp);
 | 
			
		||||
      } else {
 | 
			
		||||
| 
						 | 
				
			
			@ -408,60 +498,49 @@
 | 
			
		|||
      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;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
    // Generic field resolution with small exception map
 | 
			
		||||
    const exceptionMap = {
 | 
			
		||||
      water_subscription_number: '#req_water_sub',
 | 
			
		||||
      national_code: '#rep_national_code',
 | 
			
		||||
      representative: '#rep_national_code'
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    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 'bank_name': return '#id_bank_name';
 | 
			
		||||
        case 'address': return '#id_address';
 | 
			
		||||
        default: return '#id_' + field;
 | 
			
		||||
      }
 | 
			
		||||
    function findFieldSelector(field, context) {
 | 
			
		||||
      const $ctx = context ? $(context) : $('#requestModal');
 | 
			
		||||
      let $el = $ctx.find(`#id_${field}`).first();
 | 
			
		||||
      if ($el.length) return $el;
 | 
			
		||||
      $el = $ctx.find(`[name="${field}"]`).first();
 | 
			
		||||
      if ($el.length) return $el;
 | 
			
		||||
      $el = $ctx.find(`[data-field="${field}"]`).first();
 | 
			
		||||
      if ($el.length) return $el;
 | 
			
		||||
      const ex = exceptionMap[field];
 | 
			
		||||
      return ex ? $(ex) : $();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    function showInlineErrors(errors) {
 | 
			
		||||
      if (!errors) return;
 | 
			
		||||
      let nonFieldWell = '';
 | 
			
		||||
      let nonFieldCustomer = '';
 | 
			
		||||
      // Request-level errors (e.g., process)
 | 
			
		||||
      if (errors.request) {
 | 
			
		||||
        for (const key in errors.request) {
 | 
			
		||||
          const msgs = Array.isArray(errors.request[key]) ? errors.request[key] : [errors.request[key]];
 | 
			
		||||
          if (key === '__all__' || key === 'non_field_errors') { continue; }
 | 
			
		||||
          applyErrorTo(findFieldSelector(key, '#requestForm'), msgs[0]);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      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]);
 | 
			
		||||
          applyErrorTo(findFieldSelector(key, '#wellFormBlock'), 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]);
 | 
			
		||||
          applyErrorTo(findFieldSelector(key, '#repNewFields'), msgs[0]);
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      if (nonFieldWell) setStatus('#wellStatus', nonFieldWell, 'danger');
 | 
			
		||||
| 
						 | 
				
			
			@ -536,7 +615,7 @@
 | 
			
		|||
              $('#remove-file').val('false');
 | 
			
		||||
            // Initialize Persian Date Picker after well form is shown
 | 
			
		||||
            setTimeout(initPersianDatePicker, 100);
 | 
			
		||||
            setStatus('#wellStatus', 'چاه یافت نشد. با ذخیره، ایجاد خواهد شد.', 'danger');
 | 
			
		||||
            setStatus('#wellStatus', 'چاه یافت نشد. اطلاعات چاه را وارد کنید.', 'danger');
 | 
			
		||||
          }
 | 
			
		||||
        })
 | 
			
		||||
        .fail(function(){ setStatus('#wellStatus', 'خطا در بررسی چاه', 'danger'); });
 | 
			
		||||
| 
						 | 
				
			
			@ -594,46 +673,26 @@
 | 
			
		|||
    });
 | 
			
		||||
 | 
			
		||||
    $('#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());
 | 
			
		||||
      clearInlineErrors();
 | 
			
		||||
      // Use form's native FormData - much cleaner!
 | 
			
		||||
      const formData = new FormData(document.getElementById('requestForm'));
 | 
			
		||||
      
 | 
			
		||||
      // Add custom fields that aren't in the form
 | 
			
		||||
      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() || '');
 | 
			
		||||
      formData.append('bank_name', $('#id_bank_name').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]);
 | 
			
		||||
        }
 | 
			
		||||
      
 | 
			
		||||
      // Handle special national_code logic (prefer visible field)
 | 
			
		||||
      const ncField = $('#id_national_code').val();
 | 
			
		||||
      if (ncField) {
 | 
			
		||||
        formData.set('national_code', ncField);
 | 
			
		||||
      } else {
 | 
			
		||||
        formData.set('national_code', $('#rep_national_code').val().trim());
 | 
			
		||||
      }
 | 
			
		||||
      
 | 
			
		||||
      // Handle Persian date conversion
 | 
			
		||||
      const gregorianDate = $('#id_reference_letter_date').attr('data-gregorian');
 | 
			
		||||
      if (gregorianDate) {
 | 
			
		||||
        formData.set('reference_letter_date', gregorianDate);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      const $btn = $(this).prop('disabled', true).text('در حال ذخیره...');
 | 
			
		||||
| 
						 | 
				
			
			@ -652,6 +711,10 @@
 | 
			
		|||
            setTimeout(function(){ location.reload(); }, 1200);
 | 
			
		||||
          }
 | 
			
		||||
        } else {
 | 
			
		||||
          clearInlineErrors();
 | 
			
		||||
          if (resp.errors) {
 | 
			
		||||
            showInlineErrors(resp.errors);
 | 
			
		||||
          }
 | 
			
		||||
          const msg = buildErrorMessage(resp);
 | 
			
		||||
          showToast(msg, 'danger');
 | 
			
		||||
        }
 | 
			
		||||
| 
						 | 
				
			
			@ -659,6 +722,10 @@
 | 
			
		|||
        let msg = 'خطا در ذخیره';
 | 
			
		||||
        try {
 | 
			
		||||
          const resp = JSON.parse(xhr.responseText);
 | 
			
		||||
          clearInlineErrors();
 | 
			
		||||
          if (resp && resp.errors) {
 | 
			
		||||
            showInlineErrors(resp.errors);
 | 
			
		||||
          }
 | 
			
		||||
          msg = buildErrorMessage(resp) || msg;
 | 
			
		||||
        } catch(e) {}
 | 
			
		||||
        showToast(msg, 'danger');
 | 
			
		||||
| 
						 | 
				
			
			@ -715,6 +782,14 @@
 | 
			
		|||
      }
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    // Enforce digit-only and max length for national code input
 | 
			
		||||
    $('#rep_national_code').on('input', function() {
 | 
			
		||||
      const cleaned = (this.value || '').replace(/\D/g, '').slice(0, 10);
 | 
			
		||||
      if (this.value !== cleaned) {
 | 
			
		||||
        this.value = cleaned;
 | 
			
		||||
      }
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    $('#requestModal').on('hidden.bs.modal', function(){
 | 
			
		||||
      $('#requestForm')[0].reset();
 | 
			
		||||
      $('#wellFormBlock').hide();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue