Новая архитектура: - ShowcaseItem модель - физический экземпляр букета на витрине - OneToOneField(sold_order_item) - БД-уровневая защита от двойной продажи - Поддержка создания нескольких экземпляров одного букета - Возможность продавать N из M доступных (например 2 из 5) Изменения: - inventory/models.py: добавлена модель ShowcaseItem с методами lock/unlock/mark_sold - inventory/services/showcase_manager.py: переработан для работы с ShowcaseItem - pos/views.py: API поддерживает quantity и showcase_item_ids - pos/templates/pos/terminal.html: поле "Сколько букетов создать" - pos/static/pos/js/terminal.js: выбор количества, передача showcase_item_ids Миграции: - 0007: создание модели ShowcaseItem - 0008: data migration существующих букетов - 0009: очистка ShowcaseItem для уже проданных букетов 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
509 lines
24 KiB
HTML
509 lines
24 KiB
HTML
{% extends 'base.html' %}
|
||
{% load static %}
|
||
{% block title %}POS Terminal{% endblock %}
|
||
|
||
{% block extra_css %}
|
||
<link rel="stylesheet" href="{% static 'pos/css/terminal.css' %}">
|
||
{% endblock %}
|
||
|
||
{% block content %}
|
||
<!-- Main POS Container -->
|
||
<div class="pos-main-container">
|
||
<div class="pos-container">
|
||
<div class="row g-3" style="height: 100%;">
|
||
<!-- Products Grid (Left side - 8/12) -->
|
||
<div class="col-md-8" style="display: flex; flex-direction: column; height: 100%;">
|
||
<!-- Search Box -->
|
||
<div class="mb-3">
|
||
<div class="input-group">
|
||
<input type="text" class="form-control" id="searchInput" placeholder="Поиск по товарам (мин. 3 символа)...">
|
||
<button class="btn btn-outline-secondary" type="button" id="clearSearchBtn" style="display: none;">
|
||
<i class="bi bi-x-lg"></i>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Categories -->
|
||
<div class="mb-3">
|
||
<div class="row g-3" id="categoryGrid"></div>
|
||
</div>
|
||
|
||
<!-- Products Grid (Блок товаров) - Прокручиваемая область -->
|
||
<div class="products-scrollable">
|
||
<div class="row g-3" id="productGrid"></div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Right Panel (4/12) - Fixed -->
|
||
<div class="col-md-4">
|
||
<div class="right-panel-fixed d-flex flex-column">
|
||
<!-- Информация о складе (всегда показываем блок для фиксированной позиции) -->
|
||
<div class="card mb-2">
|
||
<div class="card-body py-2 px-3 d-flex justify-content-between align-items-center">
|
||
{% if current_warehouse %}
|
||
<div>
|
||
<small class="text-muted d-block" style="font-size: 0.75rem;">Склад:</small>
|
||
<strong style="font-size: 0.95rem;">{{ current_warehouse.name }}</strong>
|
||
</div>
|
||
<button class="btn btn-sm btn-outline-secondary" id="changeWarehouseBtn" style="font-size: 0.75rem;">
|
||
<i class="bi bi-arrow-left-right"></i> Сменить
|
||
</button>
|
||
{% else %}
|
||
<div class="text-danger">
|
||
<small class="d-block" style="font-size: 0.75rem;">Склад:</small>
|
||
<strong style="font-size: 0.95rem;"><i class="bi bi-exclamation-triangle me-1"></i>Не выбран</strong>
|
||
</div>
|
||
{% endif %}
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Cart Panel -->
|
||
<div class="card mb-2 flex-grow-1" style="min-height: 0;">
|
||
<div class="card-header bg-white d-flex justify-content-between align-items-center">
|
||
<h6 class="mb-0">Корзина</h6>
|
||
<div class="d-flex gap-1 align-items-center">
|
||
<button class="btn btn-outline-primary btn-sm d-flex align-items-center" id="customerSelectBtn">
|
||
<i class="bi bi-person me-1"></i>
|
||
<div class="d-flex flex-column align-items-start lh-1">
|
||
<small class="text-muted" style="font-size: 0.65rem;">Клиент</small>
|
||
<span id="customerSelectBtnText" class="fw-semibold">Выбрать</span>
|
||
</div>
|
||
</button>
|
||
<a href="#" id="customerProfileLink" class="btn btn-sm btn-outline-secondary" title="Открыть анкету клиента" target="_blank" style="display: none;">
|
||
<i class="bi bi-box-arrow-up-right"></i>
|
||
</a>
|
||
<button class="btn btn-sm btn-outline-danger" id="resetCustomerBtn" title="Сбросить на системного клиента" style="display: none;">
|
||
<i class="bi bi-x-lg"></i>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
<div class="card-body d-flex flex-column" style="min-height: 0;">
|
||
<div id="cartList" class="flex-grow-1" style="overflow-y: auto;"></div>
|
||
|
||
<div class="mt-auto">
|
||
<div class="d-flex justify-content-between align-items-center py-1 border-top">
|
||
<strong class="mb-0">Итого:</strong>
|
||
<strong class="mb-0 text-primary fs-5" id="cartTotal">0.00</strong>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Action Buttons Panel -->
|
||
<div class="card action-buttons-panel">
|
||
<div class="card-body p-2">
|
||
<div class="row g-2">
|
||
<div class="col-4">
|
||
<button class="btn btn-outline-warning rounded-3 w-100" id="addToShowcaseBtn" style="height: 60px;">
|
||
<i class="bi bi-flower1"></i><br>На витрину
|
||
</button>
|
||
</div>
|
||
<div class="col-4">
|
||
<button class="btn btn-outline-secondary rounded-3 w-100" style="height: 60px;">
|
||
</button>
|
||
</div>
|
||
<div class="col-4">
|
||
<button class="btn btn-outline-secondary rounded-3 w-100" style="height: 60px;">
|
||
</button>
|
||
</div>
|
||
<div class="col-4">
|
||
<button class="btn btn-outline-secondary rounded-3 w-100" style="height: 60px;">
|
||
</button>
|
||
</div>
|
||
<div class="col-4">
|
||
<button class="btn btn-outline-secondary rounded-3 w-100" style="height: 60px;">
|
||
</button>
|
||
</div>
|
||
<div class="col-4">
|
||
<button class="btn btn-outline-primary rounded-3 w-100" id="scheduleLater" style="height: 60px;">
|
||
<i class="bi bi-calendar2"></i><br>Отложенный заказ
|
||
</button>
|
||
</div>
|
||
<div class="col-4">
|
||
<button class="btn btn-outline-secondary rounded-3 w-100" id="clearCart" style="height: 60px;">
|
||
<i class="bi bi-trash"></i><br>Очистить
|
||
</button>
|
||
</div>
|
||
<div class="col-4">
|
||
<button class="btn btn-outline-secondary rounded-3 w-100" style="height: 60px;">
|
||
</button>
|
||
</div>
|
||
<div class="col-4">
|
||
<button class="btn btn-success rounded-3 w-100" id="checkoutNow" style="height: 60px;">
|
||
<i class="bi bi-check2-circle"></i><br>Продать
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Modal: Создание временного комплекта на витрину -->
|
||
<div class="modal fade" id="createTempKitModal" tabindex="-1" aria-labelledby="createTempKitModalLabel" aria-hidden="true">
|
||
<div class="modal-dialog modal-xl">
|
||
<div class="modal-content">
|
||
<div class="modal-header">
|
||
<h5 class="modal-title" id="createTempKitModalLabel">
|
||
<i class="bi bi-flower1"></i> Создать временный комплект на витрину
|
||
</h5>
|
||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||
</div>
|
||
<div class="modal-body">
|
||
<div class="row">
|
||
<!-- Левая колонка: основные поля -->
|
||
<div class="col-md-6">
|
||
<!-- Название комплекта -->
|
||
<div class="mb-3">
|
||
<label for="tempKitName" class="form-label">Название комплекта *</label>
|
||
<input type="text" class="form-control" id="tempKitName" placeholder="Введите название" required>
|
||
</div>
|
||
|
||
<!-- Выбор витрины -->
|
||
<div class="mb-3">
|
||
<label for="showcaseSelect" class="form-label">Витрина *</label>
|
||
<select class="form-select" id="showcaseSelect" required>
|
||
<option value="">Загрузка...</option>
|
||
</select>
|
||
</div>
|
||
|
||
<!-- Количество букетов -->
|
||
<div class="mb-3">
|
||
<label for="showcaseKitQuantity" class="form-label">Сколько букетов создать</label>
|
||
<input type="number" class="form-control" id="showcaseKitQuantity" value="1" min="1" max="99">
|
||
<small class="text-muted">Будет создано указанное количество одинаковых букетов на витрину</small>
|
||
</div>
|
||
|
||
<!-- Описание -->
|
||
<div class="mb-3">
|
||
<label for="tempKitDescription" class="form-label">Описание (опционально)</label>
|
||
<textarea class="form-control" id="tempKitDescription" rows="3" placeholder="Краткое описание комплекта"></textarea>
|
||
</div>
|
||
|
||
<!-- Загрузка фото -->
|
||
<div class="mb-3">
|
||
<label for="tempKitPhoto" class="form-label">Фото комплекта (опционально)</label>
|
||
<input type="file" class="form-control" id="tempKitPhoto" accept="image/*">
|
||
<div id="photoPreview" class="mt-2" style="display: none;">
|
||
<img id="photoPreviewImg" src="" alt="Preview" class="img-thumbnail" style="max-width: 200px; max-height: 200px;">
|
||
<button type="button" class="btn btn-sm btn-danger ms-2" id="removePhoto">
|
||
<i class="bi bi-x"></i> Удалить
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Правая колонка: цены и состав -->
|
||
<div class="col-md-6">
|
||
<!-- Список товаров в корзине -->
|
||
<div class="mb-3">
|
||
<label class="form-label">Товары в комплекте</label>
|
||
<div class="border rounded p-2" id="tempKitItemsList" style="max-height: 200px; overflow-y: auto; background: #f8f9fa;">
|
||
<!-- Динамически заполняется через JS -->
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Блок ценообразования -->
|
||
<div class="card">
|
||
<div class="card-header bg-light">
|
||
<strong>Ценообразование</strong>
|
||
</div>
|
||
<div class="card-body">
|
||
<!-- Базовая цена -->
|
||
<div class="mb-2">
|
||
<small class="text-muted">Базовая цена (сумма компонентов):</small>
|
||
<div class="fw-bold" id="tempKitBasePrice">0.00 руб.</div>
|
||
</div>
|
||
|
||
<!-- Корректировка цены -->
|
||
<div class="mb-2">
|
||
<label for="priceAdjustmentType" class="form-label small">Корректировка цены</label>
|
||
<select class="form-select form-select-sm" id="priceAdjustmentType">
|
||
<option value="none">Без изменения</option>
|
||
<option value="increase_percent">Увеличить на %</option>
|
||
<option value="increase_amount">Увеличить на сумму</option>
|
||
<option value="decrease_percent">Уменьшить на %</option>
|
||
<option value="decrease_amount">Уменьшить на сумму</option>
|
||
</select>
|
||
</div>
|
||
|
||
<div class="mb-2" id="adjustmentValueBlock" style="display: none;">
|
||
<label for="priceAdjustmentValue" class="form-label small">Значение</label>
|
||
<input type="number" class="form-control form-control-sm" id="priceAdjustmentValue"
|
||
min="0" step="0.01" value="0" placeholder="0.00">
|
||
</div>
|
||
|
||
<!-- Расчётная цена с корректировкой -->
|
||
<div class="mb-2 pb-2 border-bottom">
|
||
<small class="text-muted">Расчётная цена:</small>
|
||
<div class="fw-bold text-primary" id="tempKitCalculatedPrice">0.00 руб.</div>
|
||
</div>
|
||
|
||
<!-- Ручная финальная цена (sale_price) -->
|
||
<div class="mb-0">
|
||
<div class="form-check form-switch mb-2">
|
||
<input class="form-check-input" type="checkbox" id="useSalePrice">
|
||
<label class="form-check-label small" for="useSalePrice">
|
||
Установить свою цену (приоритет)
|
||
</label>
|
||
</div>
|
||
<div id="salePriceBlock" style="display: none;">
|
||
<input type="number" class="form-control form-control-sm" id="salePrice"
|
||
min="0" step="0.01" placeholder="Введите цену">
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Итоговая цена продажи -->
|
||
<div class="alert alert-success mt-3 mb-0">
|
||
<strong>Итоговая цена продажи:</strong><br>
|
||
<span class="fs-4" id="tempKitFinalPrice">0.00</span> руб.
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="modal-footer">
|
||
<!-- Кнопка "Разобрать" (отображается только в режиме редактирования) -->
|
||
<button type="button" class="btn btn-danger me-auto" id="disassembleKitBtn" style="display: none;">
|
||
<i class="bi bi-scissors"></i> Разобрать букет
|
||
</button>
|
||
|
||
<!-- Правая группа кнопок -->
|
||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Отмена</button>
|
||
<button type="button" class="btn btn-primary" id="confirmCreateTempKit">
|
||
<i class="bi bi-check-circle"></i> Создать и зарезервировать
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Модалка: Продажа -->
|
||
<div class="modal fade" id="checkoutModal" tabindex="-1" aria-labelledby="checkoutModalLabel" aria-hidden="true">
|
||
<div class="modal-dialog modal-dialog-centered modal-lg" style="max-width: 70vw;">
|
||
<div class="modal-content" style="max-height: 90vh; overflow: hidden;">
|
||
<div class="modal-header py-2">
|
||
<h5 class="modal-title" id="checkoutModalLabel">
|
||
<i class="bi bi-cash-stack"></i> Продажа
|
||
</h5>
|
||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||
</div>
|
||
<div class="modal-body py-2" style="overflow-y: auto;">
|
||
<div class="row g-3">
|
||
<!-- Левая колонка: состав заказа -->
|
||
<div class="col-md-7">
|
||
<!-- Информация о клиенте и баланс в одной строке -->
|
||
<div class="row g-2 mb-2">
|
||
<div class="col-auto">
|
||
<label class="form-label fw-semibold small mb-1">Клиент</label>
|
||
<div class="d-flex gap-1">
|
||
<button class="btn btn-outline-primary btn-sm" id="checkoutCustomerSelectBtn" style="font-size: 0.85rem; padding: 0.25rem 0.5rem;">
|
||
<i class="bi bi-person me-1"></i>
|
||
<span id="checkoutCustomerSelectBtnText">Выбрать</span>
|
||
</button>
|
||
<button class="btn btn-sm btn-outline-danger" id="checkoutResetCustomerBtn" title="Сброс" style="display: none; font-size: 0.85rem; padding: 0.25rem 0.5rem;">
|
||
<i class="bi bi-x-lg"></i>
|
||
</button>
|
||
</div>
|
||
</div>
|
||
<div class="col" id="checkoutWalletBalance" style="display: none;">
|
||
<label class="form-label fw-semibold small mb-1">Баланс кошелька</label>
|
||
<div class="alert alert-info py-1 px-2 mb-0" style="font-size: 0.9rem;">
|
||
<i class="bi bi-wallet2"></i>
|
||
<span id="checkoutWalletBalanceAmount">0.00</span> руб.
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Состав заказа -->
|
||
<div class="mb-2">
|
||
<strong class="small">Состав заказа</strong>
|
||
<div class="border rounded p-2 mt-1" id="checkoutItems" style="max-height: 180px; overflow-y: auto; background: #f8f9fa; font-size: 0.9rem;">
|
||
<!-- Заполняется из JS -->
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Комментарий к заказу -->
|
||
<div class="mb-2">
|
||
<label for="orderNote" class="form-label small mb-1">Комментарий</label>
|
||
<input type="text" class="form-control form-control-sm" id="orderNote" placeholder="Примечание к заказу">
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Правая колонка: оплата -->
|
||
<div class="col-md-5">
|
||
<div class="card mb-0">
|
||
<div class="card-header bg-light py-2">
|
||
<strong class="small">Оплата</strong>
|
||
</div>
|
||
<div class="card-body p-2">
|
||
<!-- Итого к оплате -->
|
||
<div class="mb-2 pb-2 border-bottom">
|
||
<small class="text-muted">Итого к оплате:</small>
|
||
<div class="fw-bold text-success fs-5" id="checkoutFinalPrice">0.00 руб.</div>
|
||
</div>
|
||
|
||
<!-- Переключатель режима -->
|
||
<div class="mb-2">
|
||
<label class="form-label fw-semibold small mb-1">Режим оплаты</label>
|
||
<div class="btn-group w-100" role="group">
|
||
<button type="button"
|
||
class="btn btn-sm btn-outline-primary active"
|
||
id="singlePaymentMode">
|
||
Одним способом
|
||
</button>
|
||
<button type="button"
|
||
class="btn btn-sm btn-outline-primary"
|
||
id="mixedPaymentMode">
|
||
Смешанная
|
||
</button>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Контейнер для PaymentWidget -->
|
||
<div id="paymentWidgetContainer"></div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
<div class="modal-footer py-2">
|
||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Отмена</button>
|
||
<button type="button" class="btn btn-success" id="confirmCheckoutBtn">
|
||
<i class="bi bi-check2-circle"></i> Подтвердить продажу
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Модалка: Выбор склада -->
|
||
<div class="modal fade" id="selectWarehouseModal" tabindex="-1" aria-labelledby="selectWarehouseModalLabel" aria-hidden="true">
|
||
<div class="modal-dialog">
|
||
<div class="modal-content">
|
||
<div class="modal-header">
|
||
<h5 class="modal-title" id="selectWarehouseModalLabel">
|
||
<i class="bi bi-building"></i> Выбор склада
|
||
</h5>
|
||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||
</div>
|
||
<div class="modal-body">
|
||
<div class="list-group" id="warehouseList">
|
||
{% for warehouse in warehouses %}
|
||
<button type="button" class="list-group-item list-group-item-action d-flex justify-content-between align-items-center warehouse-item"
|
||
data-warehouse-id="{{ warehouse.id }}"
|
||
data-warehouse-name="{{ warehouse.name }}">
|
||
<div>
|
||
<strong>{{ warehouse.name }}</strong>
|
||
{% if warehouse.is_default %}
|
||
<span class="badge bg-warning text-dark ms-2">По умолчанию</span>
|
||
{% endif %}
|
||
</div>
|
||
{% if warehouse.id == current_warehouse.id %}
|
||
<i class="bi bi-check-circle-fill text-success"></i>
|
||
{% endif %}
|
||
</button>
|
||
{% endfor %}
|
||
</div>
|
||
</div>
|
||
<div class="modal-footer">
|
||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Отмена</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Модалка: Выбор клиента -->
|
||
<div class="modal fade" id="selectCustomerModal" tabindex="-1" aria-labelledby="selectCustomerModalLabel" aria-hidden="true">
|
||
<div class="modal-dialog">
|
||
<div class="modal-content">
|
||
<div class="modal-header">
|
||
<h5 class="modal-title" id="selectCustomerModalLabel">
|
||
<i class="bi bi-person-search"></i> Выбор клиента
|
||
</h5>
|
||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||
</div>
|
||
<div class="modal-body">
|
||
<div class="mb-3">
|
||
<label for="customerSearchInput" class="form-label">Поиск клиента</label>
|
||
<input type="text" class="form-select" id="customerSearchInput"
|
||
placeholder="Начните вводить имя, телефон или email (минимум 3 символа)">
|
||
</div>
|
||
|
||
<div class="d-grid gap-2">
|
||
<button type="button" class="btn btn-outline-success" id="createNewCustomerBtn">
|
||
<i class="bi bi-person-plus"></i> Создать нового клиента
|
||
</button>
|
||
<button type="button" class="btn btn-outline-secondary" id="selectSystemCustomerBtn">
|
||
<i class="bi bi-person"></i> Выбрать системного клиента (анонимный)
|
||
</button>
|
||
</div>
|
||
</div>
|
||
<div class="modal-footer">
|
||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Отмена</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
<!-- Модалка: Создание нового клиента -->
|
||
<div class="modal fade" id="createCustomerModal" tabindex="-1" aria-labelledby="createCustomerModalLabel" aria-hidden="true">
|
||
<div class="modal-dialog">
|
||
<div class="modal-content">
|
||
<div class="modal-header">
|
||
<h5 class="modal-title" id="createCustomerModalLabel">
|
||
<i class="bi bi-person-plus"></i> Создать клиента
|
||
</h5>
|
||
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||
</div>
|
||
<div class="modal-body">
|
||
<div class="mb-3">
|
||
<label for="newCustomerName" class="form-label">Имя *</label>
|
||
<input type="text" class="form-control" id="newCustomerName" placeholder="Введите имя клиента" required>
|
||
</div>
|
||
|
||
<div class="mb-3">
|
||
<label for="newCustomerPhone" class="form-label">Телефон</label>
|
||
<input type="text" class="form-control" id="newCustomerPhone" placeholder="+375XXXXXXXXX">
|
||
</div>
|
||
|
||
<div class="mb-3">
|
||
<label for="newCustomerEmail" class="form-label">Email</label>
|
||
<input type="email" class="form-control" id="newCustomerEmail" placeholder="email@example.com">
|
||
</div>
|
||
|
||
<div id="createCustomerError" class="alert alert-danger d-none"></div>
|
||
</div>
|
||
<div class="modal-footer">
|
||
<button type="button" class="btn btn-secondary" data-bs-dismiss="modal">Отмена</button>
|
||
<button type="button" class="btn btn-primary" id="confirmCreateCustomerBtn">
|
||
<i class="bi bi-check-circle"></i> Создать
|
||
</button>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
{% endblock %}
|
||
|
||
{% block extra_js %}
|
||
<!-- Hidden data containers for JavaScript -->
|
||
<script id="categoriesData" type="application/json">{{ categories_json|safe }}</script>
|
||
<script id="itemsData" type="application/json">{{ items_json|safe }}</script>
|
||
<script id="showcaseKitsData" type="application/json">{{ showcase_kits_json|safe }}</script>
|
||
<script id="systemCustomerData" type="application/json">{{ system_customer_json|safe }}</script>
|
||
<script id="selectedCustomerData" type="application/json">{{ selected_customer_json|safe }}</script>
|
||
<script id="cartData" type="application/json">{{ cart_data|safe }}</script>
|
||
<script id="currentWarehouseData" type="application/json">
|
||
{
|
||
"id": {% if current_warehouse %}{{ current_warehouse.id }}{% else %}null{% endif %},
|
||
"name": "{% if current_warehouse %}{{ current_warehouse.name|escapejs }}{% else %}""{% endif %}"
|
||
}
|
||
</script>
|
||
|
||
<script src="{% static 'pos/js/terminal.js' %}"></script>
|
||
{% endblock %}
|