38086-vm/core/templates/core/inventory.html
2026-02-10 12:23:20 +00:00

810 lines
53 KiB
HTML

{% extends 'base.html' %}
{% load i18n static %}
{% block title %}{% trans "Stock Management" %} | {{ site_settings.business_name }}{% endblock %}
{% block content %}
<div class="container">
<div class="d-flex justify-content-between align-items-center mb-4">
<div>
<h2 class="fw-bold mb-1">{% trans "Stock Management" %}</h2>
<nav aria-label="breadcrumb">
<ol class="breadcrumb">
<li class="breadcrumb-item"><a href="{% url 'index' %}">{% trans "Dashboard" %}</a></li>
<li class="breadcrumb-item active" aria-current="page">{% trans "Stock" %}</li>
</ol>
</nav>
</div>
<div class="btn-group">
<button class="btn btn-primary shadow-sm" data-bs-toggle="modal" data-bs-target="#addProductModal">
<i class="bi bi-plus-lg me-2"></i>{% trans "Add Item" %}
</button>
<button class="btn btn-success shadow-sm" data-bs-toggle="modal" data-bs-target="#importModal">
<i class="bi bi-file-earmark-excel me-2"></i>{% trans "Import" %}
</button>
<button class="btn btn-outline-primary shadow-sm" data-bs-toggle="modal" data-bs-target="#addCategoryModal">
<i class="bi bi-folder-plus me-2"></i>{% trans "Add Category" %}
</button>
<a href="{% url 'import_categories' %}" class="btn btn-outline-success shadow-sm">
<i class="bi bi-file-earmark-arrow-up me-2"></i>{% trans "Import Categories" %}
</a>
<button class="btn btn-outline-primary shadow-sm" data-bs-toggle="modal" data-bs-target="#addUnitModal">
<i class="bi bi-rulers me-2"></i>{% trans "Add Unit" %}
</button>
</div>
</div>
{% if messages %}
<div class="mb-4">
{% for message in messages %}
<div class="alert alert-{{ message.tags }} alert-dismissible fade show rounded-3" role="alert">
{{ message }}
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"></button>
</div>
{% endfor %}
</div>
{% endif %}
<!-- Tabs for Stock Management -->
<ul class="nav nav-pills mb-4 bg-white p-2 rounded-4 shadow-sm" id="stockTabs" role="tablist">
<li class="nav-item" role="presentation">
<button class="nav-link active px-4 rounded-3" id="items-tab" data-bs-toggle="tab" data-bs-target="#items" type="button" role="tab">
<i class="bi bi-box-seam me-2"></i>{% trans "Items" %}
</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link px-4 rounded-3" id="categories-tab" data-bs-toggle="tab" data-bs-target="#categories-list" type="button" role="tab">
<i class="bi bi-folder me-2"></i>{% trans "Categories" %}
</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link px-4 rounded-3" id="units-tab" data-bs-toggle="tab" data-bs-target="#units-list" type="button" role="tab">
<i class="bi bi-rulers me-2"></i>{% trans "Units" %}
</button>
</li>
<li class="nav-item" role="presentation">
<button class="nav-link px-4 rounded-3 text-danger" id="expired-tab" data-bs-toggle="tab" data-bs-target="#expired-list" type="button" role="tab">
<i class="bi bi-calendar-x me-2"></i>{% trans "Expired / Expiring" %}
</button>
</li>
</ul>
<div class="tab-content" id="stockTabsContent">
<!-- Items Tab -->
<div class="tab-pane fade show active" id="items" role="tabpanel">
<!-- Search & Filter Bar -->
<div class="card border-0 shadow-sm rounded-4 mb-4">
<div class="card-body p-3">
<form class="row g-3">
<div class="col-md-6">
<div class="input-group">
<span class="input-group-text bg-white border-end-0"><i class="bi bi-search text-muted"></i></span>
<input type="text" class="form-control border-start-0" placeholder="{% trans 'Search by name or SKU...' %}">
</div>
</div>
<div class="col-md-4">
<select class="form-select">
<option value="">{% trans "All Categories" %}</option>
{% for category in categories %}
<option value="{{ category.id }}">{{ category.name_ar }} / {{ category.name_en }}</option>
{% endfor %}
</select>
</div>
<div class="col-md-2">
<button type="button" class="btn btn-light w-100">{% trans "Filter" %}</button>
</div>
</form>
</div>
</div>
<!-- Product Table (Grid) -->
<div class="card border-0 shadow-sm rounded-4">
<div class="table-responsive">
<table class="table table-hover align-middle mb-0" id="productsTable">
<thead class="bg-light">
<tr>
<th class="ps-4">{% trans "Item" %}</th>
<th>{% trans "SKU/Barcode" %}</th>
<th>{% trans "Category" %}</th>
<th>{% trans "Stock" %}</th>
<th>{% trans "Cost" %}</th>
<th>{% trans "Price" %}</th>
<th>{% trans "Status" %}</th>
<th class="text-end pe-4">{% trans "Actions" %}</th>
</tr>
</thead>
<tbody>
{% for product in products %}
<tr class="{% if not product.is_active %}opacity-50{% endif %}">
<td class="ps-4">
<div class="d-flex align-items-center">
{% if product.image %}
<img src="{{ product.image.url }}" class="rounded-2 me-3" alt="" style="width: 40px; height: 40px; object-fit: cover;">
{% else %}
<div class="bg-light rounded-2 me-3 d-flex align-items-center justify-content-center" style="width: 40px; height: 40px;">
<i class="bi bi-box-seam text-muted"></i>
</div>
{% endif %}
<div>
<div class="fw-bold text-dark" dir="rtl">{{ product.name_ar }}</div>
<div class="small text-muted">{{ product.name_en }}</div>
<small class="text-muted">{{ product.unit.name_ar|default:"" }} / {{ product.unit.name_en|default:"" }}</small>
</div>
</div>
</td>
<td><code>{{ product.sku }}</code></td>
<td>{{ product.category.name_ar }} / {{ product.category.name_en }}</td>
<td>
<span class="badge {% if product.stock_quantity <= product.min_stock_level %}bg-danger{% else %}bg-success-subtle text-success{% endif %} rounded-pill">
{{ product.stock_quantity|floatformat:2 }} {{ product.unit.short_name|default:"" }}
</span>
</td>
<td>{{ site_settings.currency_symbol }}{{ product.cost_price|floatformat:3 }}</td>
<td class="fw-bold text-primary">{{ site_settings.currency_symbol }}{{ product.price|floatformat:3 }}</td>
<td>
{% if product.is_active %}
<span class="badge bg-success-subtle text-success border-success-subtle">{% trans "Active" %}</span>
{% else %}
<span class="badge bg-secondary-subtle text-secondary">{% trans "Inactive" %}</span>
{% endif %}
</td>
<td class="text-end pe-4">
<div class="btn-group">
<button class="btn btn-sm btn-light rounded-pill px-2 me-1" data-bs-toggle="modal" data-bs-target="#viewProductModal{{ product.id }}" title="{% trans 'View' %}">
<i class="bi bi-eye text-primary"></i>
</button>
<button class="btn btn-sm btn-light rounded-pill px-2 me-1" data-bs-toggle="modal" data-bs-target="#editProductModal{{ product.id }}" title="{% trans 'Edit' %}">
<i class="bi bi-pencil text-success"></i>
</button>
<a href="{% url 'delete_product' product.id %}" class="btn btn-sm btn-light rounded-pill px-2" onclick="return confirm('{% trans 'Are you sure you want to delete this item?' %}')" title="{% trans 'Delete' %}">
<i class="bi bi-trash text-danger"></i>
</a>
</div>
</td>
</tr>
<!-- View Product Modal -->
<div class="modal fade" id="viewProductModal{{ product.id }}" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-lg">
<div class="modal-content rounded-4 border-0 shadow">
<div class="modal-header border-0 pb-0">
<h5 class="modal-title fw-bold">{% trans "Item Details" %}</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div class="row g-3">
<div class="col-md-4">
{% if product.image %}
<img src="{{ product.image.url }}" class="img-fluid rounded-4 shadow-sm" alt="">
{% else %}
<div class="bg-light rounded-4 d-flex align-items-center justify-content-center" style="height: 200px;">
<i class="bi bi-box-seam text-muted opacity-25" style="font-size: 4rem;"></i>
</div>
{% endif %}
</div>
<div class="col-md-8">
<h3 class="fw-bold text-dark" dir="rtl">{{ product.name_ar }}</h3>
<h5 class="text-muted">{{ product.name_en }}</h5>
<hr>
<div class="row">
<div class="col-6 mb-2"><strong>{% trans "SKU" %}:</strong> <code>{{ product.sku }}</code></div>
<div class="col-6 mb-2"><strong>{% trans "Category" %}:</strong> {{ product.category.name_ar }}</div>
<div class="col-6 mb-2"><strong>{% trans "Stock" %}:</strong> {{ product.stock_quantity|floatformat:2 }} {{ product.unit.short_name }} (Min: {{ product.min_stock_level|floatformat:2 }})</div>
<div class="col-6 mb-2"><strong>{% trans "Price" %}:</strong> {{ site_settings.currency_symbol }}{{ product.price }}</div>
<div class="col-6 mb-2"><strong>{% trans "VAT" %}:</strong> {{ product.vat }}%</div>
<div class="col-6 mb-2"><strong>{% trans "Supplier" %}:</strong> {{ product.supplier.name|default:"N/A" }}</div>
{% if product.has_expiry %}
<div class="col-12 mb-2"><strong>{% trans "Expiry Date" %}:</strong> <span class="text-danger fw-bold">{{ product.expiry_date|date:"Y-m-d" }}</span></div>
{% endif %}
<div class="col-12 mt-2"><strong>{% trans "Description" %}:</strong><br>{{ product.description|linebreaks }}</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<!-- Edit Product Modal -->
<div class="modal fade" id="editProductModal{{ product.id }}" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-xl">
<div class="modal-content rounded-4 border-0 shadow">
<div class="modal-header border-0 pb-0">
<h5 class="modal-title fw-bold">{% trans "Edit Item" %}</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<form action="{% url 'edit_product' product.id %}" method="POST" enctype="multipart/form-data">
{% csrf_token %}
<div class="modal-body">
<div class="row g-3">
<div class="col-md-6">
<label class="form-label small fw-bold">{% trans "Name (English)" %}</label>
<input type="text" name="name_en" class="form-control rounded-3" value="{{ product.name_en }}" required>
</div>
<div class="col-md-6">
<label class="form-label small fw-bold">{% trans "Name (Arabic)" %}</label>
<input type="text" name="name_ar" class="form-control rounded-3" dir="rtl" value="{{ product.name_ar }}" required>
</div>
<div class="col-md-4">
<label class="form-label small fw-bold">{% trans "Barcode / SKU" %}</label>
<input type="text" name="sku" class="form-control rounded-3" value="{{ product.sku }}">
</div>
<div class="col-md-4">
<label class="form-label small fw-bold">{% trans "Category" %}</label>
<select name="category" class="form-select rounded-3" required>
{% for category in categories %}
<option value="{{ category.id }}" {% if category == product.category %}selected{% endif %}>{{ category.name_ar }} / {{ category.name_en }}</option>
{% endfor %}
</select>
</div>
<div class="col-md-4">
<label class="form-label small fw-bold">{% trans "Unit" %}</label>
<select name="unit" class="form-select rounded-3">
<option value="">{% trans "Select Unit" %}</option>
{% for unit in units %}
<option value="{{ unit.id }}" {% if unit == product.unit %}selected{% endif %}>{{ unit.name_ar }} / {{ unit.name_en }}</option>
{% endfor %}
</select>
</div>
<div class="col-md-4">
<label class="form-label small fw-bold">{% trans "Supplier" %}</label>
<select name="supplier" class="form-select rounded-3">
<option value="">{% trans "Select Supplier" %}</option>
{% for supplier in suppliers %}
<option value="{{ supplier.id }}" {% if supplier == product.supplier %}selected{% endif %}>{{ supplier.name }}</option>
{% endfor %}
</select>
</div>
<div class="col-md-4">
<label class="form-label small fw-bold">{% trans "Cost Price" %}</label>
<input type="number" step="0.001" name="cost_price" class="form-control rounded-3" value="{{ product.cost_price|floatformat:3 }}" required>
</div>
<div class="col-md-4">
<label class="form-label small fw-bold">{% trans "Sale Price" %}</label>
<input type="number" step="0.001" name="price" class="form-control rounded-3" value="{{ product.price|floatformat:3 }}" required>
</div>
<div class="col-md-4">
<label class="form-label small fw-bold">{% trans "Stock" %}</label>
<input type="number" name="stock_quantity" class="form-control rounded-3" step="0.01" value="{{ product.stock_quantity|floatformat:2 }}" required>
</div>
<div class="col-md-4">
<label class="form-label small fw-bold">{% trans "Stock Level (Alert)" %}</label>
<input type="number" name="min_stock_level" class="form-control rounded-3" step="0.01" value="{{ product.min_stock_level|floatformat:2 }}">
</div>
<div class="col-md-4">
<label class="form-label small fw-bold">{% trans "Opening Stock" %}</label>
<input type="number" name="opening_stock" class="form-control rounded-3" step="0.01" value="{{ product.opening_stock|floatformat:2 }}">
</div>
<div class="col-md-4">
<label class="form-label small fw-bold">{% trans "VAT (%)" %}</label>
<input type="number" step="0.01" name="vat" class="form-control rounded-3" value="{{ product.vat|floatformat:2 }}">
</div>
<div class="col-md-4">
<div class="form-check form-switch mt-4">
<input class="form-check-input" type="checkbox" name="is_active" id="isActiveCheck{{ product.id }}" {% if product.is_active %}checked{% endif %}>
<label class="form-check-label small fw-bold" for="isActiveCheck{{ product.id }}">{% trans "Active" %}</label>
</div>
</div>
<div class="col-12">
<label class="form-label small fw-bold">{% trans "Description" %}</label>
<textarea name="description" class="form-control rounded-3" rows="2">{{ product.description }}</textarea>
</div>
<div class="col-12">
<label class="form-label small fw-bold">{% trans "Update Image" %}</label>
<input type="file" name="image" class="form-control rounded-3" accept="image/*">
</div>
<div class="col-md-4">
<div class="form-check form-switch mt-4">
<input class="form-check-input" type="checkbox" name="has_expiry" id="hasExpiryCheck{{ product.id }}" {% if product.has_expiry %}checked{% endif %} onchange="document.getElementById('expiryDateDiv{{ product.id }}').style.display = this.checked ? 'block' : 'none'">
<label class="form-check-label small fw-bold" for="hasExpiryCheck{{ product.id }}">{% trans "Has Expiry Date" %}</label>
</div>
</div>
<div class="col-md-4" id="expiryDateDiv{{ product.id }}" style="display: {% if product.has_expiry %}block{% else %}none{% endif %};">
<label class="form-label small fw-bold">{% trans "Expiry Date" %}</label>
<input type="date" name="expiry_date" class="form-control rounded-3" value="{{ product.expiry_date|date:'Y-m-d' }}">
</div>
</div>
</div>
<div class="modal-footer border-0">
<button type="button" class="btn btn-light rounded-3" data-bs-dismiss="modal">{% trans "Cancel" %}</button>
<button type="submit" class="btn btn-primary rounded-3 px-4">{% trans "Save Changes" %}</button>
</div>
</form>
</div>
</div>
</div>
{% empty %}
<tr>
<td colspan="8" class="text-center py-5">
<i class="bi bi-box-seam text-muted opacity-25" style="font-size: 3rem;"></i>
<p class="mt-2 text-muted">{% trans "No products found." %}</p>
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
{% include "core/pagination.html" with page_obj=products %}
</div>
</div>
<!-- Categories Tab -->
<div class="tab-pane fade" id="categories-list" role="tabpanel">
<div class="card border-0 shadow-sm rounded-4">
<div class="table-responsive">
<table class="table table-hover align-middle mb-0" id="categoriesTable">
<thead class="bg-light">
<tr>
<th class="ps-4">{% trans "Category Name" %}</th>
<th>{% trans "Arabic Name" %}</th>
<th>{% trans "Slug" %}</th>
<th class="text-end pe-4">{% trans "Actions" %}</th>
</tr>
</thead>
<tbody>
{% for category in categories %}
<tr>
<td class="ps-4 fw-bold text-dark">{{ category.name_en }}</td>
<td dir="rtl">{{ category.name_ar }}</td>
<td><code>{{ category.slug }}</code></td>
<td class="text-end pe-4">
<div class="btn-group">
<button class="btn btn-sm btn-light rounded-pill px-2 me-1" data-bs-toggle="modal" data-bs-target="#editCategoryModal{{ category.id }}" title="{% trans 'Edit' %}">
<i class="bi bi-pencil text-success"></i>
</button>
<a href="{% url 'delete_category' category.id %}" class="btn btn-sm btn-light rounded-pill px-2" onclick="return confirm('{% trans 'Are you sure you want to delete this category?' %}')" title="{% trans 'Delete' %}">
<i class="bi bi-trash text-danger"></i>
</a>
</div>
</td>
</tr>
<!-- Edit Category Modal -->
<div class="modal fade" id="editCategoryModal{{ category.id }}" tabindex="-1" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content rounded-4 border-0 shadow">
<div class="modal-header border-0 pb-0">
<h5 class="modal-title fw-bold">{% trans "Edit Category" %}</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<form action="{% url 'edit_category' category.id %}" method="POST">
{% csrf_token %}
<div class="modal-body">
<div class="row g-3">
<div class="col-12">
<label class="form-label small fw-bold">{% trans "Name (English)" %}</label>
<input type="text" name="name_en" class="form-control rounded-3" value="{{ category.name_en }}" required>
</div>
<div class="col-12">
<label class="form-label small fw-bold">{% trans "Name (Arabic)" %}</label>
<input type="text" name="name_ar" class="form-control rounded-3" dir="rtl" value="{{ category.name_ar }}" required>
</div>
</div>
</div>
<div class="modal-footer border-0">
<button type="button" class="btn btn-light rounded-3" data-bs-dismiss="modal">{% trans "Cancel" %}</button>
<button type="submit" class="btn btn-primary rounded-3 px-4">{% trans "Save Changes" %}</button>
</div>
</form>
</div>
</div>
</div>
{% empty %}
<tr>
<td colspan="4" class="text-center py-4 text-muted">{% trans "No categories found." %}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
<!-- Units Tab -->
<div class="tab-pane fade" id="units-list" role="tabpanel">
<div class="card border-0 shadow-sm rounded-4">
<div class="table-responsive">
<table class="table table-hover align-middle mb-0" id="unitsTable">
<thead class="bg-light">
<tr>
<th class="ps-4">{% trans "Unit Name" %}</th>
<th>{% trans "Arabic Name" %}</th>
<th>{% trans "Short Name" %}</th>
<th class="text-end pe-4">{% trans "Actions" %}</th>
</tr>
</thead>
<tbody>
{% for unit in units %}
<tr>
<td class="ps-4 fw-bold text-dark">{{ unit.name_en }}</td>
<td dir="rtl">{{ unit.name_ar }}</td>
<td><span class="badge bg-light text-dark border">{{ unit.short_name }}</span></td>
<td class="text-end pe-4">
<div class="btn-group">
<button class="btn btn-sm btn-light rounded-pill px-2 me-1" data-bs-toggle="modal" data-bs-target="#editUnitModal{{ unit.id }}" title="{% trans 'Edit' %}">
<i class="bi bi-pencil text-success"></i>
</button>
<a href="{% url 'delete_unit' unit.id %}" class="btn btn-sm btn-light rounded-pill px-2" onclick="return confirm('{% trans 'Are you sure you want to delete this unit?' %}')" title="{% trans 'Delete' %}">
<i class="bi bi-trash text-danger"></i>
</a>
</div>
</td>
</tr>
{% empty %}
<tr>
<td colspan="4" class="text-center py-4 text-muted">{% trans "No units found." %}</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
<!-- Expired Items Tab -->
<div class="tab-pane fade" id="expired-list" role="tabpanel">
<div class="row mb-4">
<div class="col-md-6">
<div class="card border-0 shadow-sm rounded-4 bg-danger text-white">
<div class="card-body">
<h6 class="fw-bold mb-1">{% trans "Expired Items" %}</h6>
<h2 class="mb-0">{{ expired_products.count }}</h2>
</div>
</div>
</div>
<div class="col-md-6">
<div class="card border-0 shadow-sm rounded-4 bg-warning text-dark">
<div class="card-body">
<h6 class="fw-bold mb-1">{% trans "Expiring within 30 days" %}</h6>
<h2 class="mb-0">{{ expiring_soon_products.count }}</h2>
</div>
</div>
</div>
</div>
<div class="card border-0 shadow-sm rounded-4">
<div class="table-responsive">
<table class="table table-hover align-middle mb-0">
<thead class="bg-light">
<tr>
<th class="ps-4">{% trans "Item" %}</th>
<th>{% trans "SKU" %}</th>
<th>{% trans "Stock" %}</th>
<th>{% trans "Expiry Date" %}</th>
<th>{% trans "Status" %}</th>
</tr>
</thead>
<tbody>
{% for product in expired_products %}
<tr>
<td class="ps-4 fw-bold text-dark">{{ product.name_ar }} / {{ product.name_en }}</td>
<td><code>{{ product.sku }}</code></td>
<td>{{ product.stock_quantity|floatformat:2 }} {{ product.unit.short_name }}</td>
<td class="text-danger fw-bold">{{ product.expiry_date|date:"Y-m-d" }}</td>
<td><span class="badge bg-danger">{% trans "Expired" %}</span></td>
</tr>
{% empty %}
{% endfor %}
{% for product in expiring_soon_products %}
<tr>
<td class="ps-4 fw-bold text-dark">{{ product.name_ar }} / {{ product.name_en }}</td>
<td><code>{{ product.sku }}</code></td>
<td>{{ product.stock_quantity|floatformat:2 }} {{ product.unit.short_name }}</td>
<td class="text-warning fw-bold">{{ product.expiry_date|date:"Y-m-d" }}</td>
<td><span class="badge bg-warning text-dark">{% trans "Expiring Soon" %}</span></td>
</tr>
{% empty %}
{% if not expired_products %}
<tr>
<td colspan="5" class="text-center py-4 text-muted">{% trans "No expired or expiring items found." %}</td>
</tr>
{% endif %}
{% endfor %}
</tbody>
</table>
</div>
</div>
</div>
</div>
</div>
<!-- Modals -->
<!-- Add Category Modal -->
<div class="modal fade" id="addCategoryModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content rounded-4 border-0 shadow">
<div class="modal-header border-0 pb-0">
<h5 class="modal-title fw-bold">{% trans "Add New Category" %}</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div class="row g-3">
<div class="col-12">
<label class="form-label small fw-bold">{% trans "Name (English)" %}</label>
<input type="text" id="addCatNameEn" class="form-control rounded-3" required>
</div>
<div class="col-12">
<label class="form-label small fw-bold">{% trans "Name (Arabic)" %}</label>
<input type="text" id="addCatNameAr" class="form-control rounded-3" dir="rtl" required>
</div>
</div>
</div>
<div class="modal-footer border-0">
<button type="button" class="btn btn-light rounded-3" data-bs-dismiss="modal">{% trans "Close" %}</button>
<button type="button" class="btn btn-outline-primary rounded-3" id="saveAndAddAnotherCat">{% trans "Save & Add Another" %}</button>
<button type="button" class="btn btn-primary rounded-3 px-4" id="saveCat">{% trans "Save" %}</button>
</div>
</div>
</div>
</div>
<!-- Add Unit Modal -->
<div class="modal fade" id="addUnitModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content rounded-4 border-0 shadow">
<div class="modal-header border-0 pb-0">
<h5 class="modal-title fw-bold">{% trans "Add New Unit" %}</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<div class="row g-3">
<div class="col-12">
<label class="form-label small fw-bold">{% trans "Name (English)" %}</label>
<input type="text" id="addUnitNameEn" class="form-control rounded-3" required>
</div>
<div class="col-12">
<label class="form-label small fw-bold">{% trans "Name (Arabic)" %}</label>
<input type="text" id="addUnitNameAr" class="form-control rounded-3" dir="rtl" required>
</div>
<div class="col-12">
<label class="form-label small fw-bold">{% trans "Short Name (e.g., kg, pcs)" %}</label>
<input type="text" id="addUnitShortName" class="form-control rounded-3" required>
</div>
</div>
</div>
<div class="modal-footer border-0">
<button type="button" class="btn btn-light rounded-3" data-bs-dismiss="modal">{% trans "Close" %}</button>
<button type="button" class="btn btn-outline-primary rounded-3" id="saveAndAddAnotherUnit">{% trans "Save & Add Another" %}</button>
<button type="button" class="btn btn-primary rounded-3 px-4" id="saveUnit">{% trans "Save" %}</button>
</div>
</div>
</div>
</div>
<!-- Add Product Modal -->
<div class="modal fade" id="addProductModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog modal-xl">
<div class="modal-content rounded-4 border-0 shadow">
<div class="modal-header border-0 pb-0">
<h5 class="modal-title fw-bold">{% trans "Add New Item" %}</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<form action="{% url 'add_product' %}" method="POST" enctype="multipart/form-data">
{% csrf_token %}
<div class="modal-body">
<div class="row g-3">
<div class="col-12"><h6 class="fw-bold text-primary mb-0 mt-2">{% trans "Basic Information" %}</h6><hr class="my-2"></div>
<div class="col-md-6">
<label class="form-label small fw-bold">{% trans "Name (English)" %}</label>
<input type="text" name="name_en" class="form-control rounded-3" required>
</div>
<div class="col-md-6">
<label class="form-label small fw-bold">{% trans "Name (Arabic)" %}</label>
<input type="text" name="name_ar" class="form-control rounded-3" dir="rtl" required>
</div>
<div class="col-md-4">
<label class="form-label small fw-bold">{% trans "Barcode / SKU" %}</label>
<div class="input-group">
<input type="text" name="sku" id="skuInput" class="form-control rounded-3">
<button class="btn btn-outline-primary" type="button" id="suggestSkuBtn"><i class="bi bi-magic"></i></button>
</div>
</div>
<div class="col-md-4">
<label class="form-label small fw-bold">{% trans "Category" %}</label>
<select name="category" id="categorySelect" class="form-select rounded-3" required>
<option value="">{% trans "Select Category" %}</option>
{% for category in categories %}
<option value="{{ category.id }}">{{ category.name_ar }} / {{ category.name_en }}</option>
{% endfor %}
</select>
</div>
<div class="col-md-4">
<label class="form-label small fw-bold">{% trans "Unit" %}</label>
<select name="unit" id="unitSelect" class="form-select rounded-3">
<option value="">{% trans "Select Unit" %}</option>
{% for unit in units %}
<option value="{{ unit.id }}">{{ unit.name_ar }} / {{ unit.name_en }}</option>
{% endfor %}
</select>
</div>
<div class="col-md-4">
<label class="form-label small fw-bold">{% trans "Supplier" %}</label>
<select name="supplier" class="form-select rounded-3">
<option value="">{% trans "Select Supplier" %}</option>
{% for supplier in suppliers %}
<option value="{{ supplier.id }}">{{ supplier.name }}</option>
{% endfor %}
</select>
</div>
<div class="col-md-4">
<label class="form-label small fw-bold">{% trans "Cost Price" %}</label>
<input type="number" step="0.001" name="cost_price" class="form-control rounded-3" value="0.000" required>
</div>
<div class="col-md-4">
<label class="form-label small fw-bold">{% trans "Sale Price" %}</label>
<input type="number" step="0.001" name="price" class="form-control rounded-3" value="0.000" required>
</div>
<div class="col-md-4">
<label class="form-label small fw-bold">{% trans "Stock" %}</label>
<input type="number" name="stock_quantity" class="form-control rounded-3" step="0.01" value="0" required>
</div>
<div class="col-md-4">
<label class="form-label small fw-bold">{% trans "Stock Level (Alert)" %}</label>
<input type="number" name="min_stock_level" class="form-control rounded-3" step="0.01" value="0">
</div>
<div class="col-md-4">
<label class="form-label small fw-bold">{% trans "Opening Stock" %}</label>
<input type="number" name="opening_stock" class="form-control rounded-3" step="0.01" value="0">
</div>
<div class="col-md-4">
<label class="form-label small fw-bold">{% trans "VAT (%)" %}</label>
<input type="number" step="0.01" name="vat" class="form-control rounded-3" value="0.00">
</div>
<div class="col-md-4">
<div class="form-check form-switch mt-4">
<input class="form-check-input" type="checkbox" name="is_active" id="isActiveCheckAdd" checked>
<label class="form-check-label small fw-bold" for="isActiveCheckAdd">{% trans "Active" %}</label>
</div>
</div>
<div class="col-12">
<label class="form-label small fw-bold">{% trans "Description" %}</label>
<textarea name="description" class="form-control rounded-3" rows="2"></textarea>
</div>
<div class="col-12">
<label class="form-label small fw-bold">{% trans "Product Image" %}</label>
<input type="file" name="image" class="form-control rounded-3" accept="image/*">
</div>
<div class="col-md-4">
<div class="form-check form-switch mt-4">
<input class="form-check-input" type="checkbox" name="has_expiry" id="hasExpiryCheck">
<label class="form-check-label small fw-bold" for="hasExpiryCheck">{% trans "Has Expiry Date" %}</label>
</div>
</div>
<div class="col-md-4" id="expiryDateDiv" style="display: none;">
<label class="form-label small fw-bold">{% trans "Expiry Date" %}</label>
<input type="date" name="expiry_date" class="form-control rounded-3">
</div>
</div>
</div>
<div class="modal-footer border-0">
<button type="button" class="btn btn-light rounded-3" data-bs-dismiss="modal">{% trans "Cancel" %}</button>
<button type="submit" class="btn btn-primary rounded-3 px-4">{% trans "Save Product" %}</button>
</div>
</form>
</div>
</div>
</div>
<!-- Import Modal -->
<div class="modal fade" id="importModal" tabindex="-1" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content rounded-4 border-0 shadow">
<div class="modal-header border-0 pb-0">
<h5 class="modal-title fw-bold">{% trans "Import Items" %}</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<form action="{% url 'import_products' %}" method="POST" enctype="multipart/form-data">
{% csrf_token %}
<div class="modal-body">
<div class="mb-3">
<label class="form-label small fw-bold">{% trans "Excel File (.xlsx)" %}</label>
<input type="file" name="excel_file" class="form-control rounded-3" accept=".xlsx" required>
</div>
</div>
<div class="modal-footer border-0">
<button type="button" class="btn btn-light rounded-3" data-bs-dismiss="modal">{% trans "Cancel" %}</button>
<button type="submit" class="btn btn-success rounded-3 px-4">{% trans "Import" %}</button>
</div>
</form>
</div>
</div>
</div>
{% endblock %}
{% block scripts %}
<script>
document.addEventListener('DOMContentLoaded', function() {
// Tab persistence
var hash = window.location.hash;
if (hash) {
var triggerEl = document.querySelector('button[data-bs-target="' + hash + '"]');
if (triggerEl) {
var tab = new bootstrap.Tab(triggerEl);
tab.show();
}
}
var tabEls = document.querySelectorAll('button[data-bs-toggle="tab"]');
tabEls.forEach(function(el) {
el.addEventListener('shown.bs.tab', function(event) {
window.location.hash = event.target.getAttribute('data-bs-target');
});
});
// AJAX Save Functions
async function saveCategory(stayOpen = false) {
const nameEn = document.getElementById('addCatNameEn').value;
const nameAr = document.getElementById('addCatNameAr').value;
if (!nameEn || !nameAr) return alert('Please fill all fields');
const response = await fetch('{% url "add_category_ajax" %}', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'X-CSRFToken': '{{ csrf_token }}' },
body: JSON.stringify({ name_en: nameEn, name_ar: nameAr })
});
const data = await response.json();
if (data.success) {
if (stayOpen) {
document.getElementById('addCatNameEn').value = '';
document.getElementById('addCatNameAr').value = '';
alert('{% trans "Category added. You can add another one." %}');
} else {
window.location.reload();
}
} else {
alert('Error: ' + data.error);
}
}
async function saveUnit(stayOpen = false) {
const nameEn = document.getElementById('addUnitNameEn').value;
const nameAr = document.getElementById('addUnitNameAr').value;
const shortName = document.getElementById('addUnitShortName').value;
if (!nameEn || !nameAr || !shortName) return alert('Please fill all fields');
const response = await fetch('{% url "add_unit_ajax" %}', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'X-CSRFToken': '{{ csrf_token }}' },
body: JSON.stringify({ name_en: nameEn, name_ar: nameAr, short_name: shortName })
});
const data = await response.json();
if (data.success) {
if (stayOpen) {
document.getElementById('addUnitNameEn').value = '';
document.getElementById('addUnitNameAr').value = '';
document.getElementById('addUnitShortName').value = '';
alert('{% trans "Unit added. You can add another one." %}');
} else {
window.location.reload();
}
} else {
alert('Error: ' + data.error);
}
}
document.getElementById('saveCat').onclick = () => saveCategory(false);
document.getElementById('saveAndAddAnotherCat').onclick = () => saveCategory(true);
document.getElementById('saveUnit').onclick = () => saveUnit(false);
document.getElementById('saveAndAddAnotherUnit').onclick = () => saveUnit(true);
// Expiry Date Toggle
const hasExpiryCheck = document.getElementById('hasExpiryCheck');
const expiryDateDiv = document.getElementById('expiryDateDiv');
if (hasExpiryCheck && expiryDateDiv) {
hasExpiryCheck.onchange = function() {
expiryDateDiv.style.display = this.checked ? 'block' : 'none';
};
}
// SKU Suggestion
const suggestBtn = document.getElementById('suggestSkuBtn');
if (suggestBtn) {
suggestBtn.onclick = () => {
fetch('{% url "suggest_sku" %}')
.then(r => r.json())
.then(d => document.getElementById('skuInput').value = d.sku);
};
}
});
</script>
{% endblock %}