214 lines
11 KiB
Twig
214 lines
11 KiB
Twig
{% extends 'layouts/base.twig' %}
|
||
|
||
{% block title %}{{ title }}{% endblock %}
|
||
|
||
{% block content %}
|
||
<div class="row justify-content-center">
|
||
<div class="col-lg-8">
|
||
<div class="d-flex justify-content-between align-items-center mb-4">
|
||
<h1 class="h3 mb-0">{{ title }}</h1>
|
||
<a href="{{ site_url('/crm/deals') }}" class="btn btn-outline-secondary">
|
||
<i class="fa-solid fa-arrow-left me-2"></i>Назад
|
||
</a>
|
||
</div>
|
||
|
||
{# Сообщения об ошибках #}
|
||
{% if errors is defined and errors|length > 0 %}
|
||
<div class="alert alert-danger alert-dismissible fade show" role="alert">
|
||
<ul class="mb-0">
|
||
{% for error in errors %}
|
||
<li>{{ error }}</li>
|
||
{% endfor %}
|
||
</ul>
|
||
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
|
||
</div>
|
||
{% endif %}
|
||
|
||
<div class="card shadow-sm">
|
||
<div class="card-body">
|
||
<form method="POST" action="{{ actionUrl }}">
|
||
{{ csrf_field()|raw }}
|
||
|
||
<div class="mb-3">
|
||
<label for="title" class="form-label fw-bold">Название сделки *</label>
|
||
<input type="text"
|
||
class="form-control"
|
||
id="title"
|
||
name="title"
|
||
value="{{ old.title|default(deal.title|default('')) }}"
|
||
required
|
||
placeholder="Например: Разработка сайта для ООО Ромашка">
|
||
</div>
|
||
|
||
<div class="row mb-3">
|
||
<div class="col-md-6">
|
||
<label for="amount" class="form-label fw-bold">Сумма</label>
|
||
<div class="input-group">
|
||
<input type="number"
|
||
class="form-control"
|
||
id="amount"
|
||
name="amount"
|
||
step="0.01"
|
||
min="0"
|
||
value="{{ old.amount|default(deal.amount|default(0)) }}">
|
||
<select class="form-select" name="currency" style="max-width: 100px;">
|
||
<option value="RUB" {{ (old.currency|default(deal.currency|default('RUB'))) == 'RUB' ? 'selected' : '' }}>₽</option>
|
||
<option value="USD" {{ (old.currency|default(deal.currency|default(''))) == 'USD' ? 'selected' : '' }}>$</option>
|
||
<option value="EUR" {{ (old.currency|default(deal.currency|default(''))) == 'EUR' ? 'selected' : '' }}>€</option>
|
||
</select>
|
||
</div>
|
||
</div>
|
||
<div class="col-md-6">
|
||
<label for="stage_id" class="form-label fw-bold">Этап *</label>
|
||
<select class="form-select" id="stage_id" name="stage_id" required>
|
||
<option value="">Выберите этап</option>
|
||
{% for stage in stages %}
|
||
<option value="{{ stage.id }}"
|
||
{{ (old.stage_id|default(deal.stage_id|default(stageId|default('')))) == stage.id ? 'selected' : '' }}
|
||
data-color="{{ stage.color }}">
|
||
{{ stage.name }}
|
||
</option>
|
||
{% endfor %}
|
||
</select>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="mb-3">
|
||
<label for="description" class="form-label fw-bold">Описание</label>
|
||
<textarea class="form-control"
|
||
id="description"
|
||
name="description"
|
||
rows="4"
|
||
placeholder="Детали сделки, условия, комментарии...">{{ old.description|default(deal.description|default('')) }}</textarea>
|
||
</div>
|
||
|
||
<div class="row mb-3">
|
||
<div class="col-md-6">
|
||
<label for="company_id" class="form-label fw-bold">Клиент *</label>
|
||
<select class="form-select" id="company_id" name="company_id" required>
|
||
<option value="">Выберите клиента</option>
|
||
{% for client in clients %}
|
||
<option value="{{ client.id }}"
|
||
{{ (old.company_id|default(deal.company_id|default(''))) == client.id ? 'selected' : '' }}>
|
||
{{ client.name }}
|
||
</option>
|
||
{% endfor %}
|
||
</select>
|
||
</div>
|
||
<div class="col-md-6">
|
||
<label for="contact_id" class="form-label fw-bold">Контакт</label>
|
||
<select class="form-select" id="contact_id" name="contact_id">
|
||
<option value="">Сначала выберите клиента</option>
|
||
{% for contact in contacts %}
|
||
<option value="{{ contact.id }}"
|
||
{{ (old.contact_id|default(deal.contact_id|default(''))) == contact.id ? 'selected' : '' }}>
|
||
{{ contact.name }} {{ contact.position ? ' (' ~ contact.position ~ ')' : '' }}
|
||
</option>
|
||
{% endfor %}
|
||
</select>
|
||
<div id="contacts-loading" class="text-muted small mt-1" style="display: none;">
|
||
<i class="fa-solid fa-spinner fa-spin me-1"></i>Загрузка контактов...
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<div class="row mb-4">
|
||
<div class="col-md-6">
|
||
<label for="assigned_user_id" class="form-label fw-bold">Ответственный</label>
|
||
<select class="form-select" id="assigned_user_id" name="assigned_user_id">
|
||
<option value="">Не назначен</option>
|
||
{% for userId, userName in users %}
|
||
<option value="{{ userId }}"
|
||
{{ (old.assigned_user_id|default(deal.assigned_user_id|default(currentUserId|default('')))) == userId ? 'selected' : '' }}>
|
||
{{ userName }}
|
||
</option>
|
||
{% endfor %}
|
||
</select>
|
||
</div>
|
||
<div class="col-md-6">
|
||
<label for="expected_close_date" class="form-label fw-bold">Ожидаемая дата закрытия</label>
|
||
<input type="date"
|
||
class="form-control"
|
||
id="expected_close_date"
|
||
name="expected_close_date"
|
||
value="{{ old.expected_close_date|default(deal.expected_close_date|default('')) }}">
|
||
</div>
|
||
</div>
|
||
|
||
<div class="d-flex justify-content-end gap-2 pt-3 border-top">
|
||
<a href="{{ site_url('/crm/deals') }}" class="btn btn-outline-secondary">Отмена</a>
|
||
<button type="submit" class="btn btn-primary">
|
||
<i class="fa-solid fa-check me-2"></i>
|
||
{{ deal is defined ? 'Сохранить' : 'Создать сделку' }}
|
||
</button>
|
||
</div>
|
||
</form>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
{% endblock %}
|
||
|
||
{% block scripts %}
|
||
<script>
|
||
document.addEventListener('DOMContentLoaded', function() {
|
||
const companySelect = document.getElementById('company_id');
|
||
const contactSelect = document.getElementById('contact_id');
|
||
const contactsLoading = document.getElementById('contacts-loading');
|
||
|
||
// Функция загрузки контактов по клиенту
|
||
function loadContacts(clientId) {
|
||
if (!clientId) {
|
||
contactSelect.innerHTML = '<option value="">Сначала выберите клиента</option>';
|
||
contactSelect.disabled = true;
|
||
return;
|
||
}
|
||
|
||
contactSelect.disabled = true;
|
||
contactsLoading.style.display = 'block';
|
||
|
||
fetch(`/crm/deals/contacts-by-client?client_id=${clientId}`)
|
||
.then(response => response.json())
|
||
.then(data => {
|
||
contactsLoading.style.display = 'none';
|
||
|
||
if (data.success && data.contacts.length > 0) {
|
||
let options = '<option value="">Выберите контакт</option>';
|
||
data.contacts.forEach(contact => {
|
||
const label = contact.name + (contact.email ? ` (${contact.email})` : '');
|
||
options += `<option value="${contact.id}">${label}</option>`;
|
||
});
|
||
contactSelect.innerHTML = options;
|
||
contactSelect.disabled = false;
|
||
} else {
|
||
contactSelect.innerHTML = '<option value="">Нет контактов для этого клиента</option>';
|
||
contactSelect.disabled = false;
|
||
}
|
||
})
|
||
.catch(error => {
|
||
console.error('Ошибка загрузки контактов:', error);
|
||
contactsLoading.style.display = 'none';
|
||
contactSelect.innerHTML = '<option value="">Ошибка загрузки</option>';
|
||
contactSelect.disabled = false;
|
||
});
|
||
}
|
||
|
||
// Загружаем контакты если клиент уже выбран (редактирование)
|
||
const selectedClientId = companySelect.value;
|
||
if (selectedClientId) {
|
||
const selectedContactId = contactSelect.value;
|
||
if (selectedContactId) {
|
||
// При редактировании сохраняем выбранный контакт
|
||
contactSelect.dataset.selectedId = selectedContactId;
|
||
}
|
||
loadContacts(selectedClientId);
|
||
}
|
||
|
||
// Обработчик изменения клиента
|
||
companySelect.addEventListener('change', function() {
|
||
loadContacts(this.value);
|
||
});
|
||
});
|
||
</script>
|
||
{% endblock %}
|