Container type import from excel files
This commit is contained in:
parent
9396cd4903
commit
61edb7e538
|
@ -30,9 +30,6 @@
|
|||
</div>
|
||||
</div>
|
||||
|
||||
<table>
|
||||
</table>
|
||||
|
||||
<!-- Action buttons -->
|
||||
<div class="row">
|
||||
|
||||
|
|
|
@ -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 %}
|
|
@ -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 %}
|
|
@ -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 -->
|
||||
|
|
|
@ -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'),
|
||||
]
|
||||
|
|
|
@ -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'
|
||||
|
@ -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)
|
||||
|
|
|
@ -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')
|
||||
|
|
Loading…
Reference in New Issue