diff --git a/accounts/admin.py b/accounts/admin.py index 1d58e16..d741357 100644 --- a/accounts/admin.py +++ b/accounts/admin.py @@ -33,9 +33,9 @@ class ProfileAdmin(admin.ModelAdmin): @admin.register(Company) class CompanyAdmin(admin.ModelAdmin): - list_display = ['name', 'logo', 'signature', 'address', 'phone'] + list_display = ['name', 'logo', 'signature', 'address', 'phone', 'broker', 'registration_number'] prepopulated_fields = {'slug': ('name',)} search_fields = ['name', 'address', 'phone'] - list_filter = ['is_active'] + list_filter = ['is_active', 'broker'] date_hierarchy = 'created' ordering = ['-created'] \ No newline at end of file diff --git a/accounts/migrations/0002_company_broker.py b/accounts/migrations/0002_company_broker.py new file mode 100644 index 0000000..df12560 --- /dev/null +++ b/accounts/migrations/0002_company_broker.py @@ -0,0 +1,20 @@ +# Generated by Django 5.2.4 on 2025-09-07 13:43 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('accounts', '0001_initial'), + ('locations', '0003_remove_broker_company'), + ] + + operations = [ + migrations.AddField( + model_name='company', + name='broker', + field=models.OneToOneField(blank=True, null=True, on_delete=django.db.models.deletion.SET_NULL, related_name='company', to='locations.broker', verbose_name='کارگزار'), + ), + ] diff --git a/accounts/migrations/0003_company_account_number_company_bank_name_and_more.py b/accounts/migrations/0003_company_account_number_company_bank_name_and_more.py new file mode 100644 index 0000000..6e692ff --- /dev/null +++ b/accounts/migrations/0003_company_account_number_company_bank_name_and_more.py @@ -0,0 +1,34 @@ +# Generated by Django 5.2.4 on 2025-09-07 14:11 + +import django.core.validators +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('accounts', '0002_company_broker'), + ] + + operations = [ + migrations.AddField( + model_name='company', + name='account_number', + field=models.CharField(blank=True, max_length=20, null=True, validators=[django.core.validators.RegexValidator(code='invalid_account_number', message='شماره حساب باید فقط شامل اعداد باشد.', regex='^\\d+$')], verbose_name='شماره حساب'), + ), + migrations.AddField( + model_name='company', + name='bank_name', + field=models.CharField(blank=True, choices=[('mellat', 'بانک ملت'), ('saman', 'بانک سامان'), ('parsian', 'بانک پارسیان'), ('sina', 'بانک سینا'), ('tejarat', 'بانک تجارت'), ('tosee', 'بانک توسعه'), ('iran_zamin', 'بانک ایران زمین'), ('meli', 'بانک ملی'), ('saderat', 'بانک توسعه صادرات'), ('iran_zamin', 'بانک ایران زمین'), ('refah', 'بانک رفاه'), ('eghtesad_novin', 'بانک اقتصاد نوین'), ('pasargad', 'بانک پاسارگاد'), ('other', 'سایر')], max_length=255, null=True, verbose_name='نام بانک'), + ), + migrations.AddField( + model_name='company', + name='card_number', + field=models.CharField(blank=True, max_length=16, null=True, validators=[django.core.validators.RegexValidator(code='invalid_card_number', message='شماره کارت باید فقط شامل اعداد باشد.', regex='^\\d+$')], verbose_name='شماره کارت'), + ), + migrations.AddField( + model_name='company', + name='sheba_number', + field=models.CharField(blank=True, max_length=30, null=True, verbose_name='شماره شبا'), + ), + ] diff --git a/accounts/migrations/0004_company_branch_name.py b/accounts/migrations/0004_company_branch_name.py new file mode 100644 index 0000000..25114e1 --- /dev/null +++ b/accounts/migrations/0004_company_branch_name.py @@ -0,0 +1,18 @@ +# Generated by Django 5.2.4 on 2025-09-07 14:12 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('accounts', '0003_company_account_number_company_bank_name_and_more'), + ] + + operations = [ + migrations.AddField( + model_name='company', + name='branch_name', + field=models.CharField(blank=True, max_length=255, null=True, verbose_name='شعبه بانک'), + ), + ] diff --git a/accounts/migrations/0005_company_registration_number.py b/accounts/migrations/0005_company_registration_number.py new file mode 100644 index 0000000..b38ab10 --- /dev/null +++ b/accounts/migrations/0005_company_registration_number.py @@ -0,0 +1,18 @@ +# Generated by Django 5.2.4 on 2025-09-08 10:10 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('accounts', '0004_company_branch_name'), + ] + + operations = [ + migrations.AddField( + model_name='company', + name='registration_number', + field=models.CharField(blank=True, max_length=255, null=True, verbose_name='شماره ثبت شرکت'), + ), + ] diff --git a/accounts/migrations/0006_company_card_holder_name.py b/accounts/migrations/0006_company_card_holder_name.py new file mode 100644 index 0000000..9228034 --- /dev/null +++ b/accounts/migrations/0006_company_card_holder_name.py @@ -0,0 +1,18 @@ +# Generated by Django 5.2.4 on 2025-09-08 10:32 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ('accounts', '0005_company_registration_number'), + ] + + operations = [ + migrations.AddField( + model_name='company', + name='card_holder_name', + field=models.CharField(blank=True, max_length=255, null=True, verbose_name='نام دارنده کارت'), + ), + ] diff --git a/accounts/models.py b/accounts/models.py index a94311a..937c329 100644 --- a/accounts/models.py +++ b/accounts/models.py @@ -181,11 +181,94 @@ class Profile(BaseModel): class Company(NameSlugModel): - logo = models.ImageField(upload_to='companies/logos', null=True, blank=True, verbose_name='لوگوی شرکت') - signature = models.ImageField(upload_to='companies/signatures', null=True, blank=True, verbose_name='امضای شرکت') - address = models.TextField(null=True, blank=True, verbose_name='آدرس') - phone = models.CharField(max_length=11, null=True, blank=True, verbose_name='شماره تماس') - + logo = models.ImageField( + upload_to='companies/logos', + null=True, + blank=True, + verbose_name='لوگوی شرکت' + ) + signature = models.ImageField( + upload_to='companies/signatures', + null=True, + blank=True, + verbose_name='امضای شرکت' + ) + address = models.TextField( + null=True, + blank=True, + verbose_name='آدرس' + ) + phone = models.CharField( + max_length=11, + null=True, + blank=True, + verbose_name='شماره تماس' + ) + registration_number = models.CharField( + max_length=255, + null=True, + blank=True, + verbose_name='شماره ثبت شرکت' + ) + broker = models.OneToOneField( + Broker, + on_delete=models.SET_NULL, + verbose_name="کارگزار", + null=True, + blank=True, + related_name='company' + ) + card_number = models.CharField( + max_length=16, + null=True, + verbose_name="شماره کارت", + blank=True, + validators=[ + RegexValidator( + regex=r'^\d+$', + message='شماره کارت باید فقط شامل اعداد باشد.', + code='invalid_card_number' + ) + ] + ) + account_number = models.CharField( + max_length=20, + null=True, + verbose_name="شماره حساب", + blank=True, + validators=[ + RegexValidator( + regex=r'^\d+$', + message='شماره حساب باید فقط شامل اعداد باشد.', + code='invalid_account_number' + ) + ] + ) + card_holder_name = models.CharField( + max_length=255, + null=True, + verbose_name="نام دارنده کارت", + blank=True, + ) + sheba_number = models.CharField( + max_length=30, + null=True, + verbose_name="شماره شبا", + blank=True, + ) + bank_name = models.CharField( + max_length=255, + choices=BANK_CHOICES, + null=True, + verbose_name="نام بانک", + blank=True + ) + branch_name = models.CharField( + max_length=255, + null=True, + verbose_name="شعبه بانک", + blank=True + ) class Meta: verbose_name = 'شرکت' verbose_name_plural = 'شرکت‌ها' diff --git a/contracts/templates/contracts/contract_print.html b/contracts/templates/contracts/contract_print.html index bc47f05..d6a6b85 100644 --- a/contracts/templates/contracts/contract_print.html +++ b/contracts/templates/contracts/contract_print.html @@ -2,45 +2,71 @@ - + چاپ قرارداد {{ instance.code }} - + {% load static %} + + + + + + + + + + + +
-
-
-
{{ contract.template.company.name }}
-
{{ contract.template.name }}
-
کد درخواست: {{ instance.code }} | تاریخ: {{ contract.jcreated }}
-
- {% if contract.template.company.logo %} - - {% endif %} - + +
+
تاریخ: {{ contract.jcreated_date }} | کد درخواست: {{ instance.code }}
+
+ {% if instance.broker and instance.broker.company %} + {{ instance.broker.company.name }} + {% elif template.company %} + {{ template.company.name }} + {% else %} + شرکت آب منطقه‌ای + {% endif %} +
+

