diff --git a/.gitignore b/.gitignore index d975f31..77e02cd 100644 --- a/.gitignore +++ b/.gitignore @@ -9,8 +9,8 @@ *.pyc __pycache__/ local_settings.py -*.sqlite3 -db.sqlite3 +# *.sqlite3 +# db.sqlite3 db.sqlite3-journal media #static diff --git a/installations/forms.py b/installations/forms.py index e877b2b..86e7428 100644 --- a/installations/forms.py +++ b/installations/forms.py @@ -20,7 +20,7 @@ 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', 'meter_size', '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', @@ -62,13 +62,6 @@ class InstallationReportForm(forms.ModelForm): 'meter_size': forms.TextInput(attrs={ 'class': 'form-control' }), - 'meter_model': forms.Select(attrs={ - 'class': 'form-select' - }, choices=[ - ('', 'انتخاب کنید'), - ('A', 'A'), - ('B', 'B') - ]), 'discharge_pipe_diameter': forms.NumberInput(attrs={ 'class': 'form-control', 'min': '0', diff --git a/installations/models.py b/installations/models.py index 6cd48bd..6eed7a5 100644 --- a/installations/models.py +++ b/installations/models.py @@ -47,11 +47,6 @@ class InstallationReport(BaseModel): ('volumetric', 'حجمی'), ] meter_type = models.CharField(max_length=20, choices=METER_TYPE_CHOICES, null=True, blank=True, verbose_name='نوع کنتور') - METER_MODEL_CHOICES = [ - ('A', 'A'), - ('B', 'B'), - ] - 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='سایز کنتور') discharge_pipe_diameter = models.PositiveIntegerField(null=True, blank=True, verbose_name='قطر لوله آبده (اینچ)') USAGE_TYPE_CHOICES = [ diff --git a/installations/templates/installations/installation_report_step.html b/installations/templates/installations/installation_report_step.html index 2d14128..d6a7cfc 100644 --- a/installations/templates/installations/installation_report_step.html +++ b/installations/templates/installations/installation_report_step.html @@ -86,11 +86,7 @@

سریال جدید: {{ 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:'-' }}

