def user_invoices(request): dates_new = {} if OutgoingInvoice.objects.count() != 0: latest_inv_pk, latest_inv_date = list( zip(*list(OutgoingInvoice.objects.values_list("pk", "date")))) else: latest_inv_pk, latest_inv_date = [], [] for position in (OutgoingInvoiceProductUserPosition.objects.filter( user=request.user, productinvoice__invoice__in=latest_inv_pk).order_by( "productinvoice__invoice__date").annotate( invoice_date=F("productinvoice__invoice__inventory__date" )).prefetch_related("productinvoice")): if position.invoice_date not in dates_new: dates_new[position.invoice_date] = [] dates_new[position.invoice_date].append( (position.productinvoice.product.name, position.productinvoice.price_each / 100., position.count, position.count * position.productinvoice.price_each / 100., position.productinvoice.loss, get_loss_color(position.productinvoice.loss))) return render( request, "user_abrechnung.html", add_default_view_data( request, { "dates": sorted([(k, v) for k, v in dates_new.items() if v], reverse=True) }, "Invoice, %s" % request.user.username))
def admin_incoming_invoices(request): return render( request, "admin/incoming_invoices.html", add_default_view_data(request, { "incoming_invoices": IncomingInvoice.objects.all().order_by("-date") }, "Admin - Incoming Invoices"))
def select_product(request): if request.method == "POST": print(request.POST["json_data"]) try: users = json.loads(request.POST["json_data"]) except JSONDecodeError as e: return Http404("Invalid data input") for user, products in users.items(): user = User.objects.get(pk=int(user)) for product, count in products.items(): product = Product.objects.get(pk=int(product)) Consumption(product=product, user=user, count=count, issued_by=request.user).save() if request.COOKIES.get("temp_login") == "true": auth_logout(request) response = HttpResponseRedirect(request.path) response.set_cookie("orderList", "{}") return response return render( request, "input.html", add_default_view_data( request, { "products": Product.objects.all(), "users": User.objects.all(), "range": range(64) }, "Select Product"))
def user_consumptions(request): # TODO: more efficient user = request.user inventories = Inventory.objects.all().order_by("date") inventories = inventories.exclude(pk=inventories.first().pk) dates_new = inventories.values_list("date", flat=True) table = ProductInPeriod.get_listed_consumptions_table( inventories, Product.objects.all(), Consumption.objects.filter(user=user)) consumptions_new = [] for p_id, product_name in enumerate(Product.objects.all().values_list( "name", flat=True)): product_consumptions = [] for i_id in range(inventories.count()): product_consumptions.append(table[i_id][p_id]) consumptions_new.append((product_name, product_consumptions)) return render( request, "consumptions.html", add_default_view_data( request, { "dates": dates_new, "labels_json": [str(d) for d in dates_new], "consumptions": consumptions_new, "products": Product.objects.all(), "detailed_cons": Consumption.objects.filter(user=user).order_by("-date") }, "Consumptions, %s" % request.user.username))
def schwund_charts(request): if OutgoingInvoice.objects.count() != 0: dates, profits = zip(*OutgoingInvoice.objects.all().order_by( "inventory__date").values_list("inventory__date", "profit")) else: dates, profits = [], [] pnn = Product.objects.values_list("pk", "name") products, pnames = zip(*pnn) id_to_pname = dict(pnn) losses = dict([(product, [0] * len(dates)) for product in products]) for dt, product, loss, total in ( OutgoingInvoiceProductPosition.objects.filter( (Q(invoice__corrected_by=None) | Q(invoice__corrected_by__is_frozen=False)) & Q(invoice__is_frozen=True)).values_list( "invoice__inventory__date", "product", "loss", "total")): if product == 4 and abs(loss) == float("+inf"): print((loss, total, abs(loss) if abs(loss) != float("+inf") else (0 if total < 100 else 100))) losses[product][dates.index(dt)] = abs(loss) if abs(loss) != float( "+inf") else (0 if total < 100 else 100) new_losses = [] for k in losses: new_losses.append((id_to_pname[k], json.dumps(losses[k]))) return render( request, "charts.html", add_default_view_data( request, { "labels_json": json.dumps([str(i) for i in dates]), "losses_json": new_losses, "gewinn_json": json.dumps([i / 100 for i in profits]) }, "Schwund u. Gewinn"))
def admin_invoices_list(request): return render( request, "admin/invoice_list.html", add_default_view_data( request, { "invoices": (OutgoingInvoice.objects_temporary.all().order_by( "-inventory__date")) }, "Admin - Invoices"))
def admin_inventory_list(request): inventories = Inventory.objects.order_by("date") products = Product.objects.order_by("name") tbl_real = ProductInPeriod.get_real_consumption_list(inventories, products) tbl_listed = ProductInPeriod.get_listed_consumptions_table( inventories, products) date_n_counts_new = zip( inventories.values_list("date", flat=True), numpy.sum(numpy.abs(tbl_real - tbl_listed), axis=1)) return render( request, "admin/inventories.html", add_default_view_data( request, {"date_n_counts": reversed(list(date_n_counts_new))}, "Admin - Inventories"))
def create_consumtions(request): if request.method == "POST": if "delete" in request.POST: Consumption.objects.get(pk=request.POST["id"]).delete() return HttpResponseRedirect(request.build_absolute_uri()) else: data = {} for k, v in request.POST.items(): if v == "": continue if k.startswith("cons"): dk, id = k.split("/") if id not in data: data[id] = {} data[id][dk[5:]] = v for v in data.values(): consumtion = Consumption( product=Product.objects.get(id=v["product"]), user=User.objects.get(id=v["user"]), count=v["count"], issued_by=request.user) consumtion.save() return HttpResponseRedirect(request.build_absolute_uri()) pz = 100 p = int(request.GET["p"] if "p" in request.GET else 0) page_count = math.ceil( Consumption.objects.filter(issued_by=request.user).count() / pz) return render( request, "admin/admin_create_cons.html", add_default_view_data( request, { "range": [{ "pk": -i - 1 } for i in range(100)], "products": Product.objects.all(), "users": User.objects.all(), "pages": range(page_count), "current_page": p, "consumptions": Consumption.objects.filter(issued_by=request.user).order_by( "-date", "user__username")[p * pz:(p + 1) * pz] }, "Admin - Consumptions"))
def login(request): if request.method == "POST": username = request.POST['username'] password = request.POST['password'] user = authenticate(request, username=username, password=password) if user is not None: auth_login(request, user) response = HttpResponseRedirect(TEMPLATE_BASE_URL) response.set_cookie( "temp_login", "true" if "temp_login" in request.POST else "false") return response else: return HttpResponse("wrong password.") else: return render( request, "login.html", add_default_view_data( request, { "users": (User.objects.filter( userextension__allow_login=True).annotate( max_cons_date=Max('consumption__date')).order_by( "-max_cons_date")) }, "Login"))
def admin_invoice_detailed(request, invoice_date=None, pk=None): # fetch invoice data if pk is None: invoice = OutgoingInvoice.objects_all.filter( inventory__date=parse_date(invoice_date)).last() else: invoice = OutgoingInvoice.objects_all.get( inventory__date=parse_date(invoice_date), pk=pk) invoice_chain = list( list(reversed(list(invoice.corrected_by_iterator()))) + [invoice] + list(invoice.correction_of_iterator())) latest_in_chain = invoice_chain[0] # TODO: what what if total is equal by chance... show_latest = ( latest_in_chain.correction_of_id is None or latest_in_chain.correction_of.total != latest_in_chain.total) if not show_latest: invoice_chain = invoice_chain[1:] if pk is None: invoice = invoice_chain[0] if request.method == "POST": if not invoice.is_temporary: return HttpResponse("Not invoice not fozen.") invoice.is_frozen = True invoice.save() invoice.inventory.may_have_changed = True invoice.inventory.save() return HttpResponseRedirect(request.path) if invoice.correction_of_id is None: invoice_table, product_ids, product_names, product_loss, product_price = get_invoice_data( invoice) product_price = ((i / 100., None) for i in product_price) product_loss = ((loss, get_loss_color(loss), None, None) for loss in product_loss) else: invoice_table_diff, product_ids_diff, product_names_diff, product_loss, product_price = \ subtract_invoices(invoice.correction_of, invoice) # for now only display total amounts (override differences) invoice_table, product_ids, product_names, _, _ = get_invoice_data( invoice) product_loss = [ product_loss[product_ids_diff.index(id_)] for id_ in product_ids ] product_price = [ product_price[product_ids_diff.index(id_)] for id_ in product_ids ] product_price = ((None if i is None else i / 100., None if i2 is None else i2 / 100.) for i, i2 in product_price) product_loss = ((loss, get_loss_color(loss), loss2, get_loss_color(loss2)) for loss, loss2 in product_loss) # fetch current and nearby invoice current_date = parse_date(invoice_date) all_invoice_dates = list(get_inventory_dates()) all_invoice_dates = all_invoice_dates[ max(0, all_invoice_dates.index(current_date) - 1):all_invoice_dates.index(current_date) + 2] return render( request, 'admin/invoice.html', add_default_view_data( request, { "invoice_chain": invoice_chain, "invoice": invoice, "invoices": all_invoice_dates, "users": [i[1:] for i in invoice_table], "names": product_names, "price_each": product_price, "losses": product_loss, "date": current_date, "total": (sum(i) for i in list(zip(*invoice_table))[2:]) }, "Admin - Invoice %s" % invoice.inventory.date.strftime("%d.%m.%Y"), pre_breadcrumbs=[(TEMPLATE_BASE_URL + "invoices/", "Invoices")]))
def default_object_post(request, Model, id, template_name, additional_view_data, fields, heading, object_validator=None, parent_page="/", can_delete=None, pre_breadcrumbs=None): """ :param request: :param Model: :param id: :param template_name: :param additional_view_data: :param fields: list of (post_name, field_name, formatter) :param object_validator :param parent_page :param can_delete :return: """ assert issubclass(Model, models.Model) # get object if id is None: obj = Model() else: try: obj = Model.objects.get(pk=id) except Model.DoesNotExist: return HttpResponseNotFound("Does not exist.") # prepare view data view_data = additional_view_data.copy() view_data.update({"obj": obj}) http_status = 200 # update object if POST if request.method == "POST": def _save(): for post_name, field_name, formatter in (fields or []): if post_name not in request.POST: return 400 try: setattr(obj, field_name, formatter(request.POST[post_name])) except ValueError: # value was invalid. # TODO: best way to check for this condition? return 400 if object_validator: valid, view_data["error"] = object_validator(obj) if not valid: return 400 try: obj.save() except IntegrityError: return 400 return 200 if "delete" in request.POST: if obj.id is not None and (can_delete is None or can_delete(obj)): obj.delete() else: return HttpResponseBadRequest("Cannot delete that.") return HttpResponseRedirect(parent_page) http_status = _save() if http_status == 200: view_data["success"] = "Object Saved." else: view_data["error"] = "Something went wrong." if id is None: return HttpResponseRedirect( urllib.parse.urljoin(request.path, str(obj.pk))) return HttpResponseRedirect(request.path) # generate response return render(request, template_name, add_default_view_data(request, view_data, heading(obj), pre_breadcrumbs=pre_breadcrumbs), status=http_status)
def admin_products(request): return render( request, "admin/products.html", add_default_view_data( request, {"products": Product.objects.all().order_by("name")}, "Admin - Products"))
def admin_inventory(request, year=None, month=None, day=None): # TODO: must be more efficient # TODO: use default_object_post? if year is None: date_obj = None else: date_obj = date(int(year), int(month), int(day)) data = [] inventory = None if date_obj is not None: try: inventory = Inventory.objects.get(date=date_obj) except Inventory.DoesNotExist as e: return HttpResponseNotFound("Inventory not found for this date.") else: tmp_date = Inventory.objects.all().aggregate(Max("date"))["date__max"] tmp_date = max(date(3600, 12, 1), (tmp_date or date(3600, 12, 1))) + timedelta(days=1) inventory = Inventory(date=tmp_date) if request.method == "POST": if "delete" in request.POST: inventory.delete() return HttpResponseRedirect(TEMPLATE_BASE_URL + "inventories/") try: inventory.date = datetime.strptime(request.POST["date"], "%d.%m.%Y") except ValueError: inventory.date = datetime.now() inventory.save() for name, values in request.POST.items(): if name.startswith("inv-"): try: try: prod_inv = ProductInventory.objects.get( inventory=inventory, product_id=int(name[4:])) prod_inv.count = values except ProductInventory.DoesNotExist: prod_inv = ProductInventory(inventory=inventory, product_id=int(name[4:]), count=values) prod_inv.save() except ValueError: pass # inventory.save() return HttpResponseRedirect( urllib.parse.urljoin(TEMPLATE_BASE_URL + "inventory/", inventory.date.strftime("%Y-%m-%d"))) for prod_type in ProductType.objects.all(): type_data = [] for product in prod_type.product_set.order_by("name"): bp = BillingPeriod(inventory) pip = ProductInPeriod(bp, product) try: product_inventory = product.productinventory_set.get( inventory=inventory) except ProductInventory.DoesNotExist as e: product_inventory = None previous = 0 try: if bp.previous_billing_period is not None: previous = bp.previous_billing_period.inventory.productinventory_set.get( product=product).count except ProductInventory.DoesNotExist as e: previous = 0 expected = previous - pip.get_listed_consumptions( ) + pip.get_total_orders() type_data.append( (product, product_inventory.count if product_inventory else 0, expected, pip.get_loss(), pip.get_listed_consumptions(), pip.get_real_consumption(), get_loss_color(pip.get_loss()))) data.append((prod_type, type_data)) return render( request, "admin/inventory.html", add_default_view_data( request, { "date": date_obj, "data": data }, "Admin - Inventory: %s" % inventory.date if inventory.id else "Admin - New Inventory", pre_breadcrumbs=[(TEMPLATE_BASE_URL + "inventories/", "Inventories")]))
def admin_users(request): return render( request, 'admin/users.html', add_default_view_data( request, {"users": User.objects.all().order_by("username")}, "Admin - Users"))