{{ contract.template.name }}

-
+ +
{{ contract.rendered_body|safe }}

+ +
امضای مشترک
-
+
امضای شرکت
-
- {% if contract.template.company.signature %} - امضای شرکت +
+ {% if instance.broker and instance.broker.company and instance.broker.company.signature %} + امضای شرکت + {% elif contract.template.company and contract.template.company.signature %} + امضای شرکت {% endif %}
diff --git a/contracts/templates/contracts/contract_step.html b/contracts/templates/contracts/contract_step.html index df4fdfc..700d44b 100644 --- a/contracts/templates/contracts/contract_step.html +++ b/contracts/templates/contracts/contract_step.html @@ -19,6 +19,10 @@ {% block content %} {% include '_toasts.html' %} + + +{% instance_info_modal instance %} +
@@ -26,13 +30,18 @@

{{ step.name }}: {{ instance.process.name }}

- اشتراک آب: {{ instance.well.water_subscription_number|default:"-" }} - | نماینده: {{ instance.representative.profile.national_code|default:"-" }} + {% instance_info instance %}
@@ -41,29 +50,32 @@
+
تاریخ: {{ contract.jcreated_date }} | کد درخواست: {{ instance.code }}
+
+ {% if instance.broker and instance.broker.company %} + {{ instance.broker.company.name }} + {% elif template.company %} + {{ template.company.name }} + {% else %} + شرکت آب منطقه‌ای + {% endif %}
+

{{ contract.template.name }}

{% if can_view_contract_body %} - {% if template.company.logo %} -
- لوگوی شرکت -

{{ contract.template.company.name }}

-
{{ contract.template.name }}
-
- {% endif %} - -
تاریخ: {{ contract.jcreated }}

{{ contract.rendered_body|safe }}

امضای مشترک
-
+
امضای شرکت
-
- {% if template.company.signature %} - امضای شرکت +
+ {% if instance.broker and instance.broker.company and instance.broker.company.signature %} + امضای شرکت + {% elif template.company and template.company.signature %} + امضای شرکت {% endif %}
@@ -76,15 +88,23 @@
{% csrf_token %} {% if previous_step %} - قبلی + + + قبلی + {% else %} {% endif %} {% if next_step %} {% if is_broker %} - + {% else %} - بعدی + + بعدی + + {% endif %} {% else %} {% if is_broker %} diff --git a/contracts/views.py b/contracts/views.py index 1949665..7a1788b 100644 --- a/contracts/views.py +++ b/contracts/views.py @@ -2,29 +2,51 @@ from django.shortcuts import render, get_object_or_404, redirect from django.contrib.auth.decorators import login_required from django.urls import reverse from django.utils import timezone +from decimal import Decimal from django.template import Template, Context +from django.utils.safestring import mark_safe from processes.models import ProcessInstance, StepInstance from common.consts import UserRoles from .models import ContractTemplate, ContractInstance +from invoices.models import Invoice, Quote from _helpers.utils import jalali_converter2 +from django.http import JsonResponse def build_contract_context(instance: ProcessInstance) -> dict: representative = instance.representative profile = getattr(representative, 'profile', None) well = instance.well + # Compute prepayment from Quote-linked invoice payments + quote = Quote.objects.filter(process_instance=instance).first() + invoice = Invoice.objects.filter(quote=quote).first() if quote else None + payments_qs = invoice.payments.filter(is_deleted=False, direction='in').all() if invoice else [] + total_paid = sum((p.amount for p in payments_qs), Decimal('0')) + try: + latest_payment_date = max((p.payment_date for p in payments_qs)) if payments_qs else None + except Exception: + latest_payment_date = None + return { - 'customer_full_name': representative.get_full_name() if representative else '', - 'national_code': profile.national_code if profile else '', - 'address': profile.address if profile else '', - 'phone': profile.phone_number_1 if profile else '', - 'phone2': profile.phone_number_2 if profile else '', - 'water_subscription_number': well.water_subscription_number if well else '', - 'electricity_subscription_number': well.electricity_subscription_number if well else '', - 'water_meter_serial_number': well.water_meter_serial_number if well else '', - 'well_power': well.well_power if well else '', - 'request_code': instance.code, - 'today': jalali_converter2(timezone.now()), + 'customer_full_name': mark_safe(f"{representative.get_full_name() if representative else ''}"), + 'registration_number': mark_safe(f"{instance.broker.company.registration_number if instance.broker and instance.broker.company else ''}"), + 'national_code': mark_safe(f"{profile.national_code if profile else ''}"), + 'address': mark_safe(f"{profile.address if profile else ''}"), + 'phone': mark_safe(f"{profile.phone_number_1 if profile else ''}"), + 'phone2': mark_safe(f"{profile.phone_number_2 if profile else ''}"), + 'water_subscription_number': mark_safe(f"{well.water_subscription_number if well else ''}"), + 'electricity_subscription_number': mark_safe(f"{well.electricity_subscription_number if well else ''}"), + 'water_meter_serial_number': mark_safe(f"{well.water_meter_serial_number if well else ''}"), + 'well_power': mark_safe(f"{well.well_power if well else ''}"), + 'request_code': mark_safe(f"{instance.code}"), + 'today': mark_safe(f"{jalali_converter2(timezone.now())}"), + 'company_name': mark_safe(f"{instance.broker.company.name if instance.broker and instance.broker.company else ''}"), + 'city_name': mark_safe(f"{instance.broker.affairs.county.city.name if instance.broker and instance.broker.affairs and instance.broker.affairs.county and instance.broker.affairs.county.city else ''}"), + 'card_number': mark_safe(f"{instance.representative.profile.card_number if instance.representative else ''}"), + 'account_number': mark_safe(f"{instance.representative.profile.account_number if instance.representative else ''}"), + 'bank_name': mark_safe(f"{instance.representative.profile.get_bank_name_display() if instance.representative else ''}"), + 'prepayment_amount': mark_safe(f"{int(total_paid):,}"), + 'prepayment_date': mark_safe(f"{jalali_converter2(latest_payment_date)}") if latest_payment_date else '', } @@ -35,10 +57,7 @@ def contract_step(request, instance_id, step_id): step = get_object_or_404(instance.process.steps, id=step_id) previous_step = instance.process.steps.filter(order__lt=step.order).last() next_step = instance.process.steps.filter(order__gt=step.order).first() - # Access control: - # - INSTALLER: can open step but cannot view contract body (show inline message) - # - Others: can view - # - Only BROKER can submit/complete this step + profile = getattr(request.user, 'profile', None) is_broker = False can_view_contract_body = True @@ -72,7 +91,6 @@ def contract_step(request, instance_id, step_id): # If user submits to go next, only broker can complete and go to next if request.method == 'POST': if not is_broker: - from django.http import JsonResponse return JsonResponse({'success': False, 'message': 'شما مجوز تایید این مرحله را ندارید'}, status=403) StepInstance.objects.update_or_create( process_instance=instance, diff --git a/db.sqlite3 b/db.sqlite3 deleted file mode 100644 index e02ec79..0000000 Binary files a/db.sqlite3 and /dev/null differ diff --git a/invoices/models.py b/invoices/models.py index 10d8f83..ddf1334 100644 --- a/invoices/models.py +++ b/invoices/models.py @@ -7,6 +7,7 @@ from decimal import Decimal from django.utils import timezone from django.core.validators import MinValueValidator from django.conf import settings +from _helpers.utils import jalali_converter2 User = get_user_model() @@ -91,6 +92,7 @@ class Quote(NameSlugModel): verbose_name="ایجاد کننده", related_name='created_quotes' ) + history = HistoricalRecords() class Meta: @@ -371,3 +373,6 @@ class Payment(BaseModel): except Exception: pass return result + + def jpayment_date(self): + return jalali_converter2(self.payment_date) diff --git a/invoices/templates/invoices/final_settlement_step.html b/invoices/templates/invoices/final_settlement_step.html index ca11dec..2335298 100644 --- a/invoices/templates/invoices/final_settlement_step.html +++ b/invoices/templates/invoices/final_settlement_step.html @@ -150,7 +150,7 @@ {% if p.direction == 'in' %}دریافتی{% else %}پرداختی{% endif %} {{ p.amount|floatformat:0|intcomma:False }} تومان - {{ p.payment_date|date:'Y/m/d' }} + {{ p.jpayment_date }} {{ p.get_payment_method_display }} {{ p.reference_number|default:'-' }} @@ -316,11 +316,32 @@ (function initPersianDatePicker(){ if (window.$ && $.fn.persianDatepicker && $('#id_payment_date').length) { $('#id_payment_date').persianDatepicker({ - format: 'YYYY/MM/DD', initialValue: false, autoClose: true, persianDigit: false, observer: true, + format: 'YYYY/MM/DD', + initialValue: false, + autoClose: true, + persianDigit: false, + observer: true, calendar: { persian: { locale: 'fa', leapYearMode: 'astronomical' } }, onSelect: function(unix){ - const g = new window.persianDate(unix).toCalendar('gregorian').format('YYYY-MM-DD'); - $('#id_payment_date').attr('data-gregorian', g); + // تبدیل تاریخ شمسی به میلادی برای ارسال به سرور + 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_payment_date').val(persianDateString); + } else { + // اگر persianDate در دسترس نبود، تاریخ میلادی را نمایش بده + $('#id_payment_date').val(gregorianDateString); + } + + // ذخیره تاریخ میلادی در فیلد مخفی برای ارسال به سرور + $('#id_payment_date').attr('data-gregorian', gregorianDateString); } }); } @@ -328,8 +349,14 @@ function buildForm(){ const fd = new FormData(document.getElementById('formFinalPayment')); - const g = document.getElementById('id_payment_date').getAttribute('data-gregorian'); - if (g) { fd.set('payment_date', g); } + + // تبدیل تاریخ شمسی به میلادی برای ارسال + const persianDateValue = $('#id_payment_date').val(); + const gregorianDateValue = $('#id_payment_date').attr('data-gregorian'); + if (persianDateValue && gregorianDateValue) { + fd.set('payment_date', gregorianDateValue); + } + return fd; } (function(){ diff --git a/invoices/templates/invoices/quote_payment_step.html b/invoices/templates/invoices/quote_payment_step.html index 1b963ee..551420b 100644 --- a/invoices/templates/invoices/quote_payment_step.html +++ b/invoices/templates/invoices/quote_payment_step.html @@ -18,15 +18,16 @@ - + {% endblock %} {% block content %} {% include '_toasts.html' %} + + +{% instance_info_modal instance %} + + {% csrf_token %}
@@ -35,19 +36,21 @@

{{ step.name }}: {{ instance.process.name }}

- اشتراک آب: {{ instance.well.water_subscription_number|default:"-" }} - | نماینده: {{ instance.representative.profile.national_code|default:"-" }} + {% instance_info instance %}
-
+
{% stepper_header instance step %}
@@ -60,7 +63,7 @@
- {% if can_manage_payments %} + {% if is_broker %}
@@ -104,7 +107,7 @@
{% endif %} -
+
وضعیت پیش‌فاکتور
@@ -161,7 +164,7 @@ {% for p in payments %} {{ p.amount|floatformat:0|intcomma:False }} تومان - {{ p.payment_date|date:'Y/m/d' }} + {{ p.jpayment_date }} {{ p.get_payment_method_display }} {{ p.reference_number|default:'-' }} @@ -171,7 +174,7 @@ {% endif %} - {% if can_manage_payments %} + {% if is_broker %} @@ -195,7 +198,7 @@
وضعیت تاییدها
{% if can_approve_reject %}
- +
{% endif %} @@ -356,6 +359,13 @@ } const form = document.getElementById('formAddPayment'); const fd = buildFormData(form); + + // تبدیل تاریخ شمسی به میلادی برای ارسال + const persianDateValue = $('#id_payment_date').val(); + const gregorianDateValue = $('#id_payment_date').attr('data-gregorian'); + if (persianDateValue && gregorianDateValue) { + fd.set('payment_date', gregorianDateValue); + } fetch('{% url "invoices:add_quote_payment" instance.id step.id %}', { method: 'POST', body: fd @@ -419,18 +429,24 @@ 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_payment_date').val(persianDateString); } else { + // اگر persianDate در دسترس نبود، تاریخ میلادی را نمایش بده $('#id_payment_date').val(gregorianDateString); } + + // ذخیره تاریخ میلادی در فیلد مخفی برای ارسال به سرور $('#id_payment_date').attr('data-gregorian', gregorianDateString); } }); diff --git a/invoices/templates/invoices/quote_preview_step.html b/invoices/templates/invoices/quote_preview_step.html index e6e405a..7243f4b 100644 --- a/invoices/templates/invoices/quote_preview_step.html +++ b/invoices/templates/invoices/quote_preview_step.html @@ -24,6 +24,10 @@ {% block content %} {% include '_toasts.html' %} + + +{% instance_info_modal instance %} + {% csrf_token %}
@@ -32,15 +36,17 @@

{{ step.name }}: {{ instance.process.name }}

- اشتراک آب: {{ instance.well.water_subscription_number|default:"-" }} - | نماینده: {{ instance.representative.profile.national_code|default:"-" }} + {% instance_info instance %}
@@ -50,100 +56,116 @@
-
+
-
- - شرکت آب منطقه‌ای + +
+
+ + {% if instance.broker.company %} + لوگوی شرکت + {% else %} + + {% endif %} + +
+
+
+ {% if instance.broker.company %} + {{ instance.broker.company.name }} + {% else %} + شرکت آب منطقه‌ای + {% endif %} +
+ {% if instance.broker.company %} +
+ {% if instance.broker.company.address %} +
{{ instance.broker.company.address }}
+ {% endif %} + {% if instance.broker.affairs.county.city.name %} +
{{ instance.broker.affairs.county.city.name }}، ایران
+ {% endif %} + {% if instance.broker.company.phone %} +
{{ instance.broker.company.phone }}
+ {% endif %} +
+ {% endif %} +
-

دفتر مرکزی، خیابان اصلی

-

تهران، ایران

-

۰۲۱-۱۲۳۴۵۶۷۸

-
-

پیش‌فاکتور #{{ quote.name }}

-
- تاریخ صدور: - {{ quote.jcreated }} + +
+
+
#{{ quote.name }}
-
- معتبر تا: - {{ quote.valid_until|date:"Y/m/d" }} +
+
+ تاریخ صدور: + {{ quote.jcreated_date }} +

-
-
-
-
صادر شده برای:
-

{{ quote.customer.get_full_name }}

- {% if instance.representative.profile %} -

کد ملی: {{ instance.representative.profile.national_code }}

-

{{ instance.representative.profile.address|default:"آدرس نامشخص" }}

-

{{ instance.representative.profile.phone_number_1|default:"" }}

- {% endif %} +
+
+
+
+
+
+ اطلاعات مشترک +
+
+ نام: + {{ quote.customer.get_full_name }} +
+ {% if instance.representative.profile.national_code %} +
+ کد ملی: + {{ instance.representative.profile.national_code }} +
+ {% endif %} + {% if instance.representative.profile.phone_number_1 %} +
+ تلفن: + {{ instance.representative.profile.phone_number_1 }} +
+ {% endif %} + {% if instance.representative.profile.address %} +
+ آدرس: + {{ instance.representative.profile.address }} +
+ {% endif %} + +
+
-
-
اطلاعات چاه:
- - - - - - - - - - - - - - - - - - - - - - - -
شماره اشتراک آب:{{ instance.well.water_subscription_number }}
شماره اشتراک برق:{{ instance.well.electricity_subscription_number|default:"-" }}
سریال کنتور:{{ instance.well.water_meter_serial_number|default:"-" }}
قدرت چاه:{{ instance.well.well_power|default:"-" }}
کد درخواست:{{ instance.code }}
+
+
+
+
+ اطلاعات چاه +
+
+ شماره اشتراک آب: + {{ instance.well.water_subscription_number }} +
+
+ شماره اشتراک برق: + {{ instance.well.electricity_subscription_number|default:"-" }} +
+
+ سریال کنتور: + {{ instance.well.water_meter_serial_number|default:"-" }} +
+
+ قدرت چاه: + {{ instance.well.well_power|default:"-" }} +
+
+
@@ -170,11 +192,6 @@ {% endfor %} -

