added barcode scaner

main
Artem-Darius Weber 1 day ago
parent d48ae7e3a1
commit 9c432e6cb8

@ -133,3 +133,167 @@ Watching for file changes with StatReloader
"GET /admin/jsi18n/ HTTP/1.1" 200 3342
"GET /admin/warehouse/stockoperation/statistics/ HTTP/1.1" 200 28103
"GET /admin/warehouse/stockoperation/ HTTP/1.1" 200 15416
Watching for file changes with StatReloader
"GET /admin/warehouse/stockoperation/ HTTP/1.1" 200 15416
"GET /admin/warehouse/stockoperation/ HTTP/1.1" 200 15416
"GET /admin/jsi18n/ HTTP/1.1" 200 3342
"GET /admin/ HTTP/1.1" 200 12404
"GET /admin/goods_reception/goodsreception/ HTTP/1.1" 200 14746
"GET /admin/jsi18n/ HTTP/1.1" 200 3342
"GET /admin/product_directory/product/ HTTP/1.1" 200 12854
"GET /admin/jsi18n/ HTTP/1.1" 200 3342
"GET /admin/warehouse/storagelocation/ HTTP/1.1" 200 13458
"GET /admin/jsi18n/ HTTP/1.1" 200 3342
"GET /admin/warehouse/warehouse/ HTTP/1.1" 200 12479
"GET /admin/jsi18n/ HTTP/1.1" 200 3342
"GET /admin/warehouse/stockoperation/ HTTP/1.1" 200 15416
"GET /admin/jsi18n/ HTTP/1.1" 200 3342
"GET /admin/warehouse/stockoperation/statistics/ HTTP/1.1" 200 28103
"GET /admin/warehouse/stockoperation/ HTTP/1.1" 200 15416
"GET /admin/warehouse/stockoperation/?_facets=True HTTP/1.1" 200 15862
"GET /admin/jsi18n/ HTTP/1.1" 200 3342
"GET /static/admin/img/icon-hidelink.svg HTTP/1.1" 200 784
"GET /admin/warehouse/stockoperation/? HTTP/1.1" 200 15416
"GET /admin/jsi18n/ HTTP/1.1" 200 3342
"GET /admin/warehouse/stockoperation/?_facets=True HTTP/1.1" 200 15862
"GET /admin/jsi18n/ HTTP/1.1" 200 3342
"GET /admin/warehouse/stockoperation/? HTTP/1.1" 200 15416
"GET /admin/jsi18n/ HTTP/1.1" 200 3342
Not Found: /
"GET / HTTP/1.1" 404 2609
"GET /admin/warehouse/stockoperation/? HTTP/1.1" 200 15416
/Users/darius/Documents/franchise_store/warehouse/urls.py changed, reloading.
Watching for file changes with StatReloader
/Users/darius/Documents/franchise_store/warehouse/urls.py changed, reloading.
Watching for file changes with StatReloader
Not Found: /scan-barcode
"GET /scan-barcode HTTP/1.1" 404 2663
"GET /warehouse/scan-barcode HTTP/1.1" 301 0
Method Not Allowed (GET): /warehouse/scan-barcode/
Method Not Allowed: /warehouse/scan-barcode/
"GET /warehouse/scan-barcode/ HTTP/1.1" 405 0
Method Not Allowed (GET): /warehouse/scan-barcode/
Method Not Allowed: /warehouse/scan-barcode/
"GET /warehouse/scan-barcode/ HTTP/1.1" 405 0
/Users/darius/Documents/franchise_store/warehouse/urls.py changed, reloading.
Watching for file changes with StatReloader
/Users/darius/Documents/franchise_store/warehouse/urls.py changed, reloading.
Watching for file changes with StatReloader
Method Not Allowed (GET): /warehouse/scan-barcode/
Method Not Allowed: /warehouse/scan-barcode/
"GET /warehouse/scan-barcode/ HTTP/1.1" 405 0
Watching for file changes with StatReloader
Method Not Allowed (GET): /warehouse/scan-barcode/
Method Not Allowed: /warehouse/scan-barcode/
"GET /warehouse/scan-barcode/ HTTP/1.1" 405 0
"GET /warehouse/scan-barcode-page/ HTTP/1.1" 200 1745
/Users/darius/Documents/franchise_store/warehouse/views.py changed, reloading.
Watching for file changes with StatReloader
/Users/darius/Documents/franchise_store/warehouse/views.py changed, reloading.
Watching for file changes with StatReloader
/Users/darius/Documents/franchise_store/warehouse/views.py changed, reloading.
Watching for file changes with StatReloader
/Users/darius/Documents/franchise_store/warehouse/urls.py changed, reloading.
Watching for file changes with StatReloader
/Users/darius/Documents/franchise_store/warehouse/urls.py changed, reloading.
Watching for file changes with StatReloader
/Users/darius/Documents/franchise_store/warehouse/urls.py changed, reloading.
Watching for file changes with StatReloader
/Users/darius/Documents/franchise_store/warehouse/urls.py changed, reloading.
Watching for file changes with StatReloader
/Users/darius/Documents/franchise_store/warehouse/urls.py changed, reloading.
Watching for file changes with StatReloader
Not Found: /warehouse/scan-barcode-page/
"GET /warehouse/scan-barcode-page/ HTTP/1.1" 404 3373
"GET /warehouse/scan-barcode-camera/ HTTP/1.1" 200 3361
"GET /admin/ HTTP/1.1" 200 12404
"GET /admin/product_directory/product/ HTTP/1.1" 200 12854
"GET /admin/jsi18n/ HTTP/1.1" 200 3342
Internal Server Error: /warehouse/scan-barcode/
Traceback (most recent call last):
File "/Users/darius/anaconda3/envs/django_env/lib/python3.10/site-packages/django/core/handlers/exception.py", line 55, in inner
response = get_response(request)
File "/Users/darius/anaconda3/envs/django_env/lib/python3.10/site-packages/django/core/handlers/base.py", line 197, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
File "/Users/darius/anaconda3/envs/django_env/lib/python3.10/site-packages/django/views/decorators/csrf.py", line 65, in _view_wrapper
return view_func(request, *args, **kwargs)
File "/Users/darius/Documents/franchise_store/warehouse/views.py", line 16, in process_barcode
country_code = int(barcode[:3])
ValueError: invalid literal for int() with base 10: 'som'
"POST /warehouse/scan-barcode/ HTTP/1.1" 500 66357
"GET /warehouse/scan-barcode-camera/ HTTP/1.1" 200 3361
"GET /admin/product_directory/product/add/ HTTP/1.1" 200 16845
"GET /admin/jsi18n/ HTTP/1.1" 200 3342
"POST /admin/product_directory/product/add/ HTTP/1.1" 200 17101
"GET /admin/jsi18n/ HTTP/1.1" 200 3342
"POST /admin/product_directory/product/add/ HTTP/1.1" 302 0
"GET /admin/product_directory/product/ HTTP/1.1" 200 13509
"GET /admin/jsi18n/ HTTP/1.1" 200 3342
"GET /admin/product_directory/product/2/change/ HTTP/1.1" 200 17176
"GET /admin/jsi18n/ HTTP/1.1" 200 3342
"POST /warehouse/scan-barcode/ HTTP/1.1" 200 222
/Users/darius/Documents/franchise_store/warehouse/views.py changed, reloading.
Watching for file changes with StatReloader
"GET /warehouse/scan-barcode-camera/ HTTP/1.1" 200 3361
"POST /warehouse/scan-barcode/ HTTP/1.1" 200 222
/Users/darius/Documents/franchise_store/warehouse/views.py changed, reloading.
Watching for file changes with StatReloader
/Users/darius/Documents/franchise_store/warehouse/views.py changed, reloading.
Watching for file changes with StatReloader
/Users/darius/Documents/franchise_store/warehouse/views.py changed, reloading.
Watching for file changes with StatReloader
/Users/darius/Documents/franchise_store/warehouse/views.py changed, reloading.
Watching for file changes with StatReloader
"GET /warehouse/scan-barcode-camera/ HTTP/1.1" 200 3370
"GET /warehouse/scan-barcode-camera/ HTTP/1.1" 200 4245
Not Found: /warehouse/scan-barcode/4820024731015318/
"GET /warehouse/scan-barcode/4820024731015318/ HTTP/1.1" 404 3409
/Users/darius/Documents/franchise_store/warehouse/views.py changed, reloading.
Watching for file changes with StatReloader
/Users/darius/Documents/franchise_store/warehouse/views.py changed, reloading.
Watching for file changes with StatReloader
"GET /warehouse/scan-barcode-camera/ HTTP/1.1" 200 4440
Not Found: /process-barcode/
"POST /process-barcode/ HTTP/1.1" 404 2676
"GET /warehouse/scan-barcode-camera/ HTTP/1.1" 200 4440
Not Found: /process-barcode/
"POST /process-barcode/ HTTP/1.1" 404 2676
/Users/darius/Documents/franchise_store/warehouse/views.py changed, reloading.
Watching for file changes with StatReloader
"GET /warehouse/scan-barcode-camera/ HTTP/1.1" 200 4440
Not Found: /process-barcode/
"POST /process-barcode/ HTTP/1.1" 404 2676
/Users/darius/Documents/franchise_store/warehouse/views.py changed, reloading.
Watching for file changes with StatReloader
/Users/darius/Documents/franchise_store/warehouse/views.py changed, reloading.
Watching for file changes with StatReloader
/Users/darius/Documents/franchise_store/warehouse/views.py changed, reloading.
Watching for file changes with StatReloader
"GET /warehouse/scan-barcode-camera/ HTTP/1.1" 200 4440
Not Found: /process-barcode/
"POST /process-barcode/ HTTP/1.1" 404 2676
"GET /warehouse/scan-barcode-camera/ HTTP/1.1" 200 4450
Not Found: /warehouse/process-barcode/
"POST /warehouse/process-barcode/ HTTP/1.1" 404 3368
"GET /warehouse/scan-barcode-camera/ HTTP/1.1" 200 4245
Not Found: /warehouse/scan-barcode/4820024700016/
"GET /warehouse/scan-barcode/4820024700016/ HTTP/1.1" 404 3400
"GET /warehouse/scan-barcode-camera/ HTTP/1.1" 200 4511
Not Found: /warehouse/process-barcode/
"POST /warehouse/process-barcode/ HTTP/1.1" 404 3368
Not Found: /docs/swagger
"GET /docs/swagger HTTP/1.1" 404 2663
Not Found: /favicon.ico
"GET /favicon.ico HTTP/1.1" 404 2660
"GET /api/swagger HTTP/1.1" 301 0
"GET /api/swagger/ HTTP/1.1" 200 2227
"GET /static/drf-yasg/style.css HTTP/1.1" 200 1047
"GET /static/drf-yasg/insQ.min.js HTTP/1.1" 200 2093
"GET /static/drf-yasg/swagger-ui-init.js HTTP/1.1" 200 15480
"GET /static/drf-yasg/immutable.min.js HTTP/1.1" 200 56904
"GET /static/drf-yasg/swagger-ui-dist/swagger-ui-standalone-preset.js HTTP/1.1" 200 322863
"GET /static/drf-yasg/swagger-ui-dist/swagger-ui.css HTTP/1.1" 200 145206
"GET /static/drf-yasg/swagger-ui-dist/swagger-ui-bundle.js HTTP/1.1" 200 1046583
"GET /api/swagger/?format=openapi HTTP/1.1" 200 23941
"GET /static/drf-yasg/swagger-ui-dist/favicon-32x32.png HTTP/1.1" 200 628
"GET /static/drf-yasg/swagger-ui-dist/favicon-32x32.png HTTP/1.1" 200 628

