add cart
parent
f0cf85f3fa
commit
998a530500
|
|
@ -0,0 +1,3 @@
|
|||
date=$(date +%Y-%m-%d"_"%H_%M_%S)
|
||||
docker-compose exec web python3 manage.py dumpdata --natural-foreign --exclude auth.permission --exclude contenttypes --indent 1 | gzip > backups/djangodump_${date}.json.gz
|
||||
docker-compose exec db pg_dump -U partdoc partdoc | gzip > backups/pgdump_${date}.sql.gz
|
||||
|
|
@ -11,7 +11,7 @@ services:
|
|||
working_dir: /app
|
||||
command: python3 ./manage.py runserver 0.0.0.0:8000
|
||||
ports:
|
||||
- 8080:8000
|
||||
- 8081:8000
|
||||
depends_on:
|
||||
- db
|
||||
db:
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
FROM alpine:3.10
|
||||
FROM alpine:3.11
|
||||
|
||||
ADD requirements.txt /
|
||||
RUN apk add --update --no-cache python3 py3-psycopg2 && \
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
from django.contrib import admin
|
||||
|
||||
from .models import Brand, Product, Version, Sketch, Part, Usage, BrandedPart, ProductUsage
|
||||
from .models import Brand, Product, Version, Sketch, Part, Usage, BrandedPart, ProductUsage, Cart, CartEntry, Shop
|
||||
|
||||
# admin.site.register([Brand, Product, Version, Sketch, Part, Usage, BrandedPart, ProductUsage])
|
||||
admin.site.register([Brand, Product, Version, Sketch])
|
||||
admin.site.register([Brand, Product, Version, Sketch, Shop, CartEntry])
|
||||
|
||||
|
||||
class BrandedPartInline(admin.StackedInline):
|
||||
|
|
@ -51,7 +51,18 @@ class BrandedPartAdmin(admin.ModelAdmin):
|
|||
autocomplete_fields = ["parts"]
|
||||
|
||||
|
||||
class CartEntryInline(admin.StackedInline):
|
||||
model = CartEntry
|
||||
extra = 1
|
||||
raw_id_fields = ("origins",)
|
||||
|
||||
class CartAdmin(admin.ModelAdmin):
|
||||
inlines = [CartEntryInline]
|
||||
#search_fields = ["number"]
|
||||
#autocomplete_fields = ["parts"]
|
||||
|
||||
admin.site.register(Usage, UsageAdmin)
|
||||
admin.site.register(ProductUsage, ProductUsageAdmin)
|
||||
admin.site.register(Part, PartAdmin)
|
||||
admin.site.register(BrandedPart, BrandedPartAdmin)
|
||||
admin.site.register(Cart, CartAdmin)
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
from django.db import models, transaction
|
||||
|
||||
from django.db.models import Sum
|
||||
|
||||
class PartModel(models.Model):
|
||||
creation = models.DateTimeField(auto_now_add=True)
|
||||
|
|
@ -157,3 +157,49 @@ class ProductUsage(PartModel):
|
|||
def __str__(self):
|
||||
no = self.usage.part.number if self.usage else "--(part.number)--"
|
||||
return "ProductUsage: " + self.product.name + " @ " + str(self.quantity) + "; " + str(no)
|
||||
|
||||
|
||||
|
||||
class Shop(PartModel):
|
||||
name = models.CharField(max_length=512)
|
||||
url = models.URLField(null=True, blank=True)
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
class Cart(PartModel):
|
||||
name = models.CharField(max_length=512)
|
||||
|
||||
def __str__(self):
|
||||
return self.name
|
||||
|
||||
def add(self, product_usage):
|
||||
part = product_usage.usage.part
|
||||
entry = None
|
||||
for i in self.entries.all():
|
||||
if part == i.part:
|
||||
entry = i
|
||||
break
|
||||
if not entry:
|
||||
entry = CartEntry.objects.create(cart=self)
|
||||
entry.origins.add(product_usage)
|
||||
entry.save()
|
||||
|
||||
|
||||
class CartEntry(PartModel):
|
||||
cart = models.ForeignKey(Cart, on_delete=models.CASCADE, related_name="entries")
|
||||
origins = models.ManyToManyField(ProductUsage)
|
||||
shop = models.ForeignKey(Shop, on_delete=models.CASCADE, null=True, blank=True)
|
||||
in_cart = models.BooleanField(default=False, blank=True)
|
||||
ordered = models.BooleanField(default=False, blank=True)
|
||||
|
||||
@property
|
||||
def part(self):
|
||||
return self.origins.first().usage.part
|
||||
|
||||
@property
|
||||
def quantity(self):
|
||||
return self.origins.aggregate(sum=Sum('quantity'))["sum"]
|
||||
|
||||
def get_quantity(self):
|
||||
return self.quantity
|
||||
|
|
|
|||
|
|
@ -0,0 +1,47 @@
|
|||
function getCookie(name) {
|
||||
var cookieValue = null;
|
||||
if (document.cookie && document.cookie !== '') {
|
||||
var cookies = document.cookie.split(';');
|
||||
for (var i = 0; i < cookies.length; i++) {
|
||||
var cookie = cookies[i].trim();
|
||||
// Does this cookie string begin with the name we want?
|
||||
if (cookie.substring(0, name.length + 1) === (name + '=')) {
|
||||
cookieValue = decodeURIComponent(cookie.substring(name.length + 1));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return cookieValue;
|
||||
}
|
||||
|
||||
function csrfSafeMethod(method) {
|
||||
// these HTTP methods do not require CSRF protection
|
||||
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
|
||||
}
|
||||
$.ajaxSetup({
|
||||
beforeSend: function(xhr, settings) {
|
||||
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
|
||||
var csrftoken = getCookie('csrftoken');
|
||||
xhr.setRequestHeader("X-CSRFToken", csrftoken);
|
||||
xhr.setRequestHeader("X-Frame-Options", "SAMEORIGIN");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
function update_cart(pu_id){
|
||||
var cart = $("#cart")[0].value;
|
||||
console.log("cart", cart);
|
||||
$.ajax({
|
||||
type: "POST",
|
||||
url: "/parts/cart/add/",
|
||||
data: {
|
||||
"cart_name": cart,
|
||||
"product_usage_id": pu_id
|
||||
},
|
||||
success: function(data){
|
||||
console.log(data);
|
||||
}
|
||||
}).done(function(msg){console.log("done" + msg);console.log(msg)})
|
||||
.fail(function(msg){console.log("fail" + msg);console.log(msg)})
|
||||
;
|
||||
}
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
<h1>{{cart.name}}</h1>
|
||||
<h3>entries</h3>
|
||||
<ul>
|
||||
{% for entry in entries %}
|
||||
<li>{{entry.quantity}} -- <a href="{% url 'parts:cart_entry' cart.id entry.id %}">{{entry.part}}</a>
|
||||
<ul>
|
||||
{% for pu in entry.origins.all %}
|
||||
<li><a href="{% url 'parts:sketch' pu.usage.sketch.id %}">{{pu.usage.sketch.name}}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</ul>
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
<h1>{{cart.name}}</h1>
|
||||
<h3>entries</h3>
|
||||
|
||||
TODO
|
||||
|
||||
<a href="{% url 'parts:cart' cart.id %}">{{cart.name}}</a>
|
||||
|
|
@ -1,5 +1,7 @@
|
|||
|
||||
<h1>part {{part.number}}</h1>
|
||||
<h3>{{part.name}}</h3>
|
||||
<h3>{{part.get_name}}</h3>
|
||||
<h4>{{full_name}}</h4>
|
||||
<table>
|
||||
<tr>
|
||||
<th>Produkt</th>
|
||||
|
|
|
|||
|
|
@ -4,3 +4,11 @@
|
|||
<li><a href="{% url 'parts:product' product.id %}">{{product.name}}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
<h1>Available carts</h1>
|
||||
<ul>
|
||||
{% for cart in cart_list %}
|
||||
<li><a href="{% url 'parts:cart' cart.id %}">{{cart.name}}</a></li>
|
||||
{% endfor %}
|
||||
</ul>
|
||||
|
||||
|
|
|
|||
|
|
@ -1,13 +1,19 @@
|
|||
{% load static %}
|
||||
<script type="text/javascript" src="{% static 'parts/jquery-3.2.1.min.js' %}"></script>
|
||||
<script type="text/javascript" src="{% static 'parts/update_cart.js' %}"></script>
|
||||
|
||||
<h1>{{sketch.name}}</h1>
|
||||
<a href="{{sketch.image.url}}"><img src="{{sketch.image.url}}" /></a>
|
||||
{% if sketch.image %}<a href="{{sketch.image.url}}"><img src="{{sketch.image.url}}" /></a> {% endif %}
|
||||
<h2>{% for brand in sketch.get_brand %}{{brand.name}},{% endfor%} - {% for product in sketch.get_product %}{{product.name}},{% endfor%}</h2>
|
||||
<ul>
|
||||
{% for usage in sketch.usage_set.all %}
|
||||
<li><a href="/parts/usage/{{usage.id}}/">{{usage}}</a></li>
|
||||
<li><a href="% url 'parts:usage' usage.id %">{usage}</a></li><!--TODO!-->
|
||||
<!--<li><a href="/parts/usage/{{usage.id}}/">{{usage}}</a></li>-->
|
||||
<li><button type="button" onclick="update_cart({{usage.id}})" id="update_cart_{{usage.id}}" >+</button><a href="{% url 'parts:part' usage.part.id %}">{{usage}}</a></li><!--TODO!-->
|
||||
{% endfor %}
|
||||
</ul>
|
||||
<p>{{sketch.get_brand}}</p>
|
||||
<p>{{sketch.get_brand.name.foo}}</p>
|
||||
|
||||
|
||||
<label for="cart_name">cart:</label><input name="cart_name" id="cart"></input>
|
||||
<a href="{% url "parts:continue_sketch" sketch.product_id sketch.id %}">Edit</a>
|
||||
|
|
|
|||
|
|
@ -13,4 +13,7 @@ urlpatterns = [
|
|||
path('add/<int:product_id>/sketch/<int:sketch_id>', views.sketch_add, name="continue_sketch"),
|
||||
path('add/<int:product_id>/sketch', views.sketch_add, name="new_sketch"),
|
||||
path('search/part/', views.part_search, name="part_search"),
|
||||
path('cart/add/', views.update_cart, name="cart_add"),
|
||||
path('cart/<int:cart_id>/', views.cart, name="cart"),
|
||||
path('cart/<int:cart_id>/entry/<int:entry_id>/', views.cart_entry, name="cart_entry"),
|
||||
]
|
||||
|
|
|
|||
|
|
@ -13,7 +13,10 @@ ADD_SKETCH_REQUIRES = ['sketch_name', 'sketch_number', '']
|
|||
|
||||
def index(request):
|
||||
product_list = Product.objects.all()
|
||||
context = {'product_list': product_list}
|
||||
context = {
|
||||
'product_list': product_list,
|
||||
'cart_list': Cart.objects.all()
|
||||
}
|
||||
return render(request, 'parts/products.html', context)
|
||||
|
||||
|
||||
|
|
@ -31,7 +34,8 @@ def sketch(request, sketch_id):
|
|||
|
||||
def __part_view(request, part):
|
||||
sketches = part.usage_set.values('sketch', 'sketch_number', 'sketch__name', 'sketch__product__name', 'sketch__product__id').annotate(qty=Sum('productusage__quantity'))
|
||||
context = {'part': part, 'sketches': sketches}
|
||||
full_name = part.get_name(full=True)
|
||||
context = {'part': part, 'sketches': sketches, 'full_name': full_name}
|
||||
return render(request, 'parts/part.html', context)
|
||||
|
||||
def part(request, part_id):
|
||||
|
|
@ -179,3 +183,28 @@ def get_quantity(qnty_str):
|
|||
def is_exact_sketchnumber(sketch_number):
|
||||
approximate = ("ähn", "vgl", "~", "zu")
|
||||
return not any([i in sketch_number for i in approximate])
|
||||
|
||||
|
||||
def update_cart(request):
|
||||
if request.method == "POST":
|
||||
keys = ["cart_name", "product_usage_id"]
|
||||
if all([key in request.POST for key in keys]):
|
||||
cart, _ = Cart.objects.get_or_create(name=request.POST["cart_name"])
|
||||
pu = ProductUsage.objects.get(usage__id=request.POST["product_usage_id"])
|
||||
cart.add(pu)
|
||||
return HttpResponse('{"success": true}')
|
||||
return HttpResponse('{"success": false}')
|
||||
|
||||
|
||||
def cart(request, cart_id):
|
||||
cart = Cart.objects.get(id=cart_id)
|
||||
entries = cart.entries.all()
|
||||
context = {'cart': cart, "entries": entries}
|
||||
return render(request, 'parts/cart.html', context)
|
||||
|
||||
|
||||
def cart_entry(request, cart_id, entry_id):
|
||||
cart = Cart.objects.get(id=cart_id)
|
||||
entry = CartEntry.objects.get(id=entry_id)
|
||||
context = {'cart': cart, 'entry': entry}
|
||||
return render(request, 'parts/cart_entry.html', context)
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
django==3.0
|
||||
django==3.0.5
|
||||
psycopg2==2.8.4
|
||||
|
|
|
|||
Loading…
Reference in New Issue