@@ -283,20 +279,13 @@
{{ form.meter_type.errors.0 }}
{% endif %} -
+
{{ form.meter_size.label_tag }} {{ form.meter_size }} {% if form.meter_size.errors %}
{{ form.meter_size.errors.0 }}
{% endif %}
-
- {{ form.meter_model.label_tag }} - {{ form.meter_model }} - {% if form.meter_model.errors %} -
{{ form.meter_size.errors.0 }}
- {% endif %} -
{{ form.discharge_pipe_diameter.label_tag }} {{ form.discharge_pipe_diameter }} @@ -340,7 +329,7 @@ {% endif %}
- {{ form.water_meter_manufacturer.label_tag }}حجمی + {{ form.water_meter_manufacturer.label_tag }}
{{ form.water_meter_manufacturer }} {{ form.new_manufacturer }} @@ -446,7 +435,7 @@ {% if qi.item.description %}{{ qi.item.description }}{% endif %}
- {{ qi.unit_price|floatformat:0|intcomma:False }} ریال + {{ qi.unit_price|floatformat:0|intcomma:False }} تومان {% if removed_qty|get_item:qi.item.id %}{{ removed_qty|get_item:qi.item.id }}{% else %}{{ qi.quantity }}{% endif %} @@ -485,7 +474,7 @@ {% if it.description %}{{ it.description }}{% endif %}
- {{ it.unit_price|floatformat:0|intcomma:False }} ریال + {{ it.unit_price|floatformat:0|intcomma:False }} تومان {% with add_entry=added_map|get_item:it.id %} @@ -516,7 +505,7 @@ {% if user_is_installer %} {% endif %} - {% if next_step and not edit_mode %} + {% if next_step %} بعدی @@ -770,47 +759,6 @@ } } } - - // Dynamic meter field visibility based on meter type - (function() { - const meterTypeSelect = document.getElementById('{{ form.meter_type.id_for_label }}'); - const meterSizeWrapper = document.getElementById('meter_size_wrapper'); - const meterModelWrapper = document.getElementById('meter_model_wrapper'); - - function updateMeterFields() { - if (!meterTypeSelect) return; - - const selectedType = meterTypeSelect.value; - - if (selectedType === 'smart') { - // Show meter_model, hide meter_size - meterModelWrapper.style.display = ''; - meterSizeWrapper.style.display = 'none'; - // Clear meter_size value when hidden - const meterSizeInput = meterSizeWrapper.querySelector('input, select'); - if (meterSizeInput) meterSizeInput.value = ''; - } else if (selectedType === 'volumetric') { - // Show meter_size, hide meter_model - meterSizeWrapper.style.display = ''; - meterModelWrapper.style.display = 'none'; - // Clear meter_model value when hidden - const meterModelSelect = meterModelWrapper.querySelector('select'); - if (meterModelSelect) meterModelSelect.value = ''; - } else { - // No selection: hide both - meterSizeWrapper.style.display = 'none'; - meterModelWrapper.style.display = 'none'; - } - } - - // Initial update on page load - updateMeterFields(); - - // Update on change - if (meterTypeSelect) { - meterTypeSelect.addEventListener('change', updateMeterFields); - } - })(); {% endblock %} diff --git a/invoices/admin.py b/invoices/admin.py index a53e692..72df296 100644 --- a/invoices/admin.py +++ b/invoices/admin.py @@ -57,13 +57,13 @@ class InvoiceAdmin(SimpleHistoryAdmin): status_display.short_description = "وضعیت" def paid_amount_display(self, obj): - return f"{obj.get_paid_amount():,.0f} ریال" + return f"{obj.get_paid_amount():,.0f} تومان" paid_amount_display.short_description = "مبلغ پرداخت شده" def remaining_amount_display(self, obj): amount = obj.get_remaining_amount() color = "green" if amount <= 0 else "red" - return format_html('{:,.0f} ریال', color, amount) + return format_html('{:,.0f} تومان', color, amount) remaining_amount_display.short_description = "مبلغ باقی‌مانده" @admin.register(Payment) diff --git a/invoices/models.py b/invoices/models.py index b93e4b4..4a48c8c 100644 --- a/invoices/models.py +++ b/invoices/models.py @@ -38,7 +38,7 @@ class Item(NameSlugModel): ordering = ['name'] def __str__(self): - return f"{self.name} - {self.unit_price} ریال" + return f"{self.name} - {self.unit_price} تومان" class Quote(NameSlugModel): """مدل پیش‌فاکتور""" @@ -137,11 +137,11 @@ class Quote(NameSlugModel): return '{}'.format(color, self.get_status_display()) def get_paid_amount(self): - """خالص پرداختی (دریافتی از مشتری منهای پرداختی به مشتری) برای این پیش‌فاکتور بر اساس پرداخت‌های فاکتور مرتبط""" + """مبلغ پرداخت شده برای این پیش‌فاکتور بر اساس پرداخت‌های فاکتور مرتبط""" invoice = Invoice.objects.filter(quote=self).first() if not invoice: return Decimal('0') - return sum((p.amount if p.direction == 'in' else -p.amount) for p in invoice.payments.filter(is_deleted=False).all()) + return sum(p.amount for p in invoice.payments.filter(is_deleted=False).all()) def get_remaining_amount(self): """مبلغ باقی‌مانده بر اساس پرداخت‌ها""" @@ -151,15 +151,6 @@ class Quote(NameSlugModel): remaining = Decimal('0') return remaining - def get_vat_amount(self) -> Decimal: - """محاسبه مبلغ مالیات به صورت جداگانه بر اساس VAT_RATE.""" - base_amount = (self.total_amount or Decimal('0')) - (self.discount_amount or Decimal('0')) - try: - vat_rate = Decimal(str(getattr(settings, 'VAT_RATE', 0))) - except Exception: - vat_rate = Decimal('0') - return base_amount * vat_rate - class QuoteItem(BaseModel): """مدل آیتم‌های پیش‌فاکتور""" quote = models.ForeignKey(Quote, on_delete=models.CASCADE, related_name='items', verbose_name="پیش‌فاکتور") @@ -300,15 +291,6 @@ class Invoice(NameSlugModel): remaining = self.final_amount - paid return remaining - def get_vat_amount(self) -> Decimal: - """محاسبه مبلغ مالیات به صورت جداگانه بر اساس VAT_RATE.""" - base_amount = (self.total_amount or Decimal('0')) - (self.discount_amount or Decimal('0')) - try: - vat_rate = Decimal(str(getattr(settings, 'VAT_RATE', 0))) - except Exception: - vat_rate = Decimal('0') - return base_amount * vat_rate - def get_status_display_with_color(self): """نمایش وضعیت با رنگ""" @@ -383,7 +365,7 @@ class Payment(BaseModel): ordering = ['-payment_date'] def __str__(self): - return f"پرداخت {self.amount} ریال - {self.invoice.name}" + return f"پرداخت {self.amount} تومان - {self.invoice.name}" def save(self, *args, **kwargs): """بروزرسانی مبالغ فاکتور""" diff --git a/invoices/templates/invoices/final_invoice_print.html b/invoices/templates/invoices/final_invoice_print.html index 36e23f0..d9c8333 100644 --- a/invoices/templates/invoices/final_invoice_print.html +++ b/invoices/templates/invoices/final_invoice_print.html @@ -124,8 +124,8 @@ شرح کالا/خدمات توضیحات تعداد - قیمت واحد(ریال) - قیمت کل(ریال) + قیمت واحد(تومان) + قیمت کل(تومان) @@ -144,29 +144,25 @@ - جمع کل(ریال): + جمع کل(تومان): {{ invoice.total_amount|floatformat:0|intcomma:False }} {% if invoice.discount_amount > 0 %} - تخفیف(ریال): + تخفیف(تومان): {{ invoice.discount_amount|floatformat:0|intcomma:False }} {% endif %} - - مالیات بر ارزش افزوده(ریال): - {{ invoice.get_vat_amount|floatformat:0|intcomma:False }} - - مبلغ نهایی (شامل مالیات)(ریال): + مبلغ نهایی (شامل مالیات)(تومان): {{ invoice.final_amount|floatformat:0|intcomma:False }} - پرداختی‌ها(ریال): + پرداختی‌ها(تومان): {{ invoice.get_paid_amount|floatformat:0|intcomma:False }} - مانده(ریال): + مانده(تومان): {{ invoice.get_remaining_amount|floatformat:0|intcomma:False }} diff --git a/invoices/templates/invoices/final_invoice_step.html b/invoices/templates/invoices/final_invoice_step.html index c2e3b64..1d99072 100644 --- a/invoices/templates/invoices/final_invoice_step.html +++ b/invoices/templates/invoices/final_invoice_step.html @@ -68,19 +68,19 @@
مبلغ نهایی (با مالیات)
-
{{ invoice.final_amount|floatformat:0|intcomma:False }} ریال
+
{{ invoice.final_amount|floatformat:0|intcomma:False }} تومان
پرداختی‌ها
-
{{ invoice.get_paid_amount|floatformat:0|intcomma:False }} ریال
+
{{ invoice.get_paid_amount|floatformat:0|intcomma:False }} تومان
مانده
-
{{ invoice.get_remaining_amount|floatformat:0|intcomma:False }} ریال
+
{{ invoice.get_remaining_amount|floatformat:0|intcomma:False }} تومان
@@ -100,8 +100,8 @@ افزوده حذف تعداد نهایی - قیمت واحد (ریال) - قیمت کل (ریال) + قیمت واحد (تومان) + قیمت کل (تومان) @@ -153,27 +153,23 @@ مبلغ کل - {{ invoice.total_amount|floatformat:0|intcomma:False }} ریال + {{ invoice.total_amount|floatformat:0|intcomma:False }} تومان تخفیف - {{ invoice.discount_amount|floatformat:0|intcomma:False }} ریال - - - مالیات بر ارزش افزوده - {{ invoice.get_vat_amount|floatformat:0|intcomma:False }} ریال + {{ invoice.discount_amount|floatformat:0|intcomma:False }} تومان مبلغ نهایی (با مالیات) - {{ invoice.final_amount|floatformat:0|intcomma:False }} ریال + {{ invoice.final_amount|floatformat:0|intcomma:False }} تومان پرداختی‌ها - {{ invoice.get_paid_amount|floatformat:0|intcomma:False }} ریال + {{ invoice.get_paid_amount|floatformat:0|intcomma:False }} تومان مانده - {{ invoice.get_remaining_amount|floatformat:0|intcomma:False }} ریال + {{ invoice.get_remaining_amount|floatformat:0|intcomma:False }} تومان @@ -227,8 +223,8 @@
- - + +
@@ -250,17 +246,8 @@ else { el.classList.add('show'); el.style.display = 'block'; } } function submitSpecialCharge(){ - const form = document.getElementById('specialChargeForm'); - const fd = new FormData(form); + const fd = new FormData(document.getElementById('specialChargeForm')); fd.append('csrfmiddlewaretoken', document.querySelector('input[name=csrfmiddlewaretoken]').value); - // Ensure raw numeric amount is sent - (function ensureRawAmount(){ - const amountInput = document.getElementById('id_charge_amount'); - if (amountInput){ - const raw = (amountInput.getAttribute('data-raw-value') || amountInput.value.replace(/\D/g, '')); - if (raw) fd.set('amount', raw); - } - })(); fetch('{% url "invoices:add_special_charge" instance.id step.id %}', { method: 'POST', body: fd }) .then(r=>r.json()).then(resp=>{ if (resp.success){ @@ -298,8 +285,6 @@ } }).catch(()=> showToast('خطا در ارتباط با سرور', 'danger')); }); - - // Number formatting is handled by number-formatter.js {% endblock %} diff --git a/invoices/templates/invoices/final_settlement_step.html b/invoices/templates/invoices/final_settlement_step.html index 0e7916b..a4767d4 100644 --- a/invoices/templates/invoices/final_settlement_step.html +++ b/invoices/templates/invoices/final_settlement_step.html @@ -60,7 +60,7 @@
- {% if is_broker and invoice.get_remaining_amount != 0 %} + {% if is_broker %}
ثبت تراکنش تسویه
@@ -75,8 +75,8 @@
- - + +
@@ -122,19 +122,19 @@
مبلغ نهایی (با مالیات)
-
{{ invoice.final_amount|floatformat:0|intcomma:False }} ریال
+
{{ invoice.final_amount|floatformat:0|intcomma:False }} تومان
پرداختی‌ها
-
{{ invoice.get_paid_amount|floatformat:0|intcomma:False }} ریال
+
{{ invoice.get_paid_amount|floatformat:0|intcomma:False }} تومان
مانده
-
{{ invoice.get_remaining_amount|floatformat:0|intcomma:False }} ریال
+
{{ invoice.get_remaining_amount|floatformat:0|intcomma:False }} تومان
@@ -166,7 +166,7 @@ {% for p in payments %} {% if p.direction == 'in' %}دریافتی{% else %}پرداختی{% endif %} - {{ p.amount|floatformat:0|intcomma:False }} ریال + {{ p.amount|floatformat:0|intcomma:False }} تومان {{ p.jpayment_date }} {{ p.get_payment_method_display }} {{ p.reference_number|default:'-' }} @@ -193,7 +193,7 @@
- {% if approver_statuses and invoice.get_remaining_amount != 0 and step_instance.status != 'completed' %} + {% if approver_statuses %}
وضعیت تاییدها
@@ -320,7 +320,7 @@
- - + +
@@ -117,19 +117,19 @@
مبلغ نهایی پیش‌فاکتور (با مالیات)
-
{{ totals.final_amount|floatformat:0|intcomma:False }} ریال
+
{{ totals.final_amount|floatformat:0|intcomma:False }} تومان
مبلغ پرداخت‌شده
-
{{ totals.paid_amount|floatformat:0|intcomma:False }} ریال
+
{{ totals.paid_amount|floatformat:0|intcomma:False }} تومان
مانده
-
{{ totals.remaining_amount|floatformat:0|intcomma:False }} ریال
+
{{ totals.remaining_amount|floatformat:0|intcomma:False }} تومان
@@ -153,7 +153,6 @@ - @@ -164,8 +163,7 @@ {% for p in payments %} - - + @@ -177,7 +175,9 @@ {% endif %} {% if is_broker %} - + {% endif %} @@ -301,7 +301,7 @@ {% if not totals.is_fully_paid %} آیا مطمئن هستید که می‌خواهید مرحله را تایید کنید؟ {% else %} @@ -366,12 +366,6 @@ } const form = document.getElementById('formAddPayment'); const fd = buildFormData(form); - // Ensure raw numeric amount is sent - (function ensureRawAmount(){ - const amountInput = document.getElementById('id_amount'); - const raw = (amountInput.getAttribute('data-raw-value') || amountInput.value.replace(/\D/g, '')); - if (raw) fd.set('amount', raw); - })(); // تبدیل تاریخ شمسی به میلادی برای ارسال const persianDateValue = $('#id_payment_date').val(); @@ -389,7 +383,7 @@ setTimeout(() => { window.location.href = resp.redirect; }, 700); } } else { - showToast((resp.message || resp.error || 'خطا در ثبت فیش'), 'danger'); + showToast(resp.message + ':' + resp.error || 'خطا در ثبت فیش', 'danger'); } }).catch(() => showToast('خطا در ارتباط با سرور', 'danger')); }); @@ -466,7 +460,6 @@ } catch (e) { console.error('Error initializing Persian Date Picker:', e); } } })(); - {% endblock %} diff --git a/invoices/templates/invoices/quote_preview_step.html b/invoices/templates/invoices/quote_preview_step.html index 0742094..eeead73 100644 --- a/invoices/templates/invoices/quote_preview_step.html +++ b/invoices/templates/invoices/quote_preview_step.html @@ -200,9 +200,9 @@ - + - + {% endfor %} @@ -213,16 +213,14 @@ {% if quote.discount_amount > 0 %}