@ -0,0 +1,62 @@
from django.http import JsonResponse
from django.views import View
# Таблица стран
COUNTRY_CODES = {
range(0, 140): "США и Канада",
range(200, 300): "Внутренний код предприятия",
range(300, 380): "Франция",
380: "Болгария",
482: "Украина",
# Добавьте остальные страны из таблицы
}
def get_country(code):
"""Получение страны по коду."""
for code_range, country in COUNTRY_CODES.items():
if isinstance(code_range, range) and code in code_range:
return country
elif code == code_range:
return country
return "Неизвестная страна"
def validate_barcode(barcode):
"""Проверка валидности штрих-кода."""
if len(barcode) != 13 or not barcode.isdigit():
return False, "Штрих-код должен содержать 13 цифр."
# Проверка контрольной цифры
even_sum = sum(int(barcode[i]) for i in range(1, 12, 2))
odd_sum = sum(int(barcode[i]) for i in range(0, 12, 2))
control_digit = (10 - ((even_sum * 3 + odd_sum) % 10)) % 10
if control_digit != int(barcode[-1]):
return False, "Контрольная цифра не совпадает."
return True, "Штрих-код валиден."
class BarcodeView(View):
def post(self, request):
barcode = request.POST.get("barcode", "").strip()
# Валидация штрих-кода
is_valid, message = validate_barcode(barcode)
if not is_valid:
return JsonResponse({"error": message}, status=400)
# Расшифровка штрих-кода
country_code = int(barcode[:3])
manufacturer_code = barcode[3:7]
product_code = barcode[7:12]
control_digit = barcode[-1]
country = get_country(country_code)
response = {
"barcode": barcode,
"country": country,
"manufacturer_code": manufacturer_code,
"product_code": product_code,
"control_digit": control_digit,
}
return JsonResponse(response, status=200)

