add view to enter whole sketches at once

master
agp8x 2017-10-28 23:12:47 +02:00
parent dfb56c8e4e
commit ea688ac7e0
9 changed files with 185 additions and 20 deletions

3
.gitignore vendored
View File

@ -1,5 +1,8 @@
/venv
/pgdata
sketches/
db.sqlite3
__pycache__/
*/*/migrations/*.py
!migrations/__init__.py

View File

@ -124,3 +124,4 @@ USE_TZ = True
# https://docs.djangoproject.com/en/1.11/howto/static-files/
STATIC_URL = '/static/'
STATIC_ROOT = 'static/'

View File

@ -13,10 +13,12 @@ Including another URLconf
1. Import the include() function: from django.conf.urls import url, include
2. Add a URL to urlpatterns: url(r'^blog/', include('blog.urls'))
"""
from django.conf import settings
from django.conf.urls import url, include
from django.contrib import admin
from django.conf.urls.static import static
urlpatterns = [
url(r'^parts/', include('parts.urls'), name="parts"),
url(r'^admin/', admin.site.urls),
]
url(r'^admin/', admin.site.urls),
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)

View File

@ -2,4 +2,39 @@ from django.contrib import admin
from .models import Brand, Product, Version, Sketch, Part, Usage, BrandedPart, ProductUsage
admin.site.register([Brand, Product, Version, Sketch, Part, Usage, BrandedPart, ProductUsage])
#admin.site.register([Brand, Product, Version, Sketch, Part, Usage, BrandedPart, ProductUsage])
admin.site.register([Brand, Product, Version, Sketch, ProductUsage])
class BrandedPartInline(admin.StackedInline):
model = BrandedPart
extra = 1
class PartAdmin(admin.ModelAdmin):
inlines = [BrandedPartInline]
class PartInline(admin.StackedInline):
model = Part
#class ProductUsageInline(admin.TabularInline):
# model = ProductUsage
# extra = 1
class ProductUsageInline(admin.StackedInline):
model = ProductUsage
extra = 1
class UsageAdmin(admin.ModelAdmin):
model = Usage
extra = 1
inlines = [ProductUsageInline]
class UsageInline(admin.StackedInline):
model = Usage
extra = 1
class BrandedPartAdmin(admin.ModelAdmin):
inlines = [UsageInline]
admin.site.register(Usage, UsageAdmin)
admin.site.register(Part, PartAdmin)
admin.site.register(BrandedPart, BrandedPartAdmin)

View File

@ -1,13 +1,21 @@
from django.db import models
class Brand(models.Model):
class PartModel(models. Model):
creation = models.DateTimeField(auto_now_add=True)
modification = models.DateTimeField(auto_now=True)
class Meta:
abstract = True
class Brand(PartModel):
name = models.CharField(max_length=256)
def __str__(self):
return self.name
class Product(models.Model):
class Product(PartModel):
name = models.CharField(max_length=256)
brand = models.ForeignKey(Brand)
@ -15,12 +23,13 @@ class Product(models.Model):
return self.name + " (" + self.brand.name + ")"
class Sketch(models.Model):
class Sketch(PartModel):
class Meta:
verbose_name_plural = "sketches"
name = models.CharField(max_length=256)
brand = models.ForeignKey(Brand, blank=True, null=True)
product = models.ForeignKey(Product, blank=True, null=True)
image = models.FileField(upload_to="sketches/", blank=True, null=True)
def __str__(self):
return "Sketch: " + self.name + " (" + str(self.brand) + ")"
@ -35,30 +44,37 @@ class Sketch(models.Model):
return self.usage_set.values('productusage__product__brand').distinct()
class Version(models.Model):
class Version(PartModel):
product = models.ForeignKey(Product)
name = models.CharField(max_length=256)
replaced_by = models.ForeignKey('self', blank=True, null=True, related_name='replaces')
start = models.DateField(blank=True, null=True)
end = models.DateField(blank=True, null=True)
additional_sketch = models.ManyToManyField(Sketch, blank=True, related_name='added')
unused_sketch = models.ManyToManyField(Sketch, blank=True, related_name='replaced')
def __str__(self):
return "Version: " + self.name + " (" + str(self.product) + ")"
class Part(models.Model):
class Part(PartModel):
name = models.CharField(max_length=256)
def __str__(self):
return self.name
class BrandedPart(models.Model):
part = models.ForeignKey(Part)
class BrandedPart(PartModel):
part = models.ForeignKey(Part, null=True)
brand = models.ForeignKey(Brand)
number = models.CharField(max_length=32, unique=True)
number = models.CharField(max_length=32, unique=True, blank=True, null=True)
def __str__(self):
return self.number +": "+ self.part.name + " @ " + self.brand.name
na = self.part.name if self.part else "--(part)--"
return str(self.number) +": "+ na + " @ " + self.brand.name
class Usage(models.Model):
class Usage(PartModel):
part = models.ForeignKey(BrandedPart)
sketch = models.ForeignKey(Sketch)
sketch_number = models.CharField(max_length=32)
@ -66,13 +82,15 @@ class Usage(models.Model):
#quantity = models.ManyToManyField(ProductUsage)
def __str__(self):
return self.sketch_number +"; " + self.part.number +"; "+ self.part.part.name + "; " + str(self.sketch)
no = self.part.number if self.part else "--(part.number)--"
na = self.part.part.name if self.part.part else "--(part.part.name)--"
return self.sketch_number +"; " + str(no) +"; "+ na + "; " + str(self.sketch)
class ProductUsage(models.Model):
usage = models.ForeignKey(Usage)
class ProductUsage(PartModel):
usage = models.ForeignKey(Usage, null=True)
product = models.ForeignKey(Product)
quantity = models.IntegerField()
quantity = models.IntegerField(null=True)
on_demand = models.BooleanField(default=False)
obsolete = models.BooleanField(default=False)
used_until = models.ForeignKey(Version, null=True, blank=True, related_name='introduces')
@ -83,4 +101,4 @@ class ProductUsage(models.Model):
internal_note = models.CharField(max_length=2, blank=True)
def __str__(self):
return "ProductUsage: " + self.product.name + " @ " + str(self.quantity) + "; "+ self.usage.part.number
return "ProductUsage: " + self.product.name + " @ " + str(self.quantity) + "; "+ str(self.usage.part.number)

View File

@ -0,0 +1,8 @@
function addRow(){
var src = document.getElementById("template");
var clone = src.cloneNode(true);
clone.id = "";
clone.className ="entry";
clone.children[0].children[0].value = document.getElementsByClassName("entry").length + 1
document.getElementById("table").appendChild(clone);
}

View File

@ -0,0 +1,30 @@
{% load static %}
<script type="text/javascript" src="{% static 'parts/add_sketch.js' %}"> </script>
<h1>add sketch to {{product.name}}</h1>
<button type="button" onclick="addRow()">add row</button>
<form action="{% url 'parts:new_sketch' product.id %}" method="post">
{% csrf_token %}
<p><label for="sketch_name">Name:</label><input type="text" name="sketch_name" /></p>
<table id="table">
<tr>
<th>Bild-Nr.</th><th>Teil-Nr.</th><th>Intern</th><th>Teilbezeichnung</th><th>Anzahl</th><th>verbaut bis</th><th>verbaut ab</th><th>ersetzt durch</th><th>Anmerkungen</th>
</tr>
</table>
<input type="submit" />
</form>
<table style="display:none;">
<tr id="template">
<td><input type="text" size="8" name="fignumber" /></td>
<td><input type="text" size="13" name="partnumber" /></td>
<td><input type="text" size="1" name="internal" /></td>
<td><input type="text" size="32" name="name" /></td>
<td><input type="number" size="4" name="quantity" /></td>
<td><input type="text" size="16" name="last_version" /></td>
<td><input type="text" size="16" name="first_version" /></td>
<td><input type="text" size="13" name="replaced_by" /></td>
<td><input type="text" size="16" name="notes" /></td>
</tr>
</table>
<script type="text/javascript">addRow();</script>

View File

@ -2,8 +2,10 @@ from django.conf.urls import url
from . import views
app_name = "parts"
urlpatterns = [
url(r'^$', views.index, name="index"),
url(r'^product/(?P<product_id>[0-9]+)/$', views.product, name="detail"),
url(r'^sketch/(?P<sketch_id>[0-9]+)/$', views.sketch, name="sketch"),
url(r'^add/(?P<product_id>[0-9]+)/sketch', views.sketch_add, name="new_sketch"),
]

View File

@ -1,7 +1,12 @@
from django.shortcuts import render
from django.shortcuts import get_object_or_404, render
from django.http import HttpResponseRedirect
from django.urls import reverse
from django.db import transaction
from .models import *
ADD_SKETCH_REQUIRES = ['sketch_name','sketch_number','']
def index(request):
product_list = Product.objects.all()
context = {'product_list': product_list}
@ -16,4 +21,65 @@ def product(request, product_id):
def sketch(request, sketch_id):
sketch = Sketch.objects.get(id=sketch_id)
context = {'sketch': sketch}
return render(request, 'parts/sketch.html', context)
return render(request, 'parts/sketch.html', context)
@transaction.atomic
def sketch_add(request, product_id):
product = get_object_or_404(Product, pk=product_id)
print(request.POST)
if not "sketch_name" in request.POST:
return render(request, 'parts/add.html', {'product': product})
sketch = Sketch()
sketch.name = request.POST["sketch_name"]
sketch.product = product
sketch.brand = product.brand
sketch.save()
for i in range(len(request.POST.getlist('name'))):
print(i)
usage = Usage()
print("ASDF2")
usage.sketch = sketch
usage.sketch_number = request.POST.getlist('fignumber')[i]
if "ähn" in usage.sketch_number or "vgl" in usage.sketch_number:
usage.exact_sketch = False
print("ASDF3")
branded_part, created = BrandedPart.objects.get_or_create(brand=product.brand, number=request.POST.getlist('partnumber')[i])
print("ASDF", branded_part, created)
if created:
try:
part, _ = Part.objects.get_or_create(name=request.POST.getlist('name')[i])
except Part.MultipleObjectsReturned:
part = Part.objects.filter(name=request.POST.getlist('name')[i]).first()
branded_part.part = part
branded_part.brand = product.brand
branded_part.save()
print("ASDF")
usage.part = branded_part
usage.save()
prod = ProductUsage()
prod.usage = usage
prod.product = product
prod.quantity = int(request.POST.getlist('quantity')[i])
last_version = request.POST.getlist('last_version')[i]
if len(last_version):
version, _ = Version.objects.get_or_create(product=product, name=last_version)
prod.used_until = version
first_version = request.POST.getlist('first_version')[i]
if len(first_version):
version, _ = Version.objects.get_or_create(product=product, name=first_version)
prod.used_since = version
replaced = request.POST.getlist('replaced_by')[i]
if len(replaced):
replacement, _ = ProductUsage.objects.get_or_create(product=product, usage__part__number=replaced)
prod.replaced_by = replacement
note = request.POST.getlist('notes')[i]
if len(note):
prod.note = note
internal = request.POST.getlist('internal')[i]
if len(internal):
prod.internal = internal
prod.save()
return HttpResponseRedirect(reverse('parts:sketch', args=(sketch.id,)))