Container type import from excel files

This commit is contained in:
Dirk Jahnke 2022-04-01 19:28:10 +02:00
parent 9396cd4903
commit 61edb7e538
7 changed files with 209 additions and 11 deletions

View File

@ -30,9 +30,6 @@
</div>
</div>
<table>
</table>
<!-- Action buttons -->
<div class="row">

View File

@ -0,0 +1,18 @@
{% extends "base.html" %}
{% load static %}
{% block title %}Edit Container: {{ container.named_id }}{% endblock %}
{% block content %}
<div class="container">
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<div>
<input type="submit" class="btn btn-primary" value="Save">
<a class="btn btn-primary" href="{% url 'container:list' %}">Container List</a>
</div>
</form>
</div>
{% endblock content %}

View File

@ -0,0 +1,63 @@
{% extends "base.html" %}
{% load static %}
{% block title %}Container Type Import{% endblock %}
{% block content %}
<div class="container">
<div class="row">
<div class="col-sm-12">
<h2>Container Type Import: {{ import_file }}</h2>
<form method="post" enctype="multipart/form-data">
{% csrf_token %}
{% if not import_file %}
<input type="file" id="import_file" name="import_file" class="form-control">
{% endif %}
{% if import_file %}
<label for="first_data_row">First data row:</label><input type="number" min="1" max="10" size="3" name="first_data_row" id="first_data_row" value="1"><br />
<input type="submit" class="btn btn-primary" value="import" name="import-cmd">
{% else %}
<input type="submit" class="btn btn-primary" value="show" name="show-cmd">
{% endif %}
<div>
{% if import_file %}
File to be imported: {{ import_file }}
{% endif %}
<br>
{% for file in FILES %}
File: {{ file.name }} ({{ file.size }} Bytes)
{% endfor %}
</div>
<div>
<table class="table">
<tr>
<td>Row</td>
<td>ID</td>
<td>Description</td>
<td>Width</td>
<td>Length</td>
<td>Height</td>
<td>Cover</td>
<td>Inner Width</td>
<td>Inner Length</td>
<td>Inner Height</td>
<td>Available</td>
<td>Stores Container</td>
</tr>
{% for row in excel_data %}
<tr>
{% for col in row %}
<td>{{ col }}<input type="hidden" value="{{ col }}" name="data_{{ row.0 }}_{{ forloop.counter }}"></td>
{% endfor %}
</tr>
{% endfor %}
</table>
</div>
</form>
</div>
</div>
</div>
{% endblock content %}

View File

@ -22,7 +22,7 @@
<tbody>
{% for ctype in container_type_list %}
<tr>
<td><a href="{% url 'container:container_type_detail' ctype.id %}"><div>{{ ctype.named_id }}</div></a></td>
<td><a href="{% url 'container:container_type_update' ctype.id %}"><div>{{ ctype.named_id }}</div></a></td>
<td><div>{{ ctype.description }}</div></td>
<td><div>{% if ctype.width %}{{ ctype.width }}x{{ ctype.length }}x{{ ctype.height }}{% endif %}</div></td>
<td><div>{% if ctype.inner_width %}{{ ctype.inner_width }}x{{ ctype.inner_length }}x{{ ctype.inner_height }}{% endif %}</div></td>
@ -66,6 +66,9 @@
<a class="btn btn-primary" href="{% url 'container:add' %}" role="button">+ Container</a>
<a class="btn btn-primary" href="{% url 'asset:add' %}" role="button">+ Asset</a>
</div>
<div class="col-sm-12">
<a class="btn btn-primary" href="{% url 'container:container_type_import' %}" role="button">Import Container Types</a>
</div>
</div>
<!-- End Action buttons -->

View File