تخفیف:

{% endif %} -

مالیات بر ارزش افزوده:

مبلغ نهایی (شامل مالیات):

diff --git a/invoices/templates/invoices/quote_print.html b/invoices/templates/invoices/quote_print.html index 052f579..fc445a6 100644 --- a/invoices/templates/invoices/quote_print.html +++ b/invoices/templates/invoices/quote_print.html @@ -185,8 +185,8 @@ - - + + @@ -203,21 +203,17 @@ - + {% if quote.discount_amount > 0 %} - + {% endif %} - - - - - + diff --git a/invoices/templates/invoices/quote_step.html b/invoices/templates/invoices/quote_step.html index 82ec091..853f250 100644 --- a/invoices/templates/invoices/quote_step.html +++ b/invoices/templates/invoices/quote_step.html @@ -57,7 +57,7 @@
پیش‌فاکتور موجود
{{ existing_quote.name }} | - مبلغ کل (با احتساب مالیات): {{ existing_quote.final_amount|floatformat:0|intcomma:False }} ریال | + مبلغ کل (با احتساب مالیات): {{ existing_quote.final_amount|floatformat:0|intcomma:False }} تومان | وضعیت: {{ existing_quote.get_status_display_with_color|safe }}
@@ -97,7 +97,7 @@ {% if item.description %}{{ item.description }}{% endif %} - +
نوع مبلغ تاریخ پرداخت/سررسید چک روش
{% if p.direction == 'in' %}دریافتی{% else %}پرداختی{% endif %}{{ p.amount|floatformat:0|intcomma:False }} ریال{{ p.amount|floatformat:0|intcomma:False }} تومان {{ p.jpayment_date }} {{ p.get_payment_method_display }} {{ p.reference_number|default:'-' }}
{{ quote_item.item.name }} {{ quote_item.item.description|default:"-" }}{{ quote_item.unit_price|floatformat:0|intcomma:False }} ریال{{ quote_item.unit_price|floatformat:0|intcomma:False }} تومان {{ quote_item.quantity }}{{ quote_item.total_price|floatformat:0|intcomma:False }} ریال{{ quote_item.total_price|floatformat:0|intcomma:False }} تومان
-

