Add progress to req_list
This commit is contained in:
		
							parent
							
								
									7a153c46e6
								
							
						
					
					
						commit
						5ce94214d5
					
				
					 6 changed files with 29261 additions and 27 deletions
				
			
		
							
								
								
									
										
											BIN
										
									
								
								db.sqlite3
									
										
									
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								db.sqlite3
									
										
									
									
									
								
							
										
											Binary file not shown.
										
									
								
							| 
						 | 
					@ -20,6 +20,18 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<!-- Persian Date Picker CSS -->
 | 
					<!-- Persian Date Picker CSS -->
 | 
				
			||||||
<link rel="stylesheet" href="https://unpkg.com/persian-datepicker@latest/dist/css/persian-datepicker.min.css">
 | 
					<link rel="stylesheet" href="https://unpkg.com/persian-datepicker@latest/dist/css/persian-datepicker.min.css">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<style>
 | 
				
			||||||
 | 
					  /* Red styling for removal checkboxes when checked */
 | 
				
			||||||
 | 
					  .removal-checkbox:checked {
 | 
				
			||||||
 | 
					    background-color: #dc3545 !important;
 | 
				
			||||||
 | 
					    border-color: #dc3545 !important;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  .removal-checkbox:checked:focus {
 | 
				
			||||||
 | 
					    box-shadow: 0 0 0 0.25rem rgba(220, 53, 69, 0.25) !important;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					</style>
 | 
				
			||||||
{% endblock %}
 | 
					{% endblock %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
{% block content %}
 | 
					{% block content %}
 | 
				
			||||||
| 
						 | 
					@ -51,10 +63,6 @@
 | 
				
			||||||
                {% else %}
 | 
					                {% else %}
 | 
				
			||||||
                  <button type="button" class="btn btn-primary" disabled>ویرایش گزارش نصب</button>
 | 
					                  <button type="button" class="btn btn-primary" disabled>ویرایش گزارش نصب</button>
 | 
				
			||||||
                {% endif %}
 | 
					                {% endif %}
 | 
				
			||||||
                {% if user_can_approve %}
 | 
					 | 
				
			||||||
                  <button type="button" class="btn btn-success" data-bs-toggle="modal" data-bs-target="#approveModal" {% if step_instance and step_instance.status == 'completed' %}disabled{% endif %}>تایید</button>
 | 
					 | 
				
			||||||
                  <button type="button" class="btn btn-danger" data-bs-toggle="modal" data-bs-target="#rejectModal">رد</button>
 | 
					 | 
				
			||||||
                {% endif %}
 | 
					 | 
				
			||||||
              </div>
 | 
					              </div>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
            <div class="card-body">
 | 
					            <div class="card-body">
 | 
				
			||||||
| 
						 | 
					@ -276,7 +284,7 @@
 | 
				
			||||||
                          {% for qi in quote_items %}
 | 
					                          {% for qi in quote_items %}
 | 
				
			||||||
                          <tr>
 | 
					                          <tr>
 | 
				
			||||||
                            <td>
 | 
					                            <td>
 | 
				
			||||||
                              <input type="checkbox" class="form-check-input" name="rem_{{ qi.item.id }}_type" value="remove" title="حذف در نصب" {% if removed_qty|get_item:qi.item.id %}checked{% endif %}>
 | 
					                              <input type="checkbox" class="form-check-input removal-checkbox" name="rem_{{ qi.item.id }}_type" value="remove" title="حذف در نصب" {% if removed_qty|get_item:qi.item.id %}checked{% endif %}>
 | 
				
			||||||
                              <input type="hidden" name="rem_{{ qi.item.id }}_qty" value="{% if removed_qty|get_item:qi.item.id %}{{ removed_qty|get_item:qi.item.id }}{% else %}{{ qi.quantity }}{% endif %}">
 | 
					                              <input type="hidden" name="rem_{{ qi.item.id }}_qty" value="{% if removed_qty|get_item:qi.item.id %}{{ removed_qty|get_item:qi.item.id }}{% else %}{{ qi.quantity }}{% endif %}">
 | 
				
			||||||
                            </td>
 | 
					                            </td>
 | 
				
			||||||
                            <td>
 | 
					                            <td>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -245,7 +245,7 @@ class ProcessInstance(SluggedModel):
 | 
				
			||||||
            'cancelled': 'warning',
 | 
					            'cancelled': 'warning',
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        color = status_colors.get(self.status, 'secondary')
 | 
					        color = status_colors.get(self.status, 'secondary')
 | 
				
			||||||
        return '<span class="badge bg-{}">{}</span>'.format(color, self.get_status_display())
 | 
					        return '<span class="badge bg-label-{}">{}</span>'.format(color, self.get_status_display())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_priority_display_with_color(self):
 | 
					    def get_priority_display_with_color(self):
 | 
				
			||||||
        """نمایش اولویت با رنگ"""
 | 
					        """نمایش اولویت با رنگ"""
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -144,31 +144,41 @@
 | 
				
			||||||
            <th>نماینده</th>
 | 
					            <th>نماینده</th>
 | 
				
			||||||
            <th>استان</th>
 | 
					            <th>استان</th>
 | 
				
			||||||
            <th>امور</th>
 | 
					            <th>امور</th>
 | 
				
			||||||
 | 
					            <th>پیشرفت</th>
 | 
				
			||||||
            <th>وضعیت</th>
 | 
					            <th>وضعیت</th>
 | 
				
			||||||
            <th>تاریخ ایجاد</th>
 | 
					            <th>تاریخ ایجاد</th>
 | 
				
			||||||
            <th>عملیات</th>
 | 
					            <th>عملیات</th>
 | 
				
			||||||
          </tr>
 | 
					          </tr>
 | 
				
			||||||
        </thead>
 | 
					        </thead>
 | 
				
			||||||
        <tbody>
 | 
					        <tbody>
 | 
				
			||||||
          {% for inst in instances %}
 | 
					          {% for item in instances_with_progress %}
 | 
				
			||||||
          <tr>
 | 
					          <tr>
 | 
				
			||||||
            <td>{{ inst.code }}</td>
 | 
					            <td>{{ item.instance.code }}</td>
 | 
				
			||||||
            <td>{{ inst.process.name }}</td>
 | 
					            <td>{{ item.instance.process.name }}</td>
 | 
				
			||||||
            <td class="text-primary">
 | 
					            <td class="text-primary">
 | 
				
			||||||
              {% if inst.status == 'completed' %}
 | 
					              {% if item.instance.status == 'completed' %}
 | 
				
			||||||
                <a href="{% url 'processes:instance_summary' inst.id %}" class="text-primary">{{ inst.current_step.name|default:"--" }}</a>
 | 
					                <a href="{% url 'processes:instance_summary' item.instance.id %}" class="text-primary">{{ item.instance.current_step.name|default:"--" }}</a>
 | 
				
			||||||
              {% elif inst.current_step %}
 | 
					              {% elif item.instance.current_step %}
 | 
				
			||||||
                <a href="{% url 'processes:instance_steps' inst.id %}" class="text-primary">{{ inst.current_step.name }}</a>
 | 
					                <a href="{% url 'processes:instance_steps' item.instance.id %}" class="text-primary">{{ item.instance.current_step.name }}</a>
 | 
				
			||||||
              {% else %}
 | 
					              {% else %}
 | 
				
			||||||
                --
 | 
					                --
 | 
				
			||||||
              {% endif %}
 | 
					              {% endif %}
 | 
				
			||||||
            </td>
 | 
					            </td>
 | 
				
			||||||
            <td>{{ inst.well.water_subscription_number }}</td>
 | 
					            <td>{{ item.instance.well.water_subscription_number }}</td>
 | 
				
			||||||
            <td>{% if inst.representative %}{{ inst.representative.get_full_name }}{% else %}-{% endif %}</td>
 | 
					            <td>{% if item.instance.representative %}{{ item.instance.representative.get_full_name }}{% else %}-{% endif %}</td>
 | 
				
			||||||
            <td>{% if inst.well and inst.well.county %}{{ inst.well.county }}{% else %}-{% endif %}</td>
 | 
					            <td>{% if item.instance.well and item.instance.well.county %}{{ item.instance.well.county }}{% else %}-{% endif %}</td>
 | 
				
			||||||
            <td>{% if inst.well and inst.well.affairs %}{{ inst.well.affairs }}{% else %}-{% endif %}</td>
 | 
					            <td>{% if item.instance.well and item.instance.well.affairs %}{{ item.instance.well.affairs }}{% else %}-{% endif %}</td>
 | 
				
			||||||
            <td>{{ inst.get_status_display_with_color|safe }}</td>
 | 
					            <td>
 | 
				
			||||||
            <td>{{ inst.jcreated }}</td>
 | 
					              <div class="d-flex align-items-center">
 | 
				
			||||||
 | 
					                <div class="progress me-2" style="width: 80px; height: 6px;">
 | 
				
			||||||
 | 
					                  <div class="progress-bar {% if item.progress_percentage == 100 %}bg-success{% elif item.progress_percentage >= 70 %}bg-info{% elif item.progress_percentage >= 40 %}bg-warning{% else %}bg-secondary{% endif %}" role="progressbar" style="width: {{ item.progress_percentage }}%;" aria-valuenow="{{ item.progress_percentage }}" aria-valuemin="0" aria-valuemax="100">
 | 
				
			||||||
 | 
					                  </div>
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					                <small class="text-muted">{{ item.progress_percentage }}%</small>
 | 
				
			||||||
 | 
					              </div>
 | 
				
			||||||
 | 
					            </td>
 | 
				
			||||||
 | 
					            <td>{{ item.instance.get_status_display_with_color|safe }}</td>
 | 
				
			||||||
 | 
					            <td>{{ item.instance.jcreated }}</td>
 | 
				
			||||||
            <td>
 | 
					            <td>
 | 
				
			||||||
              <div class="d-inline-block">
 | 
					              <div class="d-inline-block">
 | 
				
			||||||
                <a href="javascript:;" class="btn btn-icon dropdown-toggle hide-arrow" data-bs-toggle="dropdown">
 | 
					                <a href="javascript:;" class="btn btn-icon dropdown-toggle hide-arrow" data-bs-toggle="dropdown">
 | 
				
			||||||
| 
						 | 
					@ -176,19 +186,19 @@
 | 
				
			||||||
                </a>
 | 
					                </a>
 | 
				
			||||||
                <ul class="dropdown-menu dropdown-menu-end m-0">
 | 
					                <ul class="dropdown-menu dropdown-menu-end m-0">
 | 
				
			||||||
                  <li>
 | 
					                  <li>
 | 
				
			||||||
                    {% if inst.status == 'completed' %}
 | 
					                    {% if item.instance.status == 'completed' %}
 | 
				
			||||||
                      <a href="{% url 'processes:instance_summary' inst.id %}" class="dropdown-item">
 | 
					                      <a href="{% url 'processes:instance_summary' item.instance.id %}" class="dropdown-item">
 | 
				
			||||||
                        <i class="bx bx-show me-1"></i>مشاهده گزارش
 | 
					                        <i class="bx bx-show me-1"></i>مشاهده گزارش
 | 
				
			||||||
                      </a>
 | 
					                      </a>
 | 
				
			||||||
                    {% else %}
 | 
					                    {% else %}
 | 
				
			||||||
                      <a href="{% url 'processes:instance_steps' inst.id %}" class="dropdown-item">
 | 
					                      <a href="{% url 'processes:instance_steps' item.instance.id %}" class="dropdown-item">
 | 
				
			||||||
                        <i class="bx bx-show me-1"></i>مشاهده جزئیات
 | 
					                        <i class="bx bx-show me-1"></i>مشاهده جزئیات
 | 
				
			||||||
                      </a>
 | 
					                      </a>
 | 
				
			||||||
                    {% endif %}
 | 
					                    {% endif %}
 | 
				
			||||||
                  </li>
 | 
					                  </li>
 | 
				
			||||||
                  <div class="dropdown-divider"></div>
 | 
					                  <div class="dropdown-divider"></div>
 | 
				
			||||||
                  <li>
 | 
					                  <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'))">
 | 
					                    <a href="#" class="dropdown-item text-danger" data-instance-id="{{ item.instance.id }}" data-instance-code="{{ item.instance.code }}" onclick="deleteRequest(this.getAttribute('data-instance-id'), this.getAttribute('data-instance-code'))">
 | 
				
			||||||
                      <i class="bx bx-trash me-1"></i>حذف
 | 
					                      <i class="bx bx-trash me-1"></i>حذف
 | 
				
			||||||
                    </a>
 | 
					                    </a>
 | 
				
			||||||
                  </li>
 | 
					                  </li>
 | 
				
			||||||
| 
						 | 
					@ -198,7 +208,7 @@
 | 
				
			||||||
          </tr>
 | 
					          </tr>
 | 
				
			||||||
          {% empty %}
 | 
					          {% empty %}
 | 
				
			||||||
          <tr>
 | 
					          <tr>
 | 
				
			||||||
            <td colspan="9" class="text-center text-muted">موردی ثبت نشده است</td>
 | 
					            <td colspan="11" class="text-center text-muted">موردی ثبت نشده است</td>
 | 
				
			||||||
          </tr>
 | 
					          </tr>
 | 
				
			||||||
          {% endfor %}
 | 
					          {% endfor %}
 | 
				
			||||||
        </tbody>
 | 
					        </tbody>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -18,16 +18,32 @@ from wells.models import WaterMeterManufacturer
 | 
				
			||||||
@login_required
 | 
					@login_required
 | 
				
			||||||
def request_list(request):
 | 
					def request_list(request):
 | 
				
			||||||
    """نمایش لیست درخواستها با جدول و مدال ایجاد"""
 | 
					    """نمایش لیست درخواستها با جدول و مدال ایجاد"""
 | 
				
			||||||
    instances = ProcessInstance.objects.select_related('well', 'representative', 'requester').filter(is_deleted=False).order_by('-created')
 | 
					    instances = ProcessInstance.objects.select_related('well', 'representative', 'requester').prefetch_related('step_instances__step').filter(is_deleted=False).order_by('-created')
 | 
				
			||||||
    processes = Process.objects.filter(is_active=True)
 | 
					    processes = Process.objects.filter(is_active=True)
 | 
				
			||||||
    manufacturers = WaterMeterManufacturer.objects.all().order_by('name')
 | 
					    manufacturers = WaterMeterManufacturer.objects.all().order_by('name')
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # Calculate progress for each instance
 | 
				
			||||||
 | 
					    instances_with_progress = []
 | 
				
			||||||
 | 
					    for instance in instances:
 | 
				
			||||||
 | 
					        total_steps = instance.process.steps.count()
 | 
				
			||||||
 | 
					        completed_steps = instance.step_instances.filter(status='completed').count()
 | 
				
			||||||
 | 
					        progress_percentage = (completed_steps / total_steps * 100) if total_steps > 0 else 0
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        instances_with_progress.append({
 | 
				
			||||||
 | 
					            'instance': instance,
 | 
				
			||||||
 | 
					            'progress_percentage': round(progress_percentage),
 | 
				
			||||||
 | 
					            'completed_steps': completed_steps,
 | 
				
			||||||
 | 
					            'total_steps': total_steps,
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    # Summary stats for header cards
 | 
					    # Summary stats for header cards
 | 
				
			||||||
    total_count = instances.count()
 | 
					    total_count = instances.count()
 | 
				
			||||||
    completed_count = instances.filter(status='completed').count()
 | 
					    completed_count = instances.filter(status='completed').count()
 | 
				
			||||||
    in_progress_count = instances.filter(status='in_progress').count()
 | 
					    in_progress_count = instances.filter(status='in_progress').count()
 | 
				
			||||||
    pending_count = instances.filter(status='pending').count()
 | 
					    pending_count = instances.filter(status='pending').count()
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    return render(request, 'processes/request_list.html', {
 | 
					    return render(request, 'processes/request_list.html', {
 | 
				
			||||||
        'instances': instances,
 | 
					        'instances_with_progress': instances_with_progress,
 | 
				
			||||||
        'customer_form': CustomerForm(),
 | 
					        'customer_form': CustomerForm(),
 | 
				
			||||||
        'well_form': WellForm(),
 | 
					        'well_form': WellForm(),
 | 
				
			||||||
        'processes': processes,
 | 
					        'processes': processes,
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										29202
									
								
								static/assets/vendor/css/rtl/core-dark.css
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										29202
									
								
								static/assets/vendor/css/rtl/core-dark.css
									
										
									
									
										vendored
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue