agdar/finance/templates/finance/package_form.html
Marwan Alwali f6329ffa10 update
2025-11-04 13:44:58 +03:00

340 lines
15 KiB
HTML

{% extends "base.html" %}
{% load i18n static crispy_forms_tags %}
{% block title %}{% if form.instance.pk %}{% trans "Edit Package" %}{% else %}{% trans "New Package" %}{% endif %} - Tenhal{% endblock %}
{% block css %}
<link href="{% static 'plugins/select2/css/select2.min.css' %}" rel="stylesheet" />
<style>
.form-control, .form-select {
border-radius: 0.375rem;
border: 1px solid #dee2e6;
padding: 0.5rem 0.75rem;
}
.form-control:focus, .form-select:focus {
border-color: #007bff;
box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);
}
.card {
border-radius: 0.5rem;
box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
}
.card-header {
border-radius: 0.5rem 0.5rem 0 0 !important;
}
.form-check-input {
margin-top: 0.3rem;
}
.select2-container--default .select2-selection--single {
border: 1px solid #dee2e6;
border-radius: 0.375rem;
min-height: 38px;
}
.select2-container--default.select2-container--focus .select2-selection--single {
border-color: #007bff;
box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);
}
.service-row {
background-color: #f8f9fa;
border: 1px solid #dee2e6;
border-radius: 0.375rem;
padding: 1rem;
margin-bottom: 0.75rem;
}
.service-row:hover {
background-color: #e9ecef;
}
.btn-remove-service {
padding: 0.25rem 0.5rem;
font-size: 0.875rem;
}
</style>
{% endblock %}
{% block content %}
<div class="container-fluid">
<div class="d-flex justify-content-between align-items-center mb-3">
<div>
<h1 class="page-header mb-0">
<i class="fas fa-box me-2"></i>
{% if form.instance.pk %}{% trans "Edit Package" %}{% else %}{% trans "New Package" %}{% endif %}
</h1>
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="{% url 'core:dashboard' %}">{% trans "Dashboard" %}</a></li>
<li class="breadcrumb-item"><a href="{% url 'finance:package_list' %}">{% trans "Packages" %}</a></li>
<li class="breadcrumb-item active">{% if form.instance.pk %}{% trans "Edit" %}{% else %}{% trans "New" %}{% endif %}</li>
</ol>
</nav>
</div>
</div>
<form method="post" id="packageForm">
{% csrf_token %}
<div class="row">
<div class="col-lg-8">
<div class="card mb-3">
<div class="card-header bg-primary text-white">
<h5 class="mb-0"><i class="fas fa-info-circle me-2"></i>{% trans "Package Information" %}</h5>
</div>
<div class="card-body">
<div class="row">
<div class="col-md-6">
<div class="mb-3">
<label class="form-label">{% trans "Name (English)" %} <span class="text-danger">*</span></label>
{{ form.name_en }}
{% if form.name_en.errors %}
<div class="text-danger small">{{ form.name_en.errors }}</div>
{% endif %}
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label class="form-label">{% trans "Name (Arabic)" %}</label>
{{ form.name_ar }}
{% if form.name_ar.errors %}
<div class="text-danger small">{{ form.name_ar.errors }}</div>
{% endif %}
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div class="mb-3">
<label class="form-label">{% trans "Price" %} <span class="text-danger">*</span></label>
{{ form.price }}
{% if form.price.errors %}
<div class="text-danger small">{{ form.price.errors }}</div>
{% endif %}
</div>
</div>
<div class="col-md-6">
<div class="mb-3">
<label class="form-label">{% trans "Validity (days)" %} <span class="text-danger">*</span></label>
{{ form.validity_days }}
{% if form.validity_days.errors %}
<div class="text-danger small">{{ form.validity_days.errors }}</div>
{% endif %}
</div>
</div>
</div>
<div class="mb-3">
<label class="form-label">{% trans "Description" %}</label>
{{ form.description }}
{% if form.description.errors %}
<div class="text-danger small">{{ form.description.errors }}</div>
{% endif %}
</div>
<div class="form-check">
{{ form.is_active }}
<label class="form-check-label" for="{{ form.is_active.id_for_label }}">
{% trans "Active" %}
</label>
</div>
</div>
</div>
<div class="card mb-3">
<div class="card-header bg-success text-white d-flex justify-content-between align-items-center">
<h5 class="mb-0"><i class="fas fa-list me-2"></i>{% trans "Services Included" %}</h5>
<div>
<span class="me-2">{% trans "Total Sessions" %}</span>
<span class="fw-bold fs-16px" id="totalSessionsDisplay">0</span>
</div>
</div>
<div class="card-body">
{{ service_formset.management_form }}
<div id="serviceRows">
{% for service_form in service_formset %}
<div class="service-row" data-form-index="{{ forloop.counter0 }}">
<div class="row align-items-center">
<div class="col-md-7">
<label class="form-label small">{% trans "Service" %} <span class="text-danger">*</span></label>
{{ service_form.service }}
{% if service_form.service.errors %}
<div class="text-danger small">{{ service_form.service.errors }}</div>
{% endif %}
</div>
<div class="col-md-3">
<label class="form-label small">{% trans "Sessions" %} <span class="text-danger">*</span></label>
{{ service_form.sessions }}
{% if service_form.sessions.errors %}
<div class="text-danger small">{{ service_form.sessions.errors }}</div>
{% endif %}
</div>
<div class="col-md-2 text-end">
<label class="form-label small d-block">&nbsp;</label>
{% if not service_form.instance.pk or service_formset.can_delete %}
<button type="button" class="btn btn-outline-danger btn-sm btn-remove-service">
<i class="fas fa-trash"></i>
</button>
{% endif %}
{{ service_form.id }}
<div style="display: none;">{{ service_form.DELETE }}</div>
</div>
</div>
</div>
{% endfor %}
</div>
<button type="button" class="btn btn-outline-success btn-sm mt-2" id="addServiceBtn">
<i class="fas fa-plus me-1"></i>{% trans "Add Service" %}
</button>
</div>
</div>
<div class="card">
<div class="card-body">
<button type="submit" class="btn btn-primary btn-lg">
<i class="fas fa-save me-2"></i>{% trans "Save Package" %}
</button>
<a href="{% url 'finance:package_list' %}" class="btn btn-outline-secondary btn-lg">
<i class="fas fa-times me-2"></i>{% trans "Cancel" %}
</a>
</div>
</div>
</div>
<div class="col-lg-4">
<div class="card">
<div class="card-header">
<h6 class="mb-0"><i class="fas fa-question-circle me-2"></i>{% trans "Help" %}</h6>
</div>
<div class="card-body">
<p class="small">{% trans "Create service packages for bundled pricing." %}</p>
<ul class="small">
<li>{% trans "Set package name and price" %}</li>
<li>{% trans "Add services and specify sessions for each" %}</li>
<li>{% trans "Total sessions are calculated automatically" %}</li>
<li>{% trans "Set validity period" %}</li>
</ul>
</div>
</div>
</div>
</div>
</form>
</div>
<!-- Empty form template for cloning -->
<script type="text/template" id="emptyFormTemplate">
<div class="service-row" data-form-index="__prefix__">
<div class="row align-items-center">
<div class="col-md-7">
<label class="form-label small">{% trans "Service" %} <span class="text-danger">*</span></label>
{{ service_formset.empty_form.service }}
</div>
<div class="col-md-3">
<label class="form-label small">{% trans "Sessions" %} <span class="text-danger">*</span></label>
{{ service_formset.empty_form.sessions }}
</div>
<div class="col-md-2 text-end">
<label class="form-label small d-block">&nbsp;</label>
<button type="button" class="btn btn-outline-danger btn-sm btn-remove-service">
<i class="fas fa-trash"></i>
</button>
{{ service_formset.empty_form.id }}
<div style="display: none;">{{ service_formset.empty_form.DELETE }}</div>
</div>
</div>
</div>
</script>
{% endblock %}
{% block js %}
<script src="{% static 'plugins/select2/dist/js/select2.min.js' %}"></script>
<script>
$(document).ready(function() {
let formIndex = {{ service_formset.total_form_count }};
// Initialize Select2 for existing service dropdowns
initializeSelect2();
// Calculate total sessions on page load
calculateTotalSessions();
// Add new service row
$('#addServiceBtn').click(function() {
// Get the template HTML and replace __prefix__
let templateHtml = $('#emptyFormTemplate').html();
templateHtml = templateHtml.replace(/__prefix__/g, formIndex);
// Create new row from the modified HTML
const newRow = $(templateHtml);
// Append to service rows
$('#serviceRows').append(newRow);
// Update form count
const totalForms = $('#id_packageservice_set-TOTAL_FORMS');
totalForms.val(parseInt(totalForms.val()) + 1);
// Initialize Select2 for the new dropdown
newRow.find('select[name$="-service"]').select2({
placeholder: '{% trans "Select Service" %}',
allowClear: true,
width: '100%'
});
formIndex++;
// Recalculate total sessions
calculateTotalSessions();
});
// Remove service row
$(document).on('click', '.btn-remove-service', function() {
const row = $(this).closest('.service-row');
const deleteCheckbox = row.find('input[name$="-DELETE"]');
if (deleteCheckbox.length > 0) {
// Mark for deletion if it's an existing record
deleteCheckbox.prop('checked', true);
row.hide();
} else {
// Remove from DOM if it's a new record
row.remove();
}
// Recalculate total sessions
calculateTotalSessions();
});
// Recalculate total sessions when session count changes
$(document).on('input change', 'input[name$="-sessions"]', function() {
calculateTotalSessions();
});
function initializeSelect2() {
$('select[name$="-service"]').each(function() {
if (!$(this).hasClass('select2-hidden-accessible')) {
$(this).select2({
placeholder: '{% trans "Select Service" %}',
allowClear: true,
width: '100%'
});
}
});
}
function calculateTotalSessions() {
let total = 0;
$('.service-row:visible').each(function() {
const deleteCheckbox = $(this).find('input[name$="-DELETE"]');
const isMarkedForDeletion = deleteCheckbox.length > 0 && deleteCheckbox.is(':checked');
if (!isMarkedForDeletion) {
const sessionsInput = $(this).find('input[name$="-sessions"]');
const sessions = parseInt(sessionsInput.val()) || 0;
total += sessions;
}
});
$('#totalSessionsDisplay').text(total);
}
});
</script>
{% endblock %}