From d48ae7e3a17c50ab9092877e203ce0395ad675b4 Mon Sep 17 00:00:00 2001 From: Artem Darius Weber Date: Wed, 8 Jan 2025 18:40:36 +0300 Subject: [PATCH] =?UTF-8?q?feat:=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B0=20=D1=81=D1=82=D1=80=D0=B0=D0=BD=D0=B8=D1=86?= =?UTF-8?q?=D0=B0=20=D1=81=20=D0=B3=D1=80=D0=B0=D1=84=D0=B8=D0=BA=D0=BE?= =?UTF-8?q?=D0=BC=20=D0=B4=D0=B2=D0=B8=D0=B6=D0=B5=D0=BD=D0=B8=D1=8F=20?= =?UTF-8?q?=D1=82=D0=BE=D0=B2=D0=B0=D1=80=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- logs.log | 34 +++++++++++++ warehouse/admin.py | 48 +++++++++++++++++++ .../admin/warehouse/stock_statistics.html | 7 +++ .../warehouse/stockoperation/change_list.html | 6 +++ 4 files changed, 95 insertions(+) create mode 100644 warehouse/templates/admin/warehouse/stock_statistics.html create mode 100644 warehouse/templates/admin/warehouse/stockoperation/change_list.html diff --git a/logs.log b/logs.log index e35bd10..92ab0b8 100644 --- a/logs.log +++ b/logs.log @@ -99,3 +99,37 @@ Watching for file changes with StatReloader "GET /admin/warehouse/stockoperation/1/change/ HTTP/1.1" 200 19394 "GET /admin/jsi18n/ HTTP/1.1" 200 3342 "GET /admin/warehouse/stockoperation/ HTTP/1.1" 200 14799 +Watching for file changes with StatReloader +"GET /admin/warehouse/stockoperation/ HTTP/1.1" 200 14886 +"GET /admin/jsi18n/ HTTP/1.1" 200 3342 +Watching for file changes with StatReloader +"GET /admin/warehouse/stockoperation/ HTTP/1.1" 200 14914 +"GET /admin/jsi18n/ HTTP/1.1" 200 3342 +/Users/darius/Documents/franchise_store/warehouse/admin.py changed, reloading. +Watching for file changes with StatReloader +/Users/darius/Documents/franchise_store/warehouse/admin.py changed, reloading. +Watching for file changes with StatReloader +/Users/darius/Documents/franchise_store/warehouse/admin.py changed, reloading. +Watching for file changes with StatReloader +Watching for file changes with StatReloader +"GET /admin/warehouse/stockoperation/ HTTP/1.1" 200 14886 +"GET /admin/jsi18n/ HTTP/1.1" 200 3342 +"GET /admin/warehouse/stockoperation/statistics/ HTTP/1.1" 200 24699 +"GET /admin/warehouse/stockoperation/ HTTP/1.1" 200 14886 +"GET /admin/warehouse/stockoperation/add/ HTTP/1.1" 200 19071 +"GET /admin/jsi18n/ HTTP/1.1" 200 3342 +"GET /admin/product_directory/product/1/change/?_to_field=id&_popup=1 HTTP/1.1" 200 10158 +"GET /admin/jsi18n/ HTTP/1.1" 200 3342 +"GET /admin/product_directory/product/1/change/?_to_field=id HTTP/1.1" 200 17244 +"GET /admin/jsi18n/ HTTP/1.1" 200 3342 +"GET /admin/warehouse/stockoperation/add/ HTTP/1.1" 200 19071 +"GET /admin/product_directory/product/add/?_to_field=id&_popup=1 HTTP/1.1" 200 10066 +"GET /admin/jsi18n/ HTTP/1.1" 200 3342 +"POST /admin/warehouse/stockoperation/add/ HTTP/1.1" 302 0 +"GET /admin/warehouse/stockoperation/ HTTP/1.1" 200 15687 +"GET /admin/jsi18n/ HTTP/1.1" 200 3342 +"GET /admin/warehouse/stockoperation/statistics/ HTTP/1.1" 200 28103 +"GET /admin/warehouse/stockoperation/ HTTP/1.1" 200 15416 +"GET /admin/jsi18n/ HTTP/1.1" 200 3342 +"GET /admin/warehouse/stockoperation/statistics/ HTTP/1.1" 200 28103 +"GET /admin/warehouse/stockoperation/ HTTP/1.1" 200 15416 diff --git a/warehouse/admin.py b/warehouse/admin.py index 2914f5a..260a64a 100644 --- a/warehouse/admin.py +++ b/warehouse/admin.py @@ -1,5 +1,13 @@ from django.contrib import admin from .models import Warehouse, StorageLocation, StockOperation +from django.urls import path +from django.shortcuts import render +import matplotlib.pyplot as plt +from io import BytesIO +import base64 + +import matplotlib +matplotlib.use('Agg') @admin.register(Warehouse) class WarehouseAdmin(admin.ModelAdmin): @@ -19,3 +27,43 @@ class StockOperationAdmin(admin.ModelAdmin): list_display = ('product', 'warehouse', 'operation_type', 'quantity', 'operation_date') search_fields = ('product__name', 'warehouse__name', 'operation_type') list_filter = ('operation_type', 'operation_date') + + def changelist_view(self, request, extra_context=None): + extra_context = extra_context or {} + extra_context['custom_button'] = { + 'url': 'statistics/', + 'label': 'Просмотреть статистику' + } + return super().changelist_view(request, extra_context) + + def get_urls(self): + urls = super().get_urls() + custom_urls = [ + path('statistics/', self.admin_site.admin_view(self.statistics_view), name='stock_operation_statistics'), + ] + return custom_urls + urls + + def statistics_view(self, request): + operations = StockOperation.objects.all() + incoming_count = operations.filter(operation_type='Incoming').count() + outgoing_count = operations.filter(operation_type='Outgoing').count() + transfer_count = operations.filter(operation_type='Transfer').count() + writeoff_count = operations.filter(operation_type='WriteOff').count() + + labels = ['Incoming', 'Outgoing', 'Transfer', 'WriteOff'] + data = [incoming_count, outgoing_count, transfer_count, writeoff_count] + + plt.figure(figsize=(6, 6)) + plt.pie(data, labels=labels, autopct='%1.1f%%', startangle=90) + plt.axis('equal') + + buffer = BytesIO() + plt.savefig(buffer, format='png') + buffer.seek(0) + image_png = buffer.getvalue() + buffer.close() + + chart = base64.b64encode(image_png).decode('utf-8') + + context = {'chart': chart} + return render(request, 'admin/warehouse/stock_statistics.html', context) \ No newline at end of file diff --git a/warehouse/templates/admin/warehouse/stock_statistics.html b/warehouse/templates/admin/warehouse/stock_statistics.html new file mode 100644 index 0000000..1a7f2c4 --- /dev/null +++ b/warehouse/templates/admin/warehouse/stock_statistics.html @@ -0,0 +1,7 @@ +{% extends "admin/base_site.html" %} + +{% block content %} +

Статистика операций на складе

+График статистики +Назад к списку операций +{% endblock %} diff --git a/warehouse/templates/admin/warehouse/stockoperation/change_list.html b/warehouse/templates/admin/warehouse/stockoperation/change_list.html new file mode 100644 index 0000000..abf58f4 --- /dev/null +++ b/warehouse/templates/admin/warehouse/stockoperation/change_list.html @@ -0,0 +1,6 @@ +{% extends "admin/change_list.html" %} + +{% block object-tools %} +{{ block.super }} +{{ custom_button.label }} +{% endblock %}