kancelyary_project/templates/add_order.html

455 lines
11 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

{% extends "base.html" %}
{% block content %}
<div class="page-header">
<h2>Создание нового заказа</h2>
<a href="{{ url_for('index') }}" class="btn-back">Отмена</a>
</div>
<form method="POST" class="order-form" id="orderForm">
<div class="form-section">
<h3>Информация о заказе</h3>
<div class="form-group">
<label for="partner_id">Партнер *</label>
<select name="partner_id" id="partner_id" required>
<option value="">Выберите партнера</option>
{% for partner in partners %}
<option value="{{ partner.id }}">{{ partner.name }}</option>
{% endfor %}
</select>
</div>
<div class="form-group">
<label for="order_date">Дата заказа *</label>
<input type="date" name="order_date" id="order_date" value="{{ today }}" required>
</div>
<div class="form-group">
<label for="notes">Примечания</label>
<textarea name="notes" id="notes" rows="3"></textarea>
</div>
</div>
<div class="form-section">
<h3>Позиции заказа</h3>
<p class="info-text">Выберите товары для заказа</p>
<div id="items-container">
<div class="item-row" id="item-row-1">
<div class="item-fields">
<div class="form-group">
<label>Товар</label>
<select name="product_id[]" class="product-select" required onchange="updatePrice(this)">
<option value="">Выберите товар</option>
{% for product in products %}
<option value="{{ product.id }}" data-price="{{ product.min_partner_price }}">
{{ product.product_name }} ({{ product.type_name }})
</option>
{% endfor %}
</select>
</div>
<div class="form-group">
<label>Количество</label>
<input type="number" name="quantity[]" class="quantity-input"
min="1" value="1" required oninput="updateItemTotal(this)">
</div>
<div class="form-group">
<label>Цена</label>
<input type="number" name="price[]" class="price-input"
step="0.01" min="0.01" required readonly>
</div>
<div class="item-total">
<label>Сумма с наценкой:</label>
<span class="item-total-value">0.00 ₽</span>
</div>
<button type="button" class="btn-remove-item" onclick="removeItem(1)" style="display: none;">×</button>
</div>
</div>
</div>
<button type="button" class="btn-add-item" onclick="addItem()">+ Добавить позицию</button>
</div>
<div class="form-actions">
<button type="submit" class="btn-submit">Создать заказ</button>
</div>
</form>
<script>
let itemCount = 1;
function addItem() {
itemCount++;
const container = document.getElementById('items-container');
const newRow = document.createElement('div');
newRow.className = 'item-row';
newRow.id = `item-row-${itemCount}`;
let options = '<option value="">Выберите товар</option>';
{% for product in products %}
options += `<option value="{{ product.id }}" data-price="{{ product.min_partner_price }}">
{{ product.product_name }} ({{ product.type_name }})
</option>`;
{% endfor %}
newRow.innerHTML = `
<div class="item-fields">
<div class="form-group">
<label>Товар</label>
<select name="product_id[]" class="product-select" required onchange="updatePrice(this)">
${options}
</select>
</div>
<div class="form-group">
<label>Количество</label>
<input type="number" name="quantity[]" class="quantity-input"
min="1" value="1" required oninput="updateItemTotal(this)">
</div>
<div class="form-group">
<label>Цена</label>
<input type="number" name="price[]" class="price-input"
step="0.01" min="0.01" required readonly>
</div>
<div class="item-total">
<label>Сумма с наценкой:</label>
<span class="item-total-value">0.00 ₽</span>
</div>
<button type="button" class="btn-remove-item" onclick="removeItem(${itemCount})">×</button>
</div>
`;
container.appendChild(newRow);
updateRemoveButtons();
}
function removeItem(id) {
const row = document.getElementById(`item-row-${id}`);
if (row) {
row.remove();
updateRemoveButtons();
}
}
function updateRemoveButtons() {
const rows = document.querySelectorAll('.item-row');
rows.forEach((row, index) => {
const btn = row.querySelector('.btn-remove-item');
if (btn) {
btn.style.display = rows.length > 1 ? 'block' : 'none';
}
});
}
function updatePrice(select) {
const row = select.closest('.item-row');
const priceInput = row.querySelector('.price-input');
const selectedOption = select.options[select.selectedIndex];
if (selectedOption && selectedOption.dataset.price) {
priceInput.value = selectedOption.dataset.price;
}
updateItemTotal(priceInput);
}
function updateItemTotal(input) {
const row = input.closest('.item-row');
const quantity = parseFloat(row.querySelector('.quantity-input').value) || 0;
const price = parseFloat(row.querySelector('.price-input').value) || 0;
const totalSpan = row.querySelector('.item-total-value');
const totalWithMarkup = quantity * price * 1.1;
totalSpan.textContent = totalWithMarkup.toFixed(2) + ' ₽';
}
document.getElementById('orderForm').addEventListener('submit', function(e) {
const rows = document.querySelectorAll('.item-row');
let hasValidItems = false;
rows.forEach((row, index) => {
const select = row.querySelector('.product-select');
const quantity = row.querySelector('.quantity-input');
const price = row.querySelector('.price-input');
if (select.value && quantity.value && price.value) {
hasValidItems = true;
}
});
if (!hasValidItems) {
e.preventDefault();
alert('Добавьте хотя бы одну позицию с корректными данными');
}
});
// Инициализация обработчиков
document.addEventListener('DOMContentLoaded', function() {
const firstSelect = document.querySelector('.product-select');
if (firstSelect) {
updatePrice(firstSelect);
}
document.querySelectorAll('.quantity-input').forEach(input => {
input.addEventListener('input', function() {
updateItemTotal(this);
});
});
});
</script>
<style>
.order-form {
background: white;
border-radius: 8px;
padding: 25px;
box-shadow: 0 2px 10px rgba(0,0,0,0.1);
max-width: 1000px;
margin: 0 auto;
}
.form-section {
margin-bottom: 30px;
padding-bottom: 20px;
border-bottom: 2px solid #E0E0E0;
}
.form-section h3 {
color: #696969;
margin-bottom: 15px;
font-size: 1.3rem;
}
.info-text {
color: #666;
margin-bottom: 15px;
font-style: italic;
}
.form-group {
margin-bottom: 15px;
}
.form-group label {
display: block;
margin-bottom: 5px;
font-weight: 600;
color: #555;
}
.form-group input,
.form-group select,
.form-group textarea {
width: 100%;
padding: 10px;
border: 1px solid #E0E0E0;
border-radius: 4px;
font-family: 'Calibri', sans-serif;
font-size: 1rem;
transition: border-color 0.3s;
}
.form-group input:focus,
.form-group select:focus,
.form-group textarea:focus {
outline: none;
border-color: #696969;
}
.stock-hint {
display: block;
margin-top: 5px;
color: #696969;
font-size: 0.9rem;
}
.stock-hint .max-stock {
font-weight: 600;
color: #4CAF50;
}
.item-row {
background-color: #F5F5F5;
border-radius: 8px;
padding: 15px;
margin-bottom: 15px;
border-left: 4px solid #696969;
}
.item-fields {
display: grid;
grid-template-columns: 2fr 1fr 1fr 1fr auto;
gap: 15px;
align-items: start;
}
.item-total {
padding-top: 25px;
font-weight: 600;
color: #696969;
}
.item-total label {
display: block;
font-size: 0.9rem;
color: #666;
margin-bottom: 5px;
}
.btn-add-item {
background-color: #696969;
color: white;
border: none;
padding: 12px 20px;
border-radius: 4px;
cursor: pointer;
font-size: 1rem;
font-weight: 600;
width: 100%;
margin-top: 10px;
transition: background-color 0.3s;
}
.btn-add-item:hover {
background-color: #555;
}
.btn-remove-item {
background-color: #ff6b6b;
color: white;
border: none;
border-radius: 4px;
width: 36px;
height: 36px;
cursor: pointer;
font-size: 1.2rem;
display: flex;
align-items: center;
justify-content: center;
transition: background-color 0.3s;
margin-top: 25px;
}
.btn-remove-item:hover {
background-color: #ff5252;
}
.total-section {
background-color: #F5F5F5;
padding: 20px;
border-radius: 8px;
margin: 20px 0;
border: 2px solid #E0E0E0;
}
.total-row {
display: flex;
justify-content: space-between;
align-items: center;
padding: 10px 0;
border-bottom: 1px solid #E0E0E0;
}
.total-row:last-child {
border-bottom: none;
}
.total-label {
font-size: 1.1rem;
color: #555;
}
.total-value {
font-size: 1.1rem;
color: #696969;
font-weight: 500;
}
.grand-total {
margin-top: 10px;
padding-top: 10px;
border-top: 2px solid #696969;
}
.grand-total .total-label,
.grand-total .total-value {
font-size: 1.3rem;
color: #696969;
}
.discount-info {
color: #4CAF50;
}
.form-actions {
text-align: center;
margin-top: 30px;
}
.btn-submit {
background-color: #696969;
color: white;
border: none;
padding: 15px 40px;
border-radius: 4px;
cursor: pointer;
font-size: 1.2rem;
font-weight: 600;
transition: background-color 0.3s;
}
.btn-submit:hover {
background-color: #555;
}
.btn-back {
display: inline-block;
background-color: #E0E0E0;
color: #696969;
text-decoration: none;
padding: 15px 40px;
border-radius: 4px;
margin-left: 10px;
font-weight: 600;
transition: background-color 0.3s;
}
.btn-back:hover {
background-color: #D0D0D0;
}
@media (max-width: 768px) {
.item-fields {
grid-template-columns: 1fr;
gap: 10px;
}
.item-total {
padding-top: 0;
}
.btn-remove-item {
margin-top: 0;
width: 100%;
}
.form-actions {
display: flex;
flex-direction: column;
gap: 10px;
}
.btn-back {
margin-left: 0;
}
}
</style>
{% endblock %}