diff --git a/hq/__init__.py b/hq/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/hq/admin.py b/hq/admin.py new file mode 100644 index 0000000..c8e7f2b --- /dev/null +++ b/hq/admin.py @@ -0,0 +1,10 @@ +from django.contrib import admin +from .models import Product, Employee, Contractor, ContractorContact + +@admin.register(Product) +class ProductAdmin(admin.ModelAdmin): + list_display = ('name', 'manufacturer', 'shelf_life', 'barcode') + +@admin.register(Employee) +class EmployeeAdmin(admin.ModelAdmin): + list_display = ('full_name', 'position', 'login', 'work_phone') diff --git a/hq/apps.py b/hq/apps.py new file mode 100644 index 0000000..74c86b7 --- /dev/null +++ b/hq/apps.py @@ -0,0 +1,6 @@ +from django.apps import AppConfig + + +class HQConfig(AppConfig): + default_auto_field = 'django.db.models.BigAutoField' + name = 'hq' diff --git a/hq/migrations/0001_initial.py b/hq/migrations/0001_initial.py new file mode 100644 index 0000000..605f867 --- /dev/null +++ b/hq/migrations/0001_initial.py @@ -0,0 +1,67 @@ +# Generated by Django 5.1.4 on 2025-01-09 09:26 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='Contractor', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=255)), + ('contract_number', models.CharField(max_length=100)), + ('address', models.TextField()), + ], + ), + migrations.CreateModel( + name='Employee', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('full_name', models.CharField(max_length=255)), + ('passport_series', models.CharField(max_length=10)), + ('passport_number', models.CharField(max_length=10)), + ('birth_date', models.DateField()), + ('position', models.CharField(max_length=255)), + ('department', models.CharField(max_length=255)), + ('login', models.CharField(max_length=100, unique=True)), + ('password', models.CharField(max_length=100)), + ('role', models.CharField(max_length=100)), + ('work_phone', models.CharField(max_length=20)), + ('personal_phone', models.CharField(blank=True, max_length=20, null=True)), + ('email', models.EmailField(max_length=254)), + ], + ), + migrations.CreateModel( + name='Product', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('name', models.CharField(max_length=255)), + ('manufacturer', models.CharField(max_length=255)), + ('manufacturer_country', models.CharField(max_length=255)), + ('manufacturer_code', models.CharField(max_length=50)), + ('dimensions', models.CharField(blank=True, max_length=255, null=True)), + ('unit', models.CharField(max_length=50)), + ('shelf_life', models.IntegerField()), + ('barcode', models.CharField(max_length=50)), + ('additional_info', models.TextField(blank=True, null=True)), + ], + ), + migrations.CreateModel( + name='ContractorContact', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('full_name', models.CharField(max_length=255)), + ('phone', models.CharField(max_length=20)), + ('email', models.EmailField(max_length=254)), + ('contractor', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='contacts', to='hq.contractor')), + ], + ), + ] diff --git a/hq/migrations/__init__.py b/hq/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/hq/models.py b/hq/models.py new file mode 100644 index 0000000..0189d05 --- /dev/null +++ b/hq/models.py @@ -0,0 +1,38 @@ +from django.db import models + +class Product(models.Model): + name = models.CharField(max_length=255) + manufacturer = models.CharField(max_length=255) + manufacturer_country = models.CharField(max_length=255) + manufacturer_code = models.CharField(max_length=50) + dimensions = models.CharField(max_length=255, null=True, blank=True) + unit = models.CharField(max_length=50) + shelf_life = models.IntegerField() # Срок годности в днях + barcode = models.CharField(max_length=50) + additional_info = models.TextField(null=True, blank=True) + +class Employee(models.Model): + full_name = models.CharField(max_length=255) + passport_series = models.CharField(max_length=10) + passport_number = models.CharField(max_length=10) + birth_date = models.DateField() + position = models.CharField(max_length=255) + department = models.CharField(max_length=255) + login = models.CharField(max_length=100, unique=True) + password = models.CharField(max_length=100) + role = models.CharField(max_length=100) + work_phone = models.CharField(max_length=20) + personal_phone = models.CharField(max_length=20, null=True, blank=True) + email = models.EmailField() + +# Пример дополнительных моделей +class Contractor(models.Model): + name = models.CharField(max_length=255) + contract_number = models.CharField(max_length=100) + address = models.TextField() + +class ContractorContact(models.Model): + contractor = models.ForeignKey(Contractor, on_delete=models.CASCADE, related_name="contacts") + full_name = models.CharField(max_length=255) + phone = models.CharField(max_length=20) + email = models.EmailField() diff --git a/hq/serializers.py b/hq/serializers.py new file mode 100644 index 0000000..62cdd3e --- /dev/null +++ b/hq/serializers.py @@ -0,0 +1,29 @@ +from rest_framework import serializers +from .models import Product, Employee, Contractor, ContractorContact + +class ProductSerializer(serializers.ModelSerializer): + class Meta: + model = Product + fields = [ + 'id', 'name', 'manufacturer', 'manufacturer_country', 'manufacturer_code', + 'dimensions', 'unit', 'shelf_life', 'barcode', 'additional_info' + ] + +class EmployeeSerializer(serializers.ModelSerializer): + class Meta: + model = Employee + fields = [ + 'id', 'full_name', 'passport_series', 'passport_number', 'birth_date', + 'position', 'department', 'login', 'password', 'role', 'work_phone', + 'personal_phone', 'email' + ] + +class ContractorSerializer(serializers.ModelSerializer): + class Meta: + model = Contractor + fields = ['id', 'name', 'contract_number', 'address'] + +class ContractorContactSerializer(serializers.ModelSerializer): + class Meta: + model = ContractorContact + fields = ['id', 'contractor', 'full_name', 'phone', 'email'] diff --git a/hq/tests.py b/hq/tests.py new file mode 100644 index 0000000..e69de29 diff --git a/hq/urls.py b/hq/urls.py new file mode 100644 index 0000000..184290f --- /dev/null +++ b/hq/urls.py @@ -0,0 +1,9 @@ +from django.urls import path +from .views import ProductUploadView, EmployeeUploadView, ContractorUploadView, ContractorContactUploadView + +urlpatterns = [ + path('api/products/upload/', ProductUploadView.as_view(), name='product-upload'), + path('api/employees/upload/', EmployeeUploadView.as_view(), name='employee-upload'), + path('api/contractors/upload/', ContractorUploadView.as_view(), name='contractor-upload'), + path('api/contractor-contacts/upload/', ContractorContactUploadView.as_view(), name='contractor-contact-upload'), +] diff --git a/hq/views.py b/hq/views.py new file mode 100644 index 0000000..85d88af --- /dev/null +++ b/hq/views.py @@ -0,0 +1,37 @@ +from rest_framework.views import APIView +from rest_framework.response import Response +from rest_framework import status +from .models import Product, Employee, Contractor, ContractorContact +from .serializers import ProductSerializer, EmployeeSerializer, ContractorSerializer, ContractorContactSerializer + +class ProductUploadView(APIView): + def post(self, request, *args, **kwargs): + serializer = ProductSerializer(data=request.data, many=True) + if serializer.is_valid(): + serializer.save() + return Response({"message": "Products uploaded successfully"}, status=status.HTTP_201_CREATED) + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + +class EmployeeUploadView(APIView): + def post(self, request, *args, **kwargs): + serializer = EmployeeSerializer(data=request.data, many=True) + if serializer.is_valid(): + serializer.save() + return Response({"message": "Employees uploaded successfully"}, status=status.HTTP_201_CREATED) + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + +class ContractorUploadView(APIView): + def post(self, request, *args, **kwargs): + serializer = ContractorSerializer(data=request.data, many=True) + if serializer.is_valid(): + serializer.save() + return Response({"message": "Contractors uploaded successfully"}, status=status.HTTP_201_CREATED) + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) + +class ContractorContactUploadView(APIView): + def post(self, request, *args, **kwargs): + serializer = ContractorContactSerializer(data=request.data, many=True) + if serializer.is_valid(): + serializer.save() + return Response({"message": "Contractor contacts uploaded successfully"}, status=status.HTTP_201_CREATED) + return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) diff --git a/hr/migrations/0001_initial.py b/hr/migrations/0001_initial.py new file mode 100644 index 0000000..8f35336 --- /dev/null +++ b/hr/migrations/0001_initial.py @@ -0,0 +1,69 @@ +# Generated by Django 5.1.4 on 2025-01-09 09:45 + +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + initial = True + + dependencies = [ + ] + + operations = [ + migrations.CreateModel( + name='Employee', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('first_name', models.CharField(max_length=50)), + ('last_name', models.CharField(max_length=50)), + ('position', models.CharField(max_length=100)), + ('email', models.EmailField(max_length=254, unique=True)), + ('hired_date', models.DateField()), + ('work_schedule', models.JSONField(default=dict)), + ], + ), + migrations.CreateModel( + name='Leave', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('leave_type', models.CharField(choices=[('vacation', 'Vacation'), ('sick', 'Sick Leave')], max_length=10)), + ('start_date', models.DateField()), + ('end_date', models.DateField()), + ('reason', models.TextField(blank=True)), + ('employee', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='hr.employee')), + ], + ), + migrations.CreateModel( + name='OvertimeReport', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('date', models.DateField()), + ('worked_hours', models.FloatField()), + ('required_hours', models.FloatField(default=8.0)), + ('overtime', models.FloatField()), + ('comment', models.TextField(blank=True)), + ('employee', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='hr.employee')), + ], + ), + migrations.CreateModel( + name='Report', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('report_date', models.DateField(auto_now_add=True)), + ('employee', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='hr.employee')), + ], + ), + migrations.CreateModel( + name='WorkTimeLog', + fields=[ + ('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')), + ('date', models.DateField()), + ('check_in', models.TimeField(blank=True, null=True)), + ('check_out', models.TimeField(blank=True, null=True)), + ('worked_hours', models.FloatField(blank=True, null=True)), + ('employee', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, to='hr.employee')), + ], + ), + ] diff --git a/hr/migrations/__init__.py b/hr/migrations/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/hr/urls.py b/hr/urls.py index 6d88889..5eed527 100644 --- a/hr/urls.py +++ b/hr/urls.py @@ -7,14 +7,16 @@ from .views import ( EmployeeViewSet, WorkTimeLogViewSet, LeaveViewSet, OvertimeReportViewSet, ReportViewSet ) +from .views import generate_employee_report # Create the router for HR-related views router_hr = DefaultRouter() router_hr.register(r'employees', EmployeeViewSet) router_hr.register(r'work-time-logs', WorkTimeLogViewSet) -router_hr.register(r'leaves', LeaveViewSet) router_hr.register(r'overtime-reports', OvertimeReportViewSet) router_hr.register(r'reports', ReportViewSet) +router_hr.register(r'work-time-logs', WorkTimeLogViewSet, basename='work-time-log') +router_hr.register(r'leaves', LeaveViewSet, basename='leave') # Swagger schema view for HR schema_view_hr = get_schema_view( @@ -34,4 +36,5 @@ urlpatterns = [ path('', include(router_hr.urls)), path('swagger/', schema_view_hr.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui-hr'), path('redoc/', schema_view_hr.with_ui('redoc', cache_timeout=0), name='schema-redoc-hr'), + path('generate-report//', generate_employee_report, name='generate_employee_report'), ] diff --git a/hr/views.py b/hr/views.py index f958047..14c2a4d 100644 --- a/hr/views.py +++ b/hr/views.py @@ -5,7 +5,51 @@ from .serializers import ( OvertimeReportSerializer, ReportSerializer ) -# ViewSet для модели Employee +from django.http import FileResponse +from django.shortcuts import get_object_or_404 +from rest_framework import viewsets +from rest_framework.filters import OrderingFilter +from django_filters.rest_framework import DjangoFilterBackend + +class WorkTimeLogViewSet(viewsets.ModelViewSet): + queryset = WorkTimeLog.objects.all() + serializer_class = WorkTimeLogSerializer + filter_backends = [DjangoFilterBackend, OrderingFilter] + filterset_fields = { + 'employee__id': ['exact'], + 'date': ['gte', 'lte'], + } + ordering_fields = ['date'] + +class LeaveViewSet(viewsets.ModelViewSet): + queryset = Leave.objects.all() + serializer_class = LeaveSerializer + filter_backends = [DjangoFilterBackend, OrderingFilter] + filterset_fields = { + 'employee__id': ['exact'], + 'start_date': ['gte', 'lte'], + 'end_date': ['gte', 'lte'], + } + ordering_fields = ['start_date', 'end_date'] + +class OvertimeReportViewSet(viewsets.ModelViewSet): + queryset = OvertimeReport.objects.all() + serializer_class = OvertimeReportSerializer + filter_backends = [DjangoFilterBackend, OrderingFilter] + filterset_fields = { + 'employee__id': ['exact'], + 'date': ['gte', 'lte'], + } + ordering_fields = ['date'] + +def generate_employee_report(request, report_id): + """ + Генерация отчета с фильтрацией по диапазону дат. + """ + report = get_object_or_404(Report, id=report_id) + pdf_buffer = report.generate_pdf() + return FileResponse(pdf_buffer, as_attachment=True, filename=f"отчет_{report.employee.last_name}.pdf") + class EmployeeViewSet(viewsets.ModelViewSet): queryset = Employee.objects.all() serializer_class = EmployeeSerializer diff --git a/logs.log b/logs.log index 4e2998f..dbc9113 100644 --- a/logs.log +++ b/logs.log @@ -732,177 +732,224 @@ django.template.exceptions.TemplateSyntaxError: + self.child.create(attrs) for attrs in validated_data + File "/home/dark/miniconda3/envs/django/lib/python3.10/site-packages/rest_framework/serializers.py", line 989, in create + instance = ModelClass._default_manager.create(**validated_data) + File "/home/dark/miniconda3/envs/django/lib/python3.10/site-packages/django/db/models/manager.py", line 87, in manager_method + return getattr(self.get_queryset(), name)(*args, **kwargs) + File "/home/dark/miniconda3/envs/django/lib/python3.10/site-packages/django/db/models/query.py", line 679, in create + obj.save(force_insert=True, using=self.db) + File "/home/dark/miniconda3/envs/django/lib/python3.10/site-packages/django/db/models/base.py", line 892, in save + self.save_base( + File "/home/dark/miniconda3/envs/django/lib/python3.10/site-packages/django/db/models/base.py", line 998, in save_base + updated = self._save_table( + File "/home/dark/miniconda3/envs/django/lib/python3.10/site-packages/django/db/models/base.py", line 1161, in _save_table + results = self._do_insert( + File "/home/dark/miniconda3/envs/django/lib/python3.10/site-packages/django/db/models/base.py", line 1202, in _do_insert + return manager._insert( + File "/home/dark/miniconda3/envs/django/lib/python3.10/site-packages/django/db/models/manager.py", line 87, in manager_method + return getattr(self.get_queryset(), name)(*args, **kwargs) + File "/home/dark/miniconda3/envs/django/lib/python3.10/site-packages/django/db/models/query.py", line 1847, in _insert + return query.get_compiler(using=using).execute_sql(returning_fields) + File "/home/dark/miniconda3/envs/django/lib/python3.10/site-packages/django/db/models/sql/compiler.py", line 1836, in execute_sql cursor.execute(sql, params) - File "/Users/darius/anaconda3/envs/django_env/lib/python3.10/site-packages/django/db/backends/utils.py", line 122, in execute + File "/home/dark/miniconda3/envs/django/lib/python3.10/site-packages/django/db/backends/utils.py", line 122, in execute return super().execute(sql, params) - File "/Users/darius/anaconda3/envs/django_env/lib/python3.10/site-packages/django/db/backends/utils.py", line 79, in execute + File "/home/dark/miniconda3/envs/django/lib/python3.10/site-packages/django/db/backends/utils.py", line 79, in execute return self._execute_with_wrappers( - File "/Users/darius/anaconda3/envs/django_env/lib/python3.10/site-packages/django/db/backends/utils.py", line 92, in _execute_with_wrappers + File "/home/dark/miniconda3/envs/django/lib/python3.10/site-packages/django/db/backends/utils.py", line 92, in _execute_with_wrappers return executor(sql, params, many, context) - File "/Users/darius/anaconda3/envs/django_env/lib/python3.10/site-packages/django/db/backends/utils.py", line 100, in _execute + File "/home/dark/miniconda3/envs/django/lib/python3.10/site-packages/django/db/backends/utils.py", line 100, in _execute with self.db.wrap_database_errors: - File "/Users/darius/anaconda3/envs/django_env/lib/python3.10/site-packages/django/db/utils.py", line 91, in __exit__ + File "/home/dark/miniconda3/envs/django/lib/python3.10/site-packages/django/db/utils.py", line 91, in __exit__ raise dj_exc_value.with_traceback(traceback) from exc_value - File "/Users/darius/anaconda3/envs/django_env/lib/python3.10/site-packages/django/db/backends/utils.py", line 105, in _execute + File "/home/dark/miniconda3/envs/django/lib/python3.10/site-packages/django/db/backends/utils.py", line 105, in _execute return self.cursor.execute(sql, params) -django.db.utils.ProgrammingError: column inventory_inventory.warehouse_id does not exist -LINE 1: ...y_inventory" INNER JOIN "warehouse_warehouse" ON ("inventory... - ^ +django.db.utils.ProgrammingError: relation "hq_product" does not exist +LINE 1: INSERT INTO "hq_product" ("name", "manufacturer", "manufactu... + ^ -"GET /admin/inventory/inventory/ HTTP/1.1" 500 168430 -Watching for file changes with StatReloader -"GET /admin/inventory/inventory/ HTTP/1.1" 200 13200 -"GET /static/admin/js/core.js HTTP/1.1" 304 0 -"GET /static/admin/css/changelists.css HTTP/1.1" 304 0 -"GET /static/admin/js/vendor/jquery/jquery.js HTTP/1.1" 304 0 -"GET /static/admin/js/actions.js HTTP/1.1" 304 0 -"GET /static/admin/js/admin/RelatedObjectLookups.js HTTP/1.1" 304 0 -"GET /static/admin/js/prepopulate.js HTTP/1.1" 304 0 -"GET /static/admin/js/jquery.init.js HTTP/1.1" 304 0 -"GET /static/admin/js/vendor/xregexp/xregexp.js HTTP/1.1" 304 0 -"GET /static/admin/js/urlify.js HTTP/1.1" 304 0 -"GET /static/admin/img/search.svg HTTP/1.1" 304 0 -"GET /static/admin/js/filters.js HTTP/1.1" 304 0 -"GET /admin/jsi18n/ HTTP/1.1" 200 3342 -"GET /static/admin/img/tooltag-add.svg HTTP/1.1" 304 0 -"GET /static/admin/img/icon-viewlink.svg HTTP/1.1" 304 0 -"GET /admin/inventory/inventory/ HTTP/1.1" 200 13200 -"GET /admin/jsi18n/ HTTP/1.1" 200 3342 -"GET /admin/inventory/inventory/add/ HTTP/1.1" 200 17583 -"GET /static/admin/css/forms.css HTTP/1.1" 304 0 -"GET /static/admin/css/widgets.css HTTP/1.1" 304 0 -"GET /static/admin/js/prepopulate_init.js HTTP/1.1" 304 0 -"GET /static/admin/js/change_form.js HTTP/1.1" 304 0 -"GET /admin/jsi18n/ HTTP/1.1" 200 3342 -"GET /admin/inventory/inventory/ HTTP/1.1" 200 13200 -"GET /admin/ HTTP/1.1" 200 13650 -"GET /api/warehouse/ HTTP/1.1" 200 3048 -"GET /static/css/styles.css HTTP/1.1" 304 0 -"GET /api/warehouse/warehouses/ HTTP/1.1" 200 2674 -"GET /api/warehouse/operations/ HTTP/1.1" 200 3296 -"GET /api/warehouse/scan-barcode-camera/ HTTP/1.1" 200 3627 -"GET /static/js/scan_barcode.js HTTP/1.1" 304 0 -"GET /api/warehouse/ HTTP/1.1" 200 3048 -Watching for file changes with StatReloader -Not Found: / -"GET / HTTP/1.1" 404 3084 -Not Found: /favicon.ico -"GET /favicon.ico HTTP/1.1" 404 3135 -Not Found: /api -"GET /api HTTP/1.1" 404 3111 -Not Found: /api/swagger -"GET /api/swagger HTTP/1.1" 404 3135 -Not Found: /api/docs -"GET /api/docs HTTP/1.1" 404 3126 -Not Found: /warehouse/scan-barcode-camera/ -"GET /warehouse/scan-barcode-camera/ HTTP/1.1" 404 3192 -"GET /api/warehouse/ HTTP/1.1" 200 3048 -"GET /static/css/styles.css HTTP/1.1" 200 393 -"GET /admin/ HTTP/1.1" 302 0 -"GET /admin/login/?next=/admin/ HTTP/1.1" 200 4165 -"GET /static/admin/css/base.css HTTP/1.1" 200 22092 -"GET /static/admin/css/nav_sidebar.css HTTP/1.1" 200 2810 -"GET /static/admin/css/login.css HTTP/1.1" 200 951 -"GET /static/admin/css/dark_mode.css HTTP/1.1" 200 2804 -"GET /static/admin/js/theme.js HTTP/1.1" 200 1653 -"GET /static/admin/css/responsive.css HTTP/1.1" 200 17972 -"GET /static/admin/js/nav_sidebar.js HTTP/1.1" 200 3063 -Not Found: / -"GET / HTTP/1.1" 404 3084 -Not Found: /api -"GET /api HTTP/1.1" 404 3111 -Not Found: /api/docs -"GET /api/docs HTTP/1.1" 404 3126 -Not Found: /api/swagger -"GET /api/swagger HTTP/1.1" 404 3135 -"GET /api/hr/swagger HTTP/1.1" 301 0 -"GET /api/hr/swagger/ HTTP/1.1" 200 2229 -"GET /static/drf-yasg/style.css HTTP/1.1" 200 1047 -"GET /static/drf-yasg/insQ.min.js HTTP/1.1" 200 2093 -"GET /static/drf-yasg/immutable.min.js HTTP/1.1" 200 56904 -"GET /static/drf-yasg/swagger-ui-init.js HTTP/1.1" 200 15480 -"GET /static/drf-yasg/swagger-ui-dist/swagger-ui.css HTTP/1.1" 200 145206 -"GET /static/drf-yasg/swagger-ui-dist/swagger-ui-standalone-preset.js HTTP/1.1" 200 322863 -"GET /static/drf-yasg/swagger-ui-dist/swagger-ui-bundle.js HTTP/1.1" 200 1046583 -"GET /api/hr/swagger/?format=openapi HTTP/1.1" 200 54931 -"GET /static/drf-yasg/swagger-ui-dist/favicon-32x32.png HTTP/1.1" 200 628 -"POST /admin/login/?next=/admin/ HTTP/1.1" 302 0 -"GET /admin/ HTTP/1.1" 200 10909 -"GET /static/admin/css/dashboard.css HTTP/1.1" 200 441 -"GET /static/admin/img/icon-addlink.svg HTTP/1.1" 200 331 -"GET /static/admin/img/icon-changelink.svg HTTP/1.1" 200 380 -"GET /api/hr/swagger/ HTTP/1.1" 200 2458 -"GET /api/hr/swagger/?format=openapi HTTP/1.1" 200 54931 -/Users/darius/Documents/franchise_store/logistic/urls.py changed, reloading. +"POST /api/hq/api/products/upload/ HTTP/1.1" 500 215430 Watching for file changes with StatReloader -"GET /api/hr/swagger/ HTTP/1.1" 200 2458 -"GET /api/hr/swagger/?format=openapi HTTP/1.1" 200 54931 -/Users/darius/Documents/franchise_store/logistic/views.py changed, reloading. -Watching for file changes with StatReloader -/Users/darius/Documents/franchise_store/logistic/urls.py changed, reloading. -Watching for file changes with StatReloader -"GET /api/hr/swagger/ HTTP/1.1" 200 2458 -"GET /api/hr/swagger/?format=openapi HTTP/1.1" 200 54931 -/Users/darius/Documents/franchise_store/logistic/urls.py changed, reloading. -Watching for file changes with StatReloader -/Users/darius/Documents/franchise_store/logistic/urls.py changed, reloading. +Internal Server Error: /api/hq/api/products/upload/ +Traceback (most recent call last): + File "/home/dark/miniconda3/envs/django/lib/python3.10/site-packages/django/db/backends/utils.py", line 105, in _execute + return self.cursor.execute(sql, params) +psycopg2.errors.UndefinedTable: relation "hq_product" does not exist +LINE 1: INSERT INTO "hq_product" ("name", "manufacturer", "manufactu... + ^ + + +The above exception was the direct cause of the following exception: + +Traceback (most recent call last): + File "/home/dark/miniconda3/envs/django/lib/python3.10/site-packages/django/core/handlers/exception.py", line 55, in inner + response = get_response(request) + File "/home/dark/miniconda3/envs/django/lib/python3.10/site-packages/django/core/handlers/base.py", line 197, in _get_response + response = wrapped_callback(request, *callback_args, **callback_kwargs) + File "/home/dark/miniconda3/envs/django/lib/python3.10/site-packages/django/views/decorators/csrf.py", line 65, in _view_wrapper + return view_func(request, *args, **kwargs) + File "/home/dark/miniconda3/envs/django/lib/python3.10/site-packages/django/views/generic/base.py", line 104, in view + return self.dispatch(request, *args, **kwargs) + File "/home/dark/miniconda3/envs/django/lib/python3.10/site-packages/rest_framework/views.py", line 509, in dispatch + response = self.handle_exception(exc) + File "/home/dark/miniconda3/envs/django/lib/python3.10/site-packages/rest_framework/views.py", line 469, in handle_exception + self.raise_uncaught_exception(exc) + File "/home/dark/miniconda3/envs/django/lib/python3.10/site-packages/rest_framework/views.py", line 480, in raise_uncaught_exception + raise exc + File "/home/dark/miniconda3/envs/django/lib/python3.10/site-packages/rest_framework/views.py", line 506, in dispatch + response = handler(request, *args, **kwargs) + File "/home/dark/Documents/GitHub/store-management-system/hq/views.py", line 11, in post + serializer.save() + File "/home/dark/miniconda3/envs/django/lib/python3.10/site-packages/rest_framework/serializers.py", line 758, in save + self.instance = self.create(validated_data) + File "/home/dark/miniconda3/envs/django/lib/python3.10/site-packages/rest_framework/serializers.py", line 730, in create + return [ + File "/home/dark/miniconda3/envs/django/lib/python3.10/site-packages/rest_framework/serializers.py", line 731, in + self.child.create(attrs) for attrs in validated_data + File "/home/dark/miniconda3/envs/django/lib/python3.10/site-packages/rest_framework/serializers.py", line 989, in create + instance = ModelClass._default_manager.create(**validated_data) + File "/home/dark/miniconda3/envs/django/lib/python3.10/site-packages/django/db/models/manager.py", line 87, in manager_method + return getattr(self.get_queryset(), name)(*args, **kwargs) + File "/home/dark/miniconda3/envs/django/lib/python3.10/site-packages/django/db/models/query.py", line 679, in create + obj.save(force_insert=True, using=self.db) + File "/home/dark/miniconda3/envs/django/lib/python3.10/site-packages/django/db/models/base.py", line 892, in save + self.save_base( + File "/home/dark/miniconda3/envs/django/lib/python3.10/site-packages/django/db/models/base.py", line 998, in save_base + updated = self._save_table( + File "/home/dark/miniconda3/envs/django/lib/python3.10/site-packages/django/db/models/base.py", line 1161, in _save_table + results = self._do_insert( + File "/home/dark/miniconda3/envs/django/lib/python3.10/site-packages/django/db/models/base.py", line 1202, in _do_insert + return manager._insert( + File "/home/dark/miniconda3/envs/django/lib/python3.10/site-packages/django/db/models/manager.py", line 87, in manager_method + return getattr(self.get_queryset(), name)(*args, **kwargs) + File "/home/dark/miniconda3/envs/django/lib/python3.10/site-packages/django/db/models/query.py", line 1847, in _insert + return query.get_compiler(using=using).execute_sql(returning_fields) + File "/home/dark/miniconda3/envs/django/lib/python3.10/site-packages/django/db/models/sql/compiler.py", line 1836, in execute_sql + cursor.execute(sql, params) + File "/home/dark/miniconda3/envs/django/lib/python3.10/site-packages/django/db/backends/utils.py", line 122, in execute + return super().execute(sql, params) + File "/home/dark/miniconda3/envs/django/lib/python3.10/site-packages/django/db/backends/utils.py", line 79, in execute + return self._execute_with_wrappers( + File "/home/dark/miniconda3/envs/django/lib/python3.10/site-packages/django/db/backends/utils.py", line 92, in _execute_with_wrappers + return executor(sql, params, many, context) + File "/home/dark/miniconda3/envs/django/lib/python3.10/site-packages/django/db/backends/utils.py", line 100, in _execute + with self.db.wrap_database_errors: + File "/home/dark/miniconda3/envs/django/lib/python3.10/site-packages/django/db/utils.py", line 91, in __exit__ + raise dj_exc_value.with_traceback(traceback) from exc_value + File "/home/dark/miniconda3/envs/django/lib/python3.10/site-packages/django/db/backends/utils.py", line 105, in _execute + return self.cursor.execute(sql, params) +django.db.utils.ProgrammingError: relation "hq_product" does not exist +LINE 1: INSERT INTO "hq_product" ("name", "manufacturer", "manufactu... + ^ + +"POST /api/hq/api/products/upload/ HTTP/1.1" 500 215430 Watching for file changes with StatReloader -/Users/darius/Documents/franchise_store/logistic/urls.py changed, reloading. +"POST /api/hq/api/products/upload/ HTTP/1.1" 201 44 +Internal Server Error: /api/hq/api/contractors/upload +Traceback (most recent call last): + File "/home/dark/miniconda3/envs/django/lib/python3.10/site-packages/django/core/handlers/exception.py", line 55, in inner + response = get_response(request) + File "/home/dark/miniconda3/envs/django/lib/python3.10/site-packages/django/utils/deprecation.py", line 131, in __call__ + response = self.process_response(request, response) + File "/home/dark/miniconda3/envs/django/lib/python3.10/site-packages/django/middleware/common.py", line 108, in process_response + return self.response_redirect_class(self.get_full_path_with_slash(request)) + File "/home/dark/miniconda3/envs/django/lib/python3.10/site-packages/django/middleware/common.py", line 87, in get_full_path_with_slash + raise RuntimeError( +RuntimeError: You called this URL via POST, but the URL doesn't end in a slash and you have APPEND_SLASH set. Django can't redirect to the slash URL while maintaining POST data. Change your form to point to 127.0.0.1:8000/api/hq/api/contractors/upload/ (note the trailing slash), or set APPEND_SLASH=False in your Django settings. +"POST /api/hq/api/contractors/upload HTTP/1.1" 500 78748 +Internal Server Error: /api/hq/api/employees/upload +Traceback (most recent call last): + File "/home/dark/miniconda3/envs/django/lib/python3.10/site-packages/django/core/handlers/exception.py", line 55, in inner + response = get_response(request) + File "/home/dark/miniconda3/envs/django/lib/python3.10/site-packages/django/utils/deprecation.py", line 131, in __call__ + response = self.process_response(request, response) + File "/home/dark/miniconda3/envs/django/lib/python3.10/site-packages/django/middleware/common.py", line 108, in process_response + return self.response_redirect_class(self.get_full_path_with_slash(request)) + File "/home/dark/miniconda3/envs/django/lib/python3.10/site-packages/django/middleware/common.py", line 87, in get_full_path_with_slash + raise RuntimeError( +RuntimeError: You called this URL via POST, but the URL doesn't end in a slash and you have APPEND_SLASH set. Django can't redirect to the slash URL while maintaining POST data. Change your form to point to 127.0.0.1:8000/api/hq/api/employees/upload/ (note the trailing slash), or set APPEND_SLASH=False in your Django settings. +"POST /api/hq/api/employees/upload HTTP/1.1" 500 78716 +"POST /api/hq/api/employees/upload/ HTTP/1.1" 201 45 +"POST /api/hq/api/contractors/upload/ HTTP/1.1" 201 47 +"POST /api/hq/api/contractor-contacts/upload/ HTTP/1.1" 201 55 Watching for file changes with StatReloader -"GET /api/hr/swagger/ HTTP/1.1" 200 2458 -"GET /api/hr/swagger/?format=openapi HTTP/1.1" 200 54931 +"GET /api/hr/ HTTP/1.1" 200 10827 diff --git a/settings/__pycache__/base.cpython-310.pyc b/settings/__pycache__/base.cpython-310.pyc index 4de4eb8..92793c0 100644 Binary files a/settings/__pycache__/base.cpython-310.pyc and b/settings/__pycache__/base.cpython-310.pyc differ diff --git a/settings/base.py b/settings/base.py index 329c199..63a3788 100644 --- a/settings/base.py +++ b/settings/base.py @@ -58,6 +58,7 @@ INSTALLED_APPS = [ 'inventory', 'warehouse', 'hr', + 'hq', 'product_directory', 'goods_reception', 'pricing', diff --git a/urls.py b/urls.py index 439e826..fedd945 100644 --- a/urls.py +++ b/urls.py @@ -9,4 +9,5 @@ urlpatterns = [ path('api/warehouse/', include('warehouse.urls')), path('api/hr/', include('hr.urls')), path('logistic/', include('logistic.urls')), + path('api/hq/', include('hq.urls')), ]