{{ quote.total_amount|floatformat:0|intcomma:False }} ریال

+

{{ quote.total_amount|floatformat:0|intcomma:False }} تومان

{% if quote.discount_amount > 0 %} -

{{ quote.discount_amount|floatformat:0|intcomma:False }} ریال

+

{{ quote.discount_amount|floatformat:0|intcomma:False }} تومان

{% endif %} -

{{ quote.get_vat_amount|floatformat:0|intcomma:False }} ریال

-

{{ quote.final_amount|floatformat:0|intcomma:False }} ریال

+

{{ quote.final_amount|floatformat:0|intcomma:False }} تومان

شرح کالا/خدمات توضیحات تعدادقیمت واحد(ریال)قیمت کل(ریال)قیمت واحد(تومان)قیمت کل(تومان)
جمع کل(ریال):جمع کل(تومان): {{ quote.total_amount|floatformat:0|intcomma:False }}
تخفیف(ریال):تخفیف(تومان): {{ quote.discount_amount|floatformat:0|intcomma:False }}
مالیات بر ارزش افزوده(ریال):{{ quote.get_vat_amount|floatformat:0|intcomma:False }}
مبلغ نهایی (با مالیات)(ریال):مبلغ نهایی (با مالیات)(تومان): {{ quote.final_amount|floatformat:0|intcomma:False }}
{{ item.unit_price|floatformat:0|intcomma:False }} ریال{{ item.unit_price|floatformat:0|intcomma:False }} تومان {% if invoice %}
-
مبلغ نهایی
{{ invoice.final_amount|floatformat:0|intcomma:False }} ریال
-
پرداختی‌ها
{{ invoice.get_paid_amount|floatformat:0|intcomma:False }} ریال
-
مانده
{{ invoice.get_remaining_amount|floatformat:0|intcomma:False }} ریال
+
مبلغ نهایی
{{ invoice.final_amount|floatformat:0|intcomma:False }} تومان
+
پرداختی‌ها
{{ invoice.get_paid_amount|floatformat:0|intcomma:False }} تومان
+
مانده
{{ invoice.get_remaining_amount|floatformat:0|intcomma:False }} تومان
@@ -237,7 +237,7 @@ {% for p in payments %} - + diff --git a/processes/templates/processes/request_list.html b/processes/templates/processes/request_list.html index eee1727..9ec7e92 100644 --- a/processes/templates/processes/request_list.html +++ b/processes/templates/processes/request_list.html @@ -245,12 +245,7 @@ {{ item.progress_percentage }}% - +
{% if p.direction == 'in' %}دریافتی{% else %}پرداختی{% endif %}{{ p.amount|floatformat:0|intcomma:False }} ریال{{ p.amount|floatformat:0|intcomma:False }} تومان {{ p.payment_date|date:'Y/m/d' }} {{ p.get_payment_method_display }} {{ p.reference_number|default:'-' }} - {{ item.instance.get_status_display_with_color|safe }} - {% if item.emergency_approved %} - تایید اضطراری - {% endif %} - {{ item.instance.get_status_display_with_color|safe }} {% if item.installation_scheduled_date %}
diff --git a/processes/views.py b/processes/views.py index 372c8e7..e959b2e 100644 --- a/processes/views.py +++ b/processes/views.py @@ -123,17 +123,6 @@ def request_list(request): reference_date = None installation_scheduled_date = reference_date if reference_date and reference_date > sched_date else sched_date - - # Emergency approved flag (final settlement step forced approval) - try: - final_settlement_step = instance.process.steps.filter(order=8).first() - emergency_approved = False - if final_settlement_step: - si = instance.step_instances.filter(step=final_settlement_step).first() - emergency_approved = bool(si and si.status == 'approved') - except Exception: - emergency_approved = False - instances_with_progress.append({ 'instance': instance, 'progress_percentage': round(progress_percentage), @@ -141,7 +130,6 @@ def request_list(request): 'total_steps': total_steps, 'installation_scheduled_date': installation_scheduled_date, 'installation_overdue_days': overdue_days, - 'emergency_approved': emergency_approved, }) # Summary stats for header cards diff --git a/static/assets/js/number-formatter.js b/static/assets/js/number-formatter.js deleted file mode 100644 index 47b2e88..0000000 --- a/static/assets/js/number-formatter.js +++ /dev/null @@ -1,144 +0,0 @@ -/** - * Number Formatter Utility - * Formats numbers with comma separators for better readability - */ - -// Format number with comma separators (e.g., 1234567 -> 1,234,567) -function formatNumber(num) { - if (!num) return ''; - return num.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ','); -} - -// Remove comma separators from formatted number -function unformatNumber(str) { - if (!str) return ''; - return str.replace(/,/g, ''); -} - -// Extract only digits from any string -function extractDigits(str) { - if (!str) return ''; - return str.replace(/\D/g, ''); -} - -// Initialize number formatting for specified input selectors -function initNumberFormatting(selectors) { - if (typeof $ === 'undefined') { - console.warn('jQuery not found. Number formatting requires jQuery.'); - return; - } - - $(document).ready(function() { - selectors.forEach(function(selector) { - // Store cursor position to maintain it after formatting - function setCursorPosition(input, pos) { - if (input.setSelectionRange) { - input.setSelectionRange(pos, pos); - } - } - - $(selector).on('input', function(e) { - let input = $(this); - let inputElement = this; - let value = input.val(); - let cursorPos = inputElement.selectionStart; - - // Extract only digits - let digitsOnly = extractDigits(value); - - // Store raw value - input.attr('data-raw-value', digitsOnly); - - // Format and set the value - let formattedValue = formatNumber(digitsOnly); - input.val(formattedValue); - - // Adjust cursor position - let oldLength = value.length; - let newLength = formattedValue.length; - let newCursorPos = cursorPos + (newLength - oldLength); - - // Make sure cursor position is valid - if (newCursorPos < 0) newCursorPos = 0; - if (newCursorPos > newLength) newCursorPos = newLength; - - // Set cursor position after a short delay - setTimeout(function() { - setCursorPosition(inputElement, newCursorPos); - }, 1); - }); - - // Handle paste events - $(selector).on('paste', function(e) { - let input = $(this); - setTimeout(function() { - let value = input.val(); - let digitsOnly = extractDigits(value); - input.attr('data-raw-value', digitsOnly); - input.val(formatNumber(digitsOnly)); - }, 1); - }); - }); - - // Before form submission, replace formatted values with raw values - $('form').on('submit', function() { - selectors.forEach(function(selector) { - let input = $(selector); - let rawValue = input.attr('data-raw-value'); - if (rawValue) { - input.val(rawValue); - } - }); - }); - }); -} - -// Helper function to get raw value from formatted input -function getRawValue(input) { - return $(input).attr('data-raw-value') || unformatNumber($(input).val()); -} - -// Helper function to set raw value before AJAX submission -function setRawValuesForSubmission(selectors) { - selectors.forEach(function(selector) { - let input = $(selector); - let rawValue = input.attr('data-raw-value'); - if (rawValue) { - input.val(rawValue); - } - }); -} - -// Helper function to restore formatted values after AJAX submission -function restoreFormattedValues(selectors) { - selectors.forEach(function(selector) { - let input = $(selector); - let rawValue = input.attr('data-raw-value'); - if (rawValue) { - input.val(formatNumber(rawValue)); - } - }); -} - -// Auto-initialize for common amount input selectors -$(document).ready(function() { - const commonSelectors = [ - '#id_amount', - '#id_charge_amount', - 'input[name="amount"]', - 'input[name="unit_price"]', - 'input[name="price"]' - ]; - - initNumberFormatting(commonSelectors); - - // Make helper functions globally available for AJAX forms - window.formatNumber = formatNumber; - window.unformatNumber = unformatNumber; - window.getRawValue = getRawValue; - // Avoid name collision causing recursion by aliasing helpers - const __nf_setRawValuesForSubmission = setRawValuesForSubmission; - const __nf_restoreFormattedValues = restoreFormattedValues; - window.setRawValuesForSubmission = function() { __nf_setRawValuesForSubmission(commonSelectors); }; - window.restoreFormattedValues = function() { __nf_restoreFormattedValues(commonSelectors); }; -}); diff --git a/templates/_base.html b/templates/_base.html index 0a41233..94ebdd1 100644 --- a/templates/_base.html +++ b/templates/_base.html @@ -169,8 +169,6 @@ layout-navbar-fixed layout-menu-fixed layout-compact - -