@ -0,0 +1,122 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Сканирование штрих-кода</title>
<script src="https://cdn.jsdelivr.net/npm/quagga/dist/quagga.min.js"></script>
<style>
#scanner-container {
width: 100%;
max-width: 640px;
margin: auto;
text-align: center;
}
#video-preview {
width: 100%;
height: auto;
}
#result {
margin-top: 20px;
}
.product-info {
margin-top: 20px;
text-align: left;
font-family: Arial, sans-serif;
}
.product-info ul {
list-style: none;
padding: 0;
}
.product-info li {
margin-bottom: 8px;
}
</style>
</head>
<body>
<h1>Сканирование штрих-кода</h1>
<div id="scanner-container">
<div id="video-preview"></div>
<p id="result">Результат: <span id="barcode-result">---</span></p>
<div id="product-details" class="product-info" style="display:none;">
<h2>Информация о товаре</h2>
<ul id="product-info-list"></ul>
</div>
<button id="stop-button" style="display:none;">Остановить сканирование</button>
</div>
<script>
const resultElement = document.getElementById("barcode-result");
const stopButton = document.getElementById("stop-button");
const productDetails = document.getElementById("product-details");
const productInfoList = document.getElementById("product-info-list");
// Инициализация Quagga
function startScanner() {
Quagga.init({
inputStream: {
name: "Live",
type: "LiveStream",
target: document.querySelector("#video-preview"),
},
decoder: {
readers: ["ean_reader", "code_128_reader", "upc_reader"],
},
}, function(err) {
if (err) {
console.error(err);
alert("Ошибка инициализации камеры");
return;
}
Quagga.start();
stopButton.style.display = "inline";
});
Quagga.onDetected(function(data) {
const barcode = data.codeResult.code;
resultElement.innerText = barcode;
Quagga.stop();
stopButton.style.display = "none";
// Отправка штрих-кода на сервер
fetch('/warehouse/process-barcode/', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({ barcode: barcode }) // Передача данных через тело запроса
})
.then(response => response.json())
.then(product => {
if (product.error) {
alert(product.error);
return;
}
// Отображение информации о товаре
productInfoList.innerHTML = ''; // Очистка списка
for (const [key, value] of Object.entries(product)) {
const listItem = document.createElement('li');
listItem.innerText = `${key}: ${value}`;
productInfoList.appendChild(listItem);
}
productDetails.style.display = "block";
})
.catch(error => {
console.error('Ошибка:', error);
alert('Продукт не найден или ошибка на сервере');
});
});
}
// Остановка сканера
stopButton.addEventListener("click", () => {
Quagga.stop();
stopButton.style.display = "none";
});
// Запуск сканера
document.addEventListener("DOMContentLoaded", startScanner);
</script>
</body>
</html>