@ -1,19 +1,21 @@
from django.urls import path
from container.views import ContainerListView, ContainerUpdateView, ContainerCreateView, ContainerDetailView, ContainerDeleteView, ContainerPrintLabelView
from container.views import ContainerTypeListView, ContainerTypeDetailView, ContainerTypeCreateView, ContainerTypeUpdateView, ContainerTypeDeleteView
from container.views import ContainerListView, ContainerUpdateView, ContainerCreateView, ContainerDetailView, ContainerDeleteView, ContainerPrintLabelView, ContainerImportView
from container.views import ContainerTypeListView, ContainerTypeDetailView, ContainerTypeCreateView, ContainerTypeUpdateView, ContainerTypeDeleteView, ContainerTypeImportView
app_name = 'container'
urlpatterns = [
path('', ContainerListView.as_view(), name='list'),
path('<int:pk>/', ContainerDetailView.as_view(), name='detail'),
path('add/', ContainerCreateView.as_view(), name='add'),
path('import/', ContainerImportView.as_view(), name='container_import'),
path('edit/<int:pk>/', ContainerUpdateView.as_view(), name='update'),
path('label/<int:pk>/', ContainerPrintLabelView.as_view(), name='print_label'),
path('delete/<int:pk>/', ContainerDeleteView.as_view(), name='delete'),
path('type/', ContainerTypeListView.as_view(), name='container_type_list'),
path('type/<int:pk>/', ContainerTypeDetailView.as_view(), name='container_type_detail'),
path('type/add/', ContainerTypeCreateView.as_view(), name='container_type_add'),
path('type/import/', ContainerTypeImportView.as_view(), name='container_type_import'),
path('type/edit/<int:pk>/', ContainerTypeUpdateView.as_view(), name='container_type_update'),
path('type/delete/<int:pk>/', ContainerTypeDeleteView.as_view(), name='container_type_delete'),
]

View File

