diff --git a/certificates/templates/certificates/step.html b/certificates/templates/certificates/step.html
index f8249cb..917183a 100644
--- a/certificates/templates/certificates/step.html
+++ b/certificates/templates/certificates/step.html
@@ -2,6 +2,7 @@
{% load static %}
{% load processes_tags %}
{% load humanize %}
+ {% load common_tags %}
{% load accounts_tags %}
{% block sidebar %}
@@ -73,21 +74,24 @@
diff --git a/certificates/views.py b/certificates/views.py
index 26a5d6f..68ca5b0 100644
--- a/certificates/views.py
+++ b/certificates/views.py
@@ -83,7 +83,7 @@ def certificate_step(request, instance_id, step_id):
messages.error(request, 'مانده فاکتور باید صفر باشد')
return redirect('processes:request_list')
- template = CertificateTemplate.objects.filter(is_active=True).order_by('-created').first()
+ template = CertificateTemplate.objects.filter(is_active=True, company=instance.broker.company).order_by('-created').first()
if not template:
return render(request, 'certificates/missing.html', {})
diff --git a/db.sqlite3 b/db.sqlite3
index b4e650c..4bedcf3 100644
Binary files a/db.sqlite3 and b/db.sqlite3 differ
diff --git a/installations/admin.py b/installations/admin.py
index fc78615..b32240b 100644
--- a/installations/admin.py
+++ b/installations/admin.py
@@ -24,11 +24,13 @@ class InstallationReportAdmin(admin.ModelAdmin):
list_display = (
'assignment', 'visited_date', 'meter_type', 'meter_size', 'water_meter_manufacturer',
'discharge_pipe_diameter', 'usage_type', 'exploitation_license_number',
- 'motor_power', 'pre_calibration_flow_rate', 'post_calibration_flow_rate',
+ 'motor_power', 'flow_rate', 'meter_reading', 'meter_charge', 'meter_charge_expiration_date',
+ 'pump_type', 'licence_working_hour',
'new_water_meter_serial', 'seal_number', 'sim_number',
+ 'is_panel_sealed', 'is_panel_cut', 'is_disconnection_done',
'is_meter_suspicious', 'approved', 'created'
)
- list_filter = ('is_meter_suspicious', 'approved', 'visited_date', 'meter_type', 'usage_type', 'water_meter_manufacturer')
+ list_filter = ('is_meter_suspicious', 'is_panel_sealed', 'is_panel_cut', 'is_disconnection_done', 'approved', 'visited_date', 'meter_type', 'pump_type', 'usage_type', 'water_meter_manufacturer')
search_fields = (
'assignment__process_instance__code', 'new_water_meter_serial', 'seal_number', 'exploitation_license_number', 'sim_number'
)
@@ -43,13 +45,16 @@ class InstallationReportAdmin(admin.ModelAdmin):
)
}),
('مشخصات هیدرولیکی', {
- 'fields': ('discharge_pipe_diameter', 'pre_calibration_flow_rate', 'post_calibration_flow_rate')
+ 'fields': ('discharge_pipe_diameter', 'flow_rate', 'meter_reading', 'meter_charge', 'meter_charge_expiration_date')
}),
('کاربری و مجوز', {
'fields': ('usage_type', 'exploitation_license_number')
}),
('توان و محرکه', {
- 'fields': ('driving_force', 'motor_power')
+ 'fields': ('driving_force', 'motor_power', 'pump_type', 'licence_working_hour')
+ }),
+ ('وضعیت تابلو/قطع', {
+ 'fields': ('is_panel_sealed', 'is_panel_cut', 'is_disconnection_done')
}),
('توضیحات', {
'fields': ('description',)
diff --git a/installations/forms.py b/installations/forms.py
index b8be2b0..d2483e7 100644
--- a/installations/forms.py
+++ b/installations/forms.py
@@ -20,10 +20,12 @@ class InstallationReportForm(forms.ModelForm):
model = InstallationReport
fields = [
'visited_date', 'new_water_meter_serial', 'seal_number',
- 'utm_x', 'utm_y', 'meter_type', 'meter_size', 'meter_model',
+ 'utm_x', 'utm_y', 'meter_type',
'discharge_pipe_diameter', 'usage_type', 'exploitation_license_number',
- 'motor_power', 'pre_calibration_flow_rate', 'post_calibration_flow_rate',
- 'water_meter_manufacturer', 'sim_number', 'driving_force',
+ 'motor_power', 'flow_rate', 'meter_charge_expiration_date',
+ 'pump_type', 'licence_working_hour',
+ 'is_panel_cut',
+ 'water_meter_manufacturer',
'is_meter_suspicious', 'description'
]
@@ -59,16 +61,7 @@ class InstallationReportForm(forms.ModelForm):
('smart', 'هوشمند (آب و برق)'),
('volumetric', 'حجمی')
]),
- 'meter_size': forms.TextInput(attrs={
- 'class': 'form-control'
- }),
- 'meter_model': forms.Select(attrs={
- 'class': 'form-select'
- }, choices=[
- ('', 'انتخاب کنید'),
- ('direct', 'مستقیم'),
- ('indirect', 'غیرمستقیم')
- ]),
+ # meter_size and meter_model removed from form UI
'discharge_pipe_diameter': forms.NumberInput(attrs={
'class': 'form-control',
'required': True
@@ -90,35 +83,41 @@ class InstallationReportForm(forms.ModelForm):
'class': 'form-control',
'required': True
}),
- 'pre_calibration_flow_rate': forms.NumberInput(attrs={
+ 'flow_rate': forms.NumberInput(attrs={
'class': 'form-control',
'min': '0',
'step': '0.0001',
- 'required': True
}),
- 'post_calibration_flow_rate': forms.NumberInput(attrs={
+ # meter_reading and meter_charge removed from form UI
+ 'meter_charge_expiration_date': forms.DateInput(attrs={
+ 'type': 'date',
'class': 'form-control',
- 'min': '0',
- 'step': '0.0001',
- 'required': True
}),
'water_meter_manufacturer': forms.Select(attrs={
'class': 'form-select',
'id': 'id_water_meter_manufacturer',
'required': True
}),
- 'sim_number': forms.TextInput(attrs={
- 'class': 'form-control',
+ # sim_number and driving_force removed from form UI
+ 'pump_type': forms.Select(attrs={
+ 'class': 'form-select',
'required': True
}),
- 'driving_force': forms.TextInput(attrs={
+ 'licence_working_hour': forms.NumberInput(attrs={
'class': 'form-control',
+ 'min': '0',
+ 'step': '1',
'required': True
}),
'is_meter_suspicious': forms.CheckboxInput(attrs={
'class': 'form-check-input',
'id': 'id_is_meter_suspicious',
}),
+ # is_panel_sealed removed from form UI
+ 'is_panel_cut': forms.CheckboxInput(attrs={
+ 'class': 'form-check-input',
+ }),
+ # is_disconnection_done removed from form UI
'description': forms.Textarea(attrs={
'class': 'form-control',
'rows': 3
@@ -127,22 +126,22 @@ class InstallationReportForm(forms.ModelForm):
labels = {
'visited_date': 'تاریخ مراجعه',
- 'new_water_meter_serial': 'سریال کنتور جدید',
+ 'new_water_meter_serial': 'سریال کنتور',
'seal_number': 'شماره پلمپ',
'utm_x': 'UTM X',
'utm_y': 'UTM Y',
'meter_type': 'نوع کنتور',
- 'meter_size': 'سایز کنتور',
'discharge_pipe_diameter': 'قطر لوله آبده (اینچ)',
'usage_type': 'نوع مصرف',
'exploitation_license_number': 'شماره پروانه بهرهبرداری',
- 'motor_power': 'قدرت موتور (کیلووات ساعت)',
- 'pre_calibration_flow_rate': 'دبی قبل از کالیبراسیون (لیتر بر ثانیه)',
- 'post_calibration_flow_rate': 'دبی بعد از کالیبراسیون (لیتر بر ثانیه)',
+ 'motor_power': 'توان مصرفی (کیلووات)',
+ 'flow_rate': 'دبی بعد از کالیبراسیون (لیتر بر ثانیه)',
+ 'meter_charge_expiration_date': 'تاریخ پایان اعتبار شارژ',
+ 'pump_type': 'نوع پمپ',
+ 'licence_working_hour': 'ساعت کارکرد پروانه',
'water_meter_manufacturer': 'شرکت سازنده کنتور',
- 'sim_number': 'شماره سیمکارت',
- 'driving_force': 'نیرو محرکه چاه',
'is_meter_suspicious': 'کنتور مشکوک است',
+ 'is_panel_cut': 'تابلو قطع',
'description': 'توضیحات'
}
diff --git a/installations/migrations/0012_installationreport_flow_rate_and_more.py b/installations/migrations/0012_installationreport_flow_rate_and_more.py
new file mode 100644
index 0000000..1f3f29b
--- /dev/null
+++ b/installations/migrations/0012_installationreport_flow_rate_and_more.py
@@ -0,0 +1,50 @@
+# Generated by Django 5.2.4 on 2025-10-27 03:42
+
+import django.core.validators
+from decimal import Decimal
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('installations', '0011_alter_installationreport_discharge_pipe_diameter'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='installationreport',
+ name='flow_rate',
+ field=models.DecimalField(blank=True, decimal_places=4, max_digits=10, null=True, verbose_name='(لیتر بر ثانیه)دبی'),
+ ),
+ migrations.AddField(
+ model_name='installationreport',
+ name='is_disconnection_done',
+ field=models.BooleanField(default=False, verbose_name='انجام عملیات قطع'),
+ ),
+ migrations.AddField(
+ model_name='installationreport',
+ name='is_panel_cut',
+ field=models.BooleanField(default=False, verbose_name='تابلو قطع'),
+ ),
+ migrations.AddField(
+ model_name='installationreport',
+ name='is_panel_sealed',
+ field=models.BooleanField(default=False, verbose_name='پلمپ تابلو'),
+ ),
+ migrations.AddField(
+ model_name='installationreport',
+ name='meter_charge',
+ field=models.DecimalField(blank=True, decimal_places=4, max_digits=10, null=True, validators=[django.core.validators.MinValueValidator(Decimal('0'))], verbose_name='شارژ کنتور (متر مکعب)'),
+ ),
+ migrations.AddField(
+ model_name='installationreport',
+ name='meter_charge_expiration_date',
+ field=models.DateField(blank=True, null=True, verbose_name='تاریخ پایان اعتبار شارژ'),
+ ),
+ migrations.AddField(
+ model_name='installationreport',
+ name='meter_reading',
+ field=models.DecimalField(blank=True, decimal_places=4, max_digits=10, null=True, validators=[django.core.validators.MinValueValidator(Decimal('0'))], verbose_name='عدد کنتور (متر مکعب)'),
+ ),
+ ]
diff --git a/installations/migrations/0013_remove_installationreport_post_calibration_flow_rate_and_more.py b/installations/migrations/0013_remove_installationreport_post_calibration_flow_rate_and_more.py
new file mode 100644
index 0000000..31f653d
--- /dev/null
+++ b/installations/migrations/0013_remove_installationreport_post_calibration_flow_rate_and_more.py
@@ -0,0 +1,21 @@
+# Generated by Django 5.2.4 on 2025-10-27 03:47
+
+from django.db import migrations
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('installations', '0012_installationreport_flow_rate_and_more'),
+ ]
+
+ operations = [
+ migrations.RemoveField(
+ model_name='installationreport',
+ name='post_calibration_flow_rate',
+ ),
+ migrations.RemoveField(
+ model_name='installationreport',
+ name='pre_calibration_flow_rate',
+ ),
+ ]
diff --git a/installations/migrations/0014_installationreport_licence_working_hour_and_more.py b/installations/migrations/0014_installationreport_licence_working_hour_and_more.py
new file mode 100644
index 0000000..f77fb6a
--- /dev/null
+++ b/installations/migrations/0014_installationreport_licence_working_hour_and_more.py
@@ -0,0 +1,38 @@
+# Generated by Django 5.2.4 on 2025-11-23 08:57
+
+from django.db import migrations, models
+
+
+class Migration(migrations.Migration):
+
+ dependencies = [
+ ('installations', '0013_remove_installationreport_post_calibration_flow_rate_and_more'),
+ ]
+
+ operations = [
+ migrations.AddField(
+ model_name='installationreport',
+ name='licence_working_hour',
+ field=models.PositiveIntegerField(blank=True, null=True, verbose_name='ساعت کارکرد پروانه'),
+ ),
+ migrations.AddField(
+ model_name='installationreport',
+ name='pump_type',
+ field=models.CharField(blank=True, choices=[('shaft_sleeve', 'شفت و غلاف'), ('submersible', 'شناور')], max_length=20, null=True, verbose_name='نوع پمپ'),
+ ),
+ migrations.AlterField(
+ model_name='installationreport',
+ name='flow_rate',
+ field=models.DecimalField(blank=True, decimal_places=4, max_digits=10, null=True, verbose_name='(لیتر بر ثانیه)دبی بعد از کالیبراسیون'),
+ ),
+ migrations.AlterField(
+ model_name='installationreport',
+ name='motor_power',
+ field=models.DecimalField(blank=True, decimal_places=4, max_digits=10, null=True, verbose_name='(کیلووات)توان مصرفی'),
+ ),
+ migrations.AlterField(
+ model_name='installationreport',
+ name='new_water_meter_serial',
+ field=models.CharField(blank=True, max_length=50, null=True, verbose_name='سریال کنتور'),
+ ),
+ ]
diff --git a/installations/models.py b/installations/models.py
index c7d7e31..9761ae3 100644
--- a/installations/models.py
+++ b/installations/models.py
@@ -41,7 +41,7 @@ class InstallationReport(BaseModel):
related_name='reports', verbose_name='اختصاص'
)
visited_date = models.DateField(null=True, blank=True, verbose_name='تاریخ مراجعه')
- new_water_meter_serial = models.CharField(max_length=50, null=True, blank=True, verbose_name='سریال کنتور جدید')
+ new_water_meter_serial = models.CharField(max_length=50, null=True, blank=True, verbose_name='سریال کنتور')
seal_number = models.CharField(max_length=50, null=True, blank=True, verbose_name='شماره پلمپ')
is_meter_suspicious = models.BooleanField(default=False, verbose_name='کنتور مشکوک است؟')
METER_TYPE_CHOICES = [
@@ -55,6 +55,18 @@ class InstallationReport(BaseModel):
]
meter_model = models.CharField(max_length=20, choices=METER_MODEL_CHOICES, null=True, blank=True, verbose_name='مدل کنتور')
meter_size = models.CharField(max_length=50, null=True, blank=True, verbose_name='سایز کنتور')
+ meter_reading = models.DecimalField(max_digits=10, decimal_places=4, null=True, blank=True, validators=[MinValueValidator(Decimal('0'))], verbose_name='عدد کنتور (متر مکعب)')
+ meter_charge = models.DecimalField(max_digits=10, decimal_places=4, null=True, blank=True, validators=[MinValueValidator(Decimal('0'))], verbose_name='شارژ کنتور (متر مکعب)')
+ meter_charge_expiration_date = models.DateField(null=True, blank=True, verbose_name='تاریخ پایان اعتبار شارژ')
+ is_panel_sealed = models.BooleanField(default=False, verbose_name='پلمپ تابلو')
+ is_panel_cut = models.BooleanField(default=False, verbose_name='تابلو قطع')
+ is_disconnection_done = models.BooleanField(default=False, verbose_name='انجام عملیات قطع')
+ PUMP_TYPE_CHOICES = [
+ ('shaft_sleeve', 'شفت و غلاف'),
+ ('submersible', 'شناور'),
+ ]
+ pump_type = models.CharField(max_length=20, choices=PUMP_TYPE_CHOICES, null=True, blank=True, verbose_name='نوع پمپ')
+ licence_working_hour = models.PositiveIntegerField(null=True, blank=True, verbose_name='ساعت کارکرد پروانه')
discharge_pipe_diameter = models.DecimalField(max_digits=10, decimal_places=4, null=True, blank=True, verbose_name='قطر لوله آبده (اینچ)')
USAGE_TYPE_CHOICES = [
('domestic', 'شرب و خدمات'),
@@ -63,9 +75,8 @@ class InstallationReport(BaseModel):
]
usage_type = models.CharField(max_length=20, choices=USAGE_TYPE_CHOICES, null=True, verbose_name='نوع مصرف')
exploitation_license_number = models.CharField(max_length=50, verbose_name='شماره پروانه بهرهبرداری چاه')
- motor_power = models.DecimalField(max_digits=10, decimal_places=4, null=True, blank=True, verbose_name='(کیلووات ساعت) قدرت موتور')
- pre_calibration_flow_rate = models.DecimalField(max_digits=10, decimal_places=4, null=True, blank=True, verbose_name='(لیتر بر ثانیه)دبی قبل از کالیبراسیون')
- post_calibration_flow_rate = models.DecimalField(max_digits=10, decimal_places=4, null=True, blank=True, verbose_name='(لیتر بر ثانیه)دبی بعد از کالیبراسیون')
+ motor_power = models.DecimalField(max_digits=10, decimal_places=4, null=True, blank=True, verbose_name='(کیلووات)توان مصرفی')
+ flow_rate = models.DecimalField(max_digits=10, decimal_places=4, null=True, blank=True, verbose_name='(لیتر بر ثانیه)دبی بعد از کالیبراسیون')
water_meter_manufacturer = models.ForeignKey('wells.WaterMeterManufacturer', on_delete=models.SET_NULL, null=True, blank=True, verbose_name='شرکت سازنده کنتور آب')
sim_number = models.CharField(max_length=20, null=True, blank=True, verbose_name='شماره سیمکارت')
driving_force = models.CharField(max_length=50, null=True, blank=True, verbose_name='نیرو محرکه چاه')
diff --git a/installations/templates/installations/installation_report_step.html b/installations/templates/installations/installation_report_step.html
index 3246dea..9aa11c3 100644
--- a/installations/templates/installations/installation_report_step.html
+++ b/installations/templates/installations/installation_report_step.html
@@ -146,28 +146,23 @@
تاریخ مراجعه: {{ report.visited_date|to_jalali|default:'-' }}
-
سریال جدید: {{ report.new_water_meter_serial|default:'-' }}
+
سریال کنتور: {{ report.new_water_meter_serial|default:'-' }}
شماره پلمپ: {{ report.seal_number|default:'-' }}
نوع کنتور: {{ report.get_meter_type_display|default:'-' }}
- {% if report.meter_type == 'smart' %}
-
مدل کنتور: {{ report.get_meter_model_display|default:'-' }}
- {% else %}
-
سایز کنتور: {{ report.meter_size|default:'-' }}
- {% endif %}
قطر لوله آبده (اینچ): {{ report.discharge_pipe_diameter|default:'-' }}
-
سازنده کنتور: {{ report.water_meter_manufacturer|default:'-' }}
-
شماره سیمکارت: {{ report.sim_number|default:'-' }}
-
نیرو محرکه چاه: {{ report.driving_force|default:'-' }}
+
شرکت سازنده کنتور: {{ report.water_meter_manufacturer.name|default:'-' }}
+
پایان اعتبار شارژ: {{ report.meter_charge_expiration_date|to_jalali|default:'-' }}
+
کنتور مشکوک: {{ report.is_meter_suspicious|yesno:'بله,خیر' }}
-
کنتور مشکوک: {{ report.is_meter_suspicious|yesno:'بله,خیر' }}
-
UTM X: {{ report.utm_x|default:'-' }}
-
UTM Y: {{ report.utm_y|default:'-' }}
+
UTM X: {{ report.utm_x|default:'-' }} Y: {{ report.utm_y|default:'-' }}
نوع مصرف: {{ report.get_usage_type_display|default:'-' }}
شماره پروانه بهرهبرداری: {{ report.exploitation_license_number|default:'-' }}
-
قدرت موتور(کیلووات ساعت): {{ report.motor_power|default:'-' }}
-
دبی قبل کالیبراسیون(لیتر/ثانیه): {{ report.pre_calibration_flow_rate|default:'-' }}
-
دبی بعد کالیبراسیون(لیتر/ثانیه): {{ report.post_calibration_flow_rate|default:'-' }}
+
توان مصرفی (کیلووات): {{ report.motor_power|default:'-' }}
+
دبی بعد از کالیبراسیون (لیتر بر ثانیه): {{ report.flow_rate|default:'-' }}
+
نوع پمپ: {{ report.get_pump_type_display|default:'-' }}
+
ساعت کارکرد پروانه: {{ report.licence_working_hour|default:'-' }}
+
تابلو قطع: {{ report.is_panel_cut|yesno:'بله,خیر' }}
@@ -346,20 +341,7 @@
{{ form.meter_type.errors.0 }}
{% endif %}
{{ form.discharge_pipe_diameter.label_tag }}
{{ form.discharge_pipe_diameter }}
@@ -389,21 +371,23 @@
{% endif %}
{% endif %}
- {% if latest_report.pre_calibration_flow_rate %}
+ {% if latest_report.flow_rate %}
{% endif %}
- {% if latest_report.post_calibration_flow_rate %}
+ {# meter_reading and meter_charge removed from summary UI #}
+ {% if latest_report.meter_charge_expiration_date %}
+ {% endif %}
+ {# is_panel_sealed removed from summary UI #}
+
+ {# is_disconnection_done removed from summary UI #}
+ {% if latest_report.pump_type %}
+
+ {% endif %}
+ {% if latest_report.licence_working_hour %}
+
diff --git a/processes/utils.py b/processes/utils.py
index 717c0fc..9491d9a 100644
--- a/processes/utils.py
+++ b/processes/utils.py
@@ -21,7 +21,7 @@ def scope_instances_queryset(user, queryset=None):
if profile.has_role(UserRoles.BROKER):
return qs.filter(broker=profile.broker)
if profile.has_role(UserRoles.ACCOUNTANT) or profile.has_role(UserRoles.MANAGER) or profile.has_role(UserRoles.WATER_RESOURCE_MANAGER):
- return qs.filter(broker__affairs__county=profile.county)
+ return qs.filter(broker__affairs__county__city=profile.county.city)
if profile.has_role(UserRoles.ADMIN):
return qs
# if profile.has_role(UserRoles.WATER_RESOURCE_MANAGER) or profile.has_role(UserRoles.HEADQUARTER):
@@ -70,7 +70,7 @@ def scope_wells_queryset(user, queryset=None):
if profile.has_role(UserRoles.BROKER):
return qs.filter(broker=profile.broker)
if profile.has_role(UserRoles.ACCOUNTANT) or profile.has_role(UserRoles.MANAGER) or profile.has_role(UserRoles.WATER_RESOURCE_MANAGER):
- return qs.filter(broker__affairs__county=profile.county)
+ return qs.filter(broker__affairs__county__city=profile.county.city)
if profile.has_role(UserRoles.INSTALLER):
# Wells that have instances assigned to this installer
from installations.models import InstallationAssignment
@@ -103,7 +103,7 @@ def scope_customers_queryset(user, queryset=None):
if profile.has_role(UserRoles.BROKER):
return qs.filter(broker=profile.broker)
if profile.has_role(UserRoles.ACCOUNTANT) or profile.has_role(UserRoles.MANAGER) or profile.has_role(UserRoles.WATER_RESOURCE_MANAGER):
- return qs.filter(county=profile.county)
+ return qs.filter(county__city=profile.county.city)
if profile.has_role(UserRoles.INSTALLER):
# Customers that are representatives of instances assigned to this installer
from installations.models import InstallationAssignment