@ -1,10 +1,13 @@
from django.urls import path, include
from rest_framework.routers import DefaultRouter
from .api_views import StockOperationViewSet
from .views import scan_barcode_camera, process_barcode
router = DefaultRouter()
router.register(r'stock-operations', StockOperationViewSet, basename='stock-operation')
urlpatterns = [
path('api/', include(router.urls)),
path('scan-barcode-camera/', scan_barcode_camera, name='scan-barcode-camera'),
path('scan-barcode/', process_barcode, name='scan-barcode'),
]

@ -1,3 +1,47 @@
from django.shortcuts import render
from django.views.decorators.csrf import csrf_exempt
from django.http import JsonResponse
import json
from product_directory.models import Product
# Create your views here.
def scan_barcode_camera(request):
return render(request, 'scan_barcode.html')
def get_product_by_barcode(request, barcode):
"""
Возвращает информацию о продукте по штрих-коду.
"""
try:
product = Product.objects.get(barcode=barcode)
response_data = {
"name": product.name,
"barcode": product.barcode,
"shelf_life_days": product.shelf_life_days,
"dimensions": product.dimensions,
"unit_of_measure": product.unit_of_measure,
"manufacturer": product.manufacturer,
"category": product.get_category_display(),
"storage_temperature": product.storage_temperature,
"promotion": product.get_promotion_display() if product.promotion else "Нет акции"
}
print(response_data)
return JsonResponse(response_data)
except Product.DoesNotExist:
return JsonResponse({"error": "Продукт с указанным штрих-кодом не найден"}, status=404)
@csrf_exempt
def process_barcode(request):
if request.method == 'POST':
data = json.loads(request.body)
barcode = data.get('barcode')
print(barcode)
# # Логика для обработки штрих-кода
# country_code = int(barcode[:3])
# manufacturer_code = barcode[3:7]
# product_code = barcode[7:12]
# control_digit = barcode[-1]
return get_product_by_barcode(barcode)
return JsonResponse({"error": "Метод не поддерживается"}, status=405)
Loading…
Cancel
Save