204 lines
No EOL
10 KiB
Twig
204 lines
No EOL
10 KiB
Twig
{% extends 'layout.twig' %}
|
|
{% import 'components/form.twig' as form %}
|
|
|
|
{% block title %}Create Order - {{ parent() }}{% endblock %}
|
|
|
|
{% block content %}
|
|
<div class="row mb-4">
|
|
<div class="col">
|
|
<h2>Create New Order</h2>
|
|
</div>
|
|
<div class="col-auto">
|
|
<div class="btn-group" role="group">
|
|
<a href="/orders" class="btn btn-secondary">
|
|
<i class="fas fa-arrow-left"></i> Back to Orders
|
|
</a>
|
|
<a href="/orders/create-from-stock" class="btn btn-primary">
|
|
<i class="fas fa-magic"></i> Create from Stock Levels
|
|
</a>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<div class="card-body">
|
|
{{ form.errors(error) }}
|
|
|
|
<form action="/orders" method="post" id="orderForm">
|
|
<div class="order-items">
|
|
<div class="row mb-3">
|
|
<div class="col">
|
|
<h5>Order Items</h5>
|
|
</div>
|
|
<div class="col-auto">
|
|
<button type="button" class="btn btn-sm btn-success add-item-btn">
|
|
<i class="fas fa-plus"></i> Add Item
|
|
</button>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="order-item-template d-none">
|
|
<div class="card mb-3 order-item">
|
|
<div class="card-body">
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="form-group">
|
|
<label>Drink Type</label>
|
|
<select name="items[{index}][drink_type_id]" class="form-control drink-type-select" required>
|
|
<option value="">-- Select Drink Type --</option>
|
|
{% for drinkType in drinkTypes %}
|
|
<option value="{{ drinkType.id }}" data-desired-stock="{{ drinkType.desiredStock }}" data-current-stock="{{ drinkType.currentStock|default(0) }}">
|
|
{{ drinkType.name }}
|
|
</option>
|
|
{% endfor %}
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-5">
|
|
<div class="form-group">
|
|
<label>Quantity</label>
|
|
<input type="number" name="items[{index}][quantity]" class="form-control quantity-input" min="1" required>
|
|
<small class="form-text text-muted stock-info"></small>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-1 d-flex align-items-end">
|
|
<button type="button" class="btn btn-sm btn-danger remove-item-btn mb-2">
|
|
<i class="fas fa-trash"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="order-items-container">
|
|
<!-- Order items will be added here -->
|
|
<div class="card mb-3 order-item">
|
|
<div class="card-body">
|
|
<div class="row">
|
|
<div class="col-md-6">
|
|
<div class="form-group">
|
|
<label>Drink Type</label>
|
|
<select name="items[0][drink_type_id]" class="form-control drink-type-select" required>
|
|
<option value="">-- Select Drink Type --</option>
|
|
{% for drinkType in drinkTypes %}
|
|
<option value="{{ drinkType.id }}" data-desired-stock="{{ drinkType.desiredStock }}" data-current-stock="{{ drinkType.currentStock|default(0) }}">
|
|
{{ drinkType.name }}
|
|
</option>
|
|
{% endfor %}
|
|
</select>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-5">
|
|
<div class="form-group">
|
|
<label>Quantity</label>
|
|
<input type="number" name="items[0][quantity]" class="form-control quantity-input" min="1" required>
|
|
<small class="form-text text-muted stock-info"></small>
|
|
</div>
|
|
</div>
|
|
<div class="col-md-1 d-flex align-items-end">
|
|
<button type="button" class="btn btn-sm btn-danger remove-item-btn mb-2" disabled>
|
|
<i class="fas fa-trash"></i>
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div class="alert alert-info d-none no-items-alert">
|
|
<i class="fas fa-info-circle"></i> Please add at least one item to the order.
|
|
</div>
|
|
</div>
|
|
|
|
<div class="form-group mt-4">
|
|
{{ form.submit('Create Order') }}
|
|
<a href="/orders" class="btn btn-link">Cancel</a>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
{% endblock %}
|
|
|
|
{% block scripts %}
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', function() {
|
|
const orderItemsContainer = document.querySelector('.order-items-container');
|
|
const orderItemTemplate = document.querySelector('.order-item-template');
|
|
const addItemBtn = document.querySelector('.add-item-btn');
|
|
const noItemsAlert = document.querySelector('.no-items-alert');
|
|
|
|
// Add item button click handler
|
|
addItemBtn.addEventListener('click', function() {
|
|
const newIndex = document.querySelectorAll('.order-item').length;
|
|
const newItem = orderItemTemplate.querySelector('.order-item').cloneNode(true);
|
|
|
|
// Update name attributes with the correct index
|
|
newItem.querySelectorAll('[name]').forEach(input => {
|
|
input.name = input.name.replace('{index}', newIndex);
|
|
});
|
|
|
|
// Enable the remove button
|
|
newItem.querySelector('.remove-item-btn').disabled = false;
|
|
|
|
// Add the new item to the container
|
|
orderItemsContainer.appendChild(newItem);
|
|
|
|
// Hide the no items alert
|
|
noItemsAlert.classList.add('d-none');
|
|
|
|
// Add event listeners to the new item
|
|
addItemEventListeners(newItem);
|
|
});
|
|
|
|
// Add event listeners to initial item
|
|
addItemEventListeners(orderItemsContainer.querySelector('.order-item'));
|
|
|
|
// Form submission handler
|
|
document.getElementById('orderForm').addEventListener('submit', function(e) {
|
|
const items = document.querySelectorAll('.order-item');
|
|
|
|
if (items.length === 0) {
|
|
e.preventDefault();
|
|
noItemsAlert.classList.remove('d-none');
|
|
}
|
|
});
|
|
|
|
// Function to add event listeners to an item
|
|
function addItemEventListeners(item) {
|
|
// Remove item button click handler
|
|
item.querySelector('.remove-item-btn').addEventListener('click', function() {
|
|
if (document.querySelectorAll('.order-item').length > 1) {
|
|
item.remove();
|
|
} else {
|
|
noItemsAlert.classList.remove('d-none');
|
|
}
|
|
});
|
|
|
|
// Drink type select change handler
|
|
item.querySelector('.drink-type-select').addEventListener('change', function() {
|
|
const option = this.options[this.selectedIndex];
|
|
const stockInfo = item.querySelector('.stock-info');
|
|
const quantityInput = item.querySelector('.quantity-input');
|
|
|
|
if (option.value) {
|
|
const desiredStock = parseInt(option.dataset.desiredStock);
|
|
const currentStock = parseInt(option.dataset.currentStock);
|
|
const difference = desiredStock - currentStock;
|
|
|
|
if (difference > 0) {
|
|
stockInfo.textContent = `Current: ${currentStock}, Desired: ${desiredStock}, Suggested order: ${difference}`;
|
|
quantityInput.value = difference;
|
|
} else {
|
|
stockInfo.textContent = `Current: ${currentStock}, Desired: ${desiredStock}, Stock is adequate`;
|
|
quantityInput.value = '';
|
|
}
|
|
} else {
|
|
stockInfo.textContent = '';
|
|
quantityInput.value = '';
|
|
}
|
|
});
|
|
}
|
|
});
|
|
</script>
|
|
{% endblock %} |