@ -1,6 +1,7 @@
from django.views import generic
from .models import Container, ContainerType
import logging, json
import logging, json, re
from django.core.exceptions import ObjectDoesNotExist
logger = logging.getLogger(__name__)
@ -29,6 +30,23 @@ class ContainerCreateView(generic.CreateView):
return super().form_valid(form)
class ContainerImportView(generic.TemplateView):
template_name = 'container_import.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
if 'start_import' in self.request.POST:
context['import_file'] = self.request.POST['import_file']
return context
def get(self, *args, **kwargs):
return super().get(self.request, args, **kwargs)
def post(self):
return super().render_to_response(self)
class ContainerUpdateView(generic.UpdateView):
model = Container
# template_name = 'container/detail.html'
@ -87,8 +105,8 @@ class ContainerPrintLabelView(generic.DetailView):
context['barcode_img'] = pil_to_html_imgdata(label_image, fmt='PNG')
context['logs'].append('Image created')
if num_copies > 0:
#from brother_ql.devicedependent import models, label_type_specs, label_sizes
#from brother_ql.devicedependent import ENDLESS_LABEL, DIE_CUT_LABEL, ROUND_DIE_CUT_LABEL
# from brother_ql.devicedependent import models, label_type_specs, label_sizes
# from brother_ql.devicedependent import ENDLESS_LABEL, DIE_CUT_LABEL, ROUND_DIE_CUT_LABEL
from brother_ql import BrotherQLRaster, create_label
from brother_ql.backends import backend_factory, guess_backend
@ -127,7 +145,7 @@ class ContainerPrintLabelView(generic.DetailView):
be_class = backend_factory(selected_backend)['backend_class']
be = be_class(config['PRINTER']['PRINTER'])
context['logs'].append('Got backend driver')
for i in range(1,num_copies):
for i in range(1, num_copies):
be.write(qlr.data)
context['logs'].append('Data sent to printer')
@ -163,7 +181,7 @@ class ContainerTypeDetailView(generic.DetailView):
class ContainerTypeCreateView(generic.CreateView):
model = ContainerType
# template_name = 'container/detail.html'
template_name = 'container/container_type_form.html'
fields = ['named_id', 'description', 'width', 'length', 'height', 'inner_width', 'inner_length', 'inner_height',
'has_cover', 'contains_container']
@ -176,6 +194,7 @@ class ContainerTypeCreateView(generic.CreateView):
class ContainerTypeUpdateView(generic.UpdateView):
model = ContainerType
# template_name = 'container/detail.html'
template_name = 'container/container_type_form.html'
fields = ['named_id', 'description', 'width', 'length', 'height', 'inner_width', 'inner_length', 'inner_height',
'has_cover', 'contains_container']
@ -186,3 +205,95 @@ class ContainerTypeUpdateView(generic.UpdateView):
class ContainerTypeDeleteView(generic.DetailView):
model = ContainerType
class ContainerTypeImportView(generic.TemplateView):
template_name = 'container/container_type_import.html'
def get_context_data(self, **kwargs):
# print('get_context_data')
context = super().get_context_data(**kwargs)
context['import_file'] = self.request.FILES['import_file'] if 'import_file' in self.request.FILES else ''
if context['import_file'] != '':
# if 'show-cmd' in self.request.POST:
# print('Show button pressed')
context['filename'] = self.request.FILES['import_file'].name
context['filesize'] = self.request.FILES['import_file'].size
context['content_type'] = self.request.FILES['import_file'].content_type
import openpyxl as excel
workbook = excel.open(self.request.FILES['import_file'])
sheet = workbook.active
sheet_data = []
row_num = 1
for row in sheet.values:
row_data = [row_num]
row_num = row_num + 1
for col in row:
row_data.append(col if col is not None else '')
sheet_data.append(row_data)
context['excel_data'] = sheet_data
return context
def post(self, request):
# print('POST method executed')
if 'import-cmd' in request.POST:
# print('import button pressed')
first_data_row = int(request.POST['first_data_row']) if 'first_data_row' in request.POST else 0
# context['first_data_row'] = first_data_row
# print('first_data_row=%d' % first_data_row)
p = re.compile(r'^data_(\d+)_(\d+)$')
import_data = {}
for key in request.POST:
match = p.match(key)
if match:
key_row, key_col = match.group(1, 2)
row_num = int(key_row)
col_num = int(key_col)
if row_num >= first_data_row:
value = request.POST[key]
if row_num not in import_data:
import_data[row_num] = {}
import_data[row_num][col_num] = value
# print('Value row=%d, col=%d, value=%s' % (row_num, col_num, value))
for col in import_data:
c7 = import_data[col][7]
c12 = import_data[col][12]
has_cover = True if c7 == 'j' or c7 == 'J' or c7 == 'y' or c7 == 'Y' else False
contains_container = True if c12 == 'j' or c12 == 'J' or c12 == 'y' or c12 == 'Y' else False
try:
ct = ContainerType.objects.get(named_id=import_data[col][2])
# Update entry
ct.description = None if import_data[col][3] == '' else import_data[col][3]
ct.width = None if import_data[col][4] == '' else import_data[col][4]
ct.length = None if import_data[col][5] == '' else import_data[col][5]
ct.height = None if import_data[col][6] == '' else import_data[col][6]
ct.inner_width = None if import_data[col][8] == '' else import_data[col][8]
ct.inner_length = None if import_data[col][9] == '' else import_data[col][9]
ct.inner_height = None if import_data[col][10] == '' else import_data[col][10]
ct.has_cover = has_cover
ct.contains_container = contains_container
ct.changed_by_id = request.user.id
# print('Updated %s' % import_data[col][2])
except ObjectDoesNotExist:
# Create a new entry
ct = ContainerType.objects.create(
named_id=import_data[col][2],
description=None if import_data[col][3] == '' else import_data[col][3],
width=None if import_data[col][4] == '' else import_data[col][4],
length=None if import_data[col][5] == '' else import_data[col][5],
height=None if import_data[col][6] == '' else import_data[col][6],
inner_width=None if import_data[col][8] == '' else import_data[col][8],
inner_length=None if import_data[col][9] == '' else import_data[col][9],
inner_height=None if import_data[col][10] == '' else import_data[col][10],
has_cover=has_cover,
contains_container=contains_container,
created_by_id=request.user.id,
changed_by_id=request.user.id
)
# print('Created %s' % import_data[col][2])
finally:
ct.save()
return super().get(request)

View File

@ -11,6 +11,7 @@ https://docs.djangoproject.com/en/3.2/ref/settings/
"""
from pathlib import Path
import os
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
@ -128,3 +129,6 @@ STATICFILES_DIRS = [
# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
MEDIA_URL = '/media/'
MEDIA_ROOT = os.path.join(BASE_DIR, 'media')