- صادر کننده: - {{ quote.created_by.get_full_name }} -

- با تشکر از انتخاب شما

جمع کل:

@@ -193,6 +210,72 @@ + +
+
+
+
شرایط و ضوابط:
+
    +
  • + + اعتبار پیش‌فاکتور صادر شده ۴۸ ساعت پس از تاریخ صدور می‌باشد +
  • +
  • + + مبلغ فوق به صورت علی‌الحساب دریافت می‌گردد +
  • +
  • + + این برگه صرفاً جهت اعلام قیمت بوده و ارزش قانونی دیگری ندارد +
  • + {% if instance.broker.company.signature %} +
  • + امضای شرکت +
  • + {% endif %} +
+
+ {% if instance.broker.company %} +
+
اطلاعات پرداخت:
+
+ {% if instance.broker.company.card_number %} +
+ شماره کارت: +
{{ instance.broker.company.card_number }}
+
+ {% endif %} + {% if instance.broker.company.account_number %} +
+ شماره حساب: +
{{ instance.broker.company.account_number }}
+
+ {% endif %} + {% if instance.broker.company.sheba_number %} +
+ شماره شبا: +
{{ instance.broker.company.sheba_number }}
+
+ {% endif %} + {% if instance.broker.company.bank_name %} +
+ بانک: +
{{ instance.broker.company.get_bank_name_display }}
+
+ {% endif %} + {% if instance.broker.company.branch_name %} +
+ شعبه: +
{{ instance.broker.company.branch_name }}
+
+ {% endif %} + +
+ +
+ {% endif %} +
+
{% if quote.notes %} @@ -240,7 +323,7 @@ {% else %} {% if next_step %} + class="btn btn-primary"> مرحله بعد diff --git a/invoices/templates/invoices/quote_print.html b/invoices/templates/invoices/quote_print.html index 7296d12..282ff44 100644 --- a/invoices/templates/invoices/quote_print.html +++ b/invoices/templates/invoices/quote_print.html @@ -5,8 +5,24 @@ پیش‌فاکتور {{ quote.name }} - {{ instance.code }} - - + {% load static %} + {% load humanize %} + + + + + + + + + + + + + + + +