Added filter functionality and combined both base.html

master
kikimor 7 months ago
parent c1183c22ea
commit 2d0d33d525

@ -7,47 +7,45 @@
<list default="true" id="7410a44d-51b9-408b-85ad-4fa46776b372" name="Changes" comment="commit unversioned files ;)">
<change afterPath="$PROJECT_DIR$/accounts/migrations/0008_populate_permissions.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/accounts/migrations/0009_create_superuser.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/booking/templatetags/__init__.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/booking/templatetags/custom_filters.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/common/migrations/0004_populate_initial_data.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/common/utils/minio_utils.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/containers/views/common.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/docker-compose.minio.yml" afterDir="false" />
<change afterPath="$PROJECT_DIR$/docker-compose-deploy.yml" afterDir="false" />
<change afterPath="$PROJECT_DIR$/payments/migrations/0004_populate_tariffs.py" afterDir="false" />
<change afterPath="$PROJECT_DIR$/static/js/container-details.js" afterDir="false" />
<change afterPath="$PROJECT_DIR$/static/styles/details.css" afterDir="false" />
<change afterPath="$PROJECT_DIR$/templates/common/base.html" afterDir="false" />
<change afterPath="$PROJECT_DIR$/templates/common/container-details.html" afterDir="false" />
<change afterPath="$PROJECT_DIR$/templates/registration/change_password.html" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/DepoT/settings.py" beforeDir="false" afterPath="$PROJECT_DIR$/DepoT/settings.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/accounts/forms.py" beforeDir="false" afterPath="$PROJECT_DIR$/accounts/forms.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/accounts/urls.py" beforeDir="false" afterPath="$PROJECT_DIR$/accounts/urls.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/accounts/views.py" beforeDir="false" afterPath="$PROJECT_DIR$/accounts/views.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/booking/urls.py" beforeDir="false" afterPath="$PROJECT_DIR$/booking/urls.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/common/urls.py" beforeDir="false" afterPath="$PROJECT_DIR$/common/urls.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/common/utils/owncloud_utls.py" beforeDir="false" afterPath="$PROJECT_DIR$/common/utils/owncloud_utls.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/containers/forms.py" beforeDir="false" afterPath="$PROJECT_DIR$/containers/forms.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/containers/urls.py" beforeDir="false" afterPath="$PROJECT_DIR$/containers/urls.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/damages_api/urls.py" beforeDir="false" afterPath="$PROJECT_DIR$/damages_api/urls.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/damages_api/views.py" beforeDir="false" afterPath="$PROJECT_DIR$/damages_api/views.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/docker-compose.yml" beforeDir="false" afterPath="$PROJECT_DIR$/docker-compose.yml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/dockerfile" beforeDir="false" afterPath="$PROJECT_DIR$/dockerfile" afterDir="false" />
<change beforePath="$PROJECT_DIR$/preinfo/urls.py" beforeDir="false" afterPath="$PROJECT_DIR$/preinfo/urls.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/preinfo/views/client_views.py" beforeDir="false" afterPath="$PROJECT_DIR$/preinfo/views/client_views.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/requirements.txt" beforeDir="false" afterPath="$PROJECT_DIR$/requirements.txt" afterDir="false" />
<change beforePath="$PROJECT_DIR$/booking/views/employee_views.py" beforeDir="false" afterPath="$PROJECT_DIR$/booking/views/employee_views.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/common/models.py" beforeDir="false" afterPath="$PROJECT_DIR$/common/models.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/common/views/employee_views.py" beforeDir="false" afterPath="$PROJECT_DIR$/common/views/employee_views.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/containers/views/employee_views.py" beforeDir="false" afterPath="$PROJECT_DIR$/containers/views/employee_views.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/preinfo/views/employee_views.py" beforeDir="false" afterPath="$PROJECT_DIR$/preinfo/views/employee_views.py" afterDir="false" />
<change beforePath="$PROJECT_DIR$/static/js/crud-list.js" beforeDir="false" afterPath="$PROJECT_DIR$/static/js/crud-list.js" afterDir="false" />
<change beforePath="$PROJECT_DIR$/static/styles/forms.css" beforeDir="false" afterPath="$PROJECT_DIR$/static/styles/forms.css" afterDir="false" />
<change beforePath="$PROJECT_DIR$/templates/client-base.html" beforeDir="false" afterPath="$PROJECT_DIR$/templates/client-base.html" afterDir="false" />
<change beforePath="$PROJECT_DIR$/templates/client/booking-list.html" beforeDir="false" afterPath="$PROJECT_DIR$/templates/client/booking-list.html" afterDir="false" />
<change beforePath="$PROJECT_DIR$/templates/client/line-list.html" beforeDir="false" afterPath="$PROJECT_DIR$/templates/client/line-list.html" afterDir="false" />
<change beforePath="$PROJECT_DIR$/templates/client/preinfo-list.html" beforeDir="false" afterPath="$PROJECT_DIR$/templates/client/preinfo-list.html" afterDir="false" />
<change beforePath="$PROJECT_DIR$/templates/employee-base.html" beforeDir="false" afterPath="$PROJECT_DIR$/templates/employee-base.html" afterDir="false" />
<change beforePath="$PROJECT_DIR$/templates/employee-sidebar.html" beforeDir="false" afterPath="$PROJECT_DIR$/templates/employee-sidebar.html" afterDir="false" />
<change beforePath="$PROJECT_DIR$/templates/client-booking-content.html" beforeDir="false" afterPath="$PROJECT_DIR$/templates/client-booking-content.html" afterDir="false" />
<change beforePath="$PROJECT_DIR$/templates/client-dashboard-content.html" beforeDir="false" afterPath="$PROJECT_DIR$/templates/client-dashboard-content.html" afterDir="false" />
<change beforePath="$PROJECT_DIR$/templates/client-orders-content.html" beforeDir="false" afterPath="$PROJECT_DIR$/templates/client-orders-content.html" afterDir="false" />
<change beforePath="$PROJECT_DIR$/templates/client-preinfo-content.html" beforeDir="false" afterPath="$PROJECT_DIR$/templates/client-preinfo-content.html" afterDir="false" />
<change beforePath="$PROJECT_DIR$/templates/client/booking-create.html" beforeDir="false" afterPath="$PROJECT_DIR$/templates/client/booking-create.html" afterDir="false" />
<change beforePath="$PROJECT_DIR$/templates/client/booking-edit.html" beforeDir="false" afterPath="$PROJECT_DIR$/templates/client/booking-edit.html" afterDir="false" />
<change beforePath="$PROJECT_DIR$/templates/client/line-create.html" beforeDir="false" afterPath="$PROJECT_DIR$/templates/client/line-create.html" afterDir="false" />
<change beforePath="$PROJECT_DIR$/templates/client/line-update.html" beforeDir="false" afterPath="$PROJECT_DIR$/templates/client/line-update.html" afterDir="false" />
<change beforePath="$PROJECT_DIR$/templates/client/preinfo-create.html" beforeDir="false" afterPath="$PROJECT_DIR$/templates/client/preinfo-create.html" afterDir="false" />
<change beforePath="$PROJECT_DIR$/templates/client/preinfo-edit.html" beforeDir="false" afterPath="$PROJECT_DIR$/templates/client/preinfo-edit.html" afterDir="false" />
<change beforePath="$PROJECT_DIR$/templates/common/base.html" beforeDir="false" afterPath="$PROJECT_DIR$/templates/common/base.html" afterDir="false" />
<change beforePath="$PROJECT_DIR$/templates/employee-dashboard-content.html" beforeDir="false" afterPath="$PROJECT_DIR$/templates/employee-dashboard-content.html" afterDir="false" />
<change beforePath="$PROJECT_DIR$/templates/employee/booking-list.html" beforeDir="false" afterPath="$PROJECT_DIR$/templates/employee/booking-list.html" afterDir="false" />
<change beforePath="$PROJECT_DIR$/templates/employee/company-create.html" beforeDir="false" afterPath="$PROJECT_DIR$/templates/employee/company-create.html" afterDir="false" />
<change beforePath="$PROJECT_DIR$/templates/employee/company-list.html" beforeDir="false" afterPath="$PROJECT_DIR$/templates/employee/company-list.html" afterDir="false" />
<change beforePath="$PROJECT_DIR$/templates/employee/company-update.html" beforeDir="false" afterPath="$PROJECT_DIR$/templates/employee/company-update.html" afterDir="false" />
<change beforePath="$PROJECT_DIR$/templates/employee/containers-list.html" beforeDir="false" afterPath="$PROJECT_DIR$/templates/employee/containers-list.html" afterDir="false" />
<change beforePath="$PROJECT_DIR$/templates/employee/line-create.html" beforeDir="false" afterPath="$PROJECT_DIR$/templates/employee/line-create.html" afterDir="false" />
<change beforePath="$PROJECT_DIR$/templates/employee/line-list.html" beforeDir="false" afterPath="$PROJECT_DIR$/templates/employee/line-list.html" afterDir="false" />
<change beforePath="$PROJECT_DIR$/templates/employee/line-update.html" beforeDir="false" afterPath="$PROJECT_DIR$/templates/employee/line-update.html" afterDir="false" />
<change beforePath="$PROJECT_DIR$/templates/employee/payment-create.html" beforeDir="false" afterPath="$PROJECT_DIR$/templates/employee/payment-create.html" afterDir="false" />
<change beforePath="$PROJECT_DIR$/templates/employee/preinfo-list.html" beforeDir="false" afterPath="$PROJECT_DIR$/templates/employee/preinfo-list.html" afterDir="false" />
<change beforePath="$PROJECT_DIR$/templates/landing-page.html" beforeDir="false" afterPath="$PROJECT_DIR$/templates/landing-page.html" afterDir="false" />
<change beforePath="$PROJECT_DIR$/templates/list-crud.html" beforeDir="false" afterPath="$PROJECT_DIR$/templates/list-crud.html" afterDir="false" />
<change beforePath="$PROJECT_DIR$/templates/registration/register.html" beforeDir="false" afterPath="$PROJECT_DIR$/templates/registration/register.html" afterDir="false" />
<change beforePath="$PROJECT_DIR$/templates/registration/user-list.html" beforeDir="false" afterPath="$PROJECT_DIR$/templates/registration/user-list.html" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
@ -62,10 +60,10 @@
<component name="FileTemplateManagerImpl">
<option name="RECENT_TEMPLATES">
<list>
<option value="HTML File" />
<option value="CSS File" />
<option value="JavaScript File" />
<option value="Python Script" />
<option value="HTML File" />
</list>
</option>
</component>
@ -172,7 +170,7 @@
<workItem from="1753175068058" duration="4635000" />
<workItem from="1753179863298" duration="8357000" />
<workItem from="1753197869497" duration="98156000" />
<workItem from="1753637487803" duration="30673000" />
<workItem from="1753637487803" duration="42690000" />
</task>
<task id="LOCAL-00001" summary="Add IntelliJ IDEA project configuration files&#10;&#10;This commit adds IntelliJ IDEA-specific configuration files for the project, including module setup, version control integration, inspection profiles, and workspace settings. These files facilitate development environment configuration for contributors using IntelliJ IDEA.">
<option name="closed" value="true" />
@ -312,6 +310,10 @@
<line>4</line>
<option name="timeStamp" value="95" />
</line-breakpoint>
<line-breakpoint enabled="true" type="django-line">
<url>file://$PROJECT_DIR$/templates/client-dashboard-content.html</url>
<option name="timeStamp" value="103" />
</line-breakpoint>
</breakpoints>
<default-breakpoints>
<breakpoint type="python-exception">

@ -1,5 +1,6 @@
from django.contrib.auth import get_user_model
from django.contrib.auth.forms import AuthenticationForm
from django.contrib.auth.views import PasswordChangeView
from django.core.exceptions import ValidationError
from django.forms import CharField
from django.forms.models import ModelForm
@ -18,7 +19,6 @@ class RegisterForm(ModelForm):
field_order = ['username', 'email', 'password1', 'password2', 'phone_number', 'company', 'line', 'user_type', 'company_permissions', 'employee_permissions', 'is_active']
class Meta:
model = get_user_model()
fields = ['username', 'email', 'password1', 'password2', 'phone_number', 'company', 'line', 'user_type', 'company_permissions', 'employee_permissions', 'is_active']
@ -52,3 +52,45 @@ class RegisterForm(ModelForm):
user.save()
return user
class UserEditForm(ModelForm):
password1 = CharField(required=False, label='Password', widget=PasswordInput)
password2 = CharField(required=False, label='Confirm Password', widget=PasswordInput)
field_order = ['username', 'email', 'password1', 'password2', 'phone_number', 'company', 'line', 'user_type', 'company_permissions', 'employee_permissions', 'is_active']
class Meta:
model = get_user_model()
fields = ['username', 'email', 'password1', 'password2', 'phone_number', 'company', 'line', 'user_type', 'company_permissions', 'employee_permissions', 'is_active']
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['user_type'].widget.attrs['readonly'] = True
self.fields['company_permissions'].widget.attrs['disabled'] = True
self.fields['employee_permissions'].widget.attrs['disabled'] = True
if self.data.get('user_type') in ( 'EM', 'BS'):
self.fields['company_permissions'].required = False
if self.data.get('user_type') in ('CL', 'CA', 'BS'):
self.fields['company_permissions'].required = False
def clean(self):
cleaned_data = super().clean()
password1 = cleaned_data.get('password1')
password2 = cleaned_data.get('password2')
if password1 and password2 and password1 != password2:
raise ValidationError("Passwords don't match")
return cleaned_data
def save(self, commit=True):
user = super().save(commit=False)
user.set_password(self.cleaned_data['password1'])
if commit:
user.save()
return user
class UserChangePasswordForm(PasswordChangeView):
old_password = CharField(widget=PasswordInput())
new_password = CharField(widget=PasswordInput())
confirm_password = CharField(widget=PasswordInput())

@ -0,0 +1,44 @@
from django.db import migrations
def create_permissions(apps, schema_editor):
EmployeePermission = apps.get_model('accounts', 'EmployeePermission')
ClientPermission = apps.get_model('accounts', 'ClientPermission')
employee_permissions = [
(1, 'can_manage_containers', 'Can manage containers'),
(2, 'can_view_reports', 'Can view reports'),
(3, 'can_handle_operations', 'Can handle operations'),
]
for _id, codename, name in employee_permissions:
EmployeePermission.objects.create(id=_id, codename=codename, name=name)
client_permissions = [
(1, 'can_view_booking', 'Can view booking'),
(2, 'can_manage_booking', 'Can book container'),
(3, 'can_view_preinfo', 'Can view preinfo'),
(4, 'can_manage_preinfo', 'Can manage preinfo'),
(5, 'can_view_payment', 'Can view payment'),
(6, 'can_manage_payment', 'Can manage payment'),
(7, 'can_manage_company_users', 'Can manage company users'),
]
for _id, codename, name in client_permissions:
ClientPermission.objects.create(id=_id, codename=codename, name=name)
def reverse_permissions(apps, schema_editor):
EmployeePermission = apps.get_model('accounts', 'EmployeePermission')
ClientPermission = apps.get_model('accounts', 'ClientPermission')
EmployeePermission.objects.all().delete()
ClientPermission.objects.all().delete()
class Migration(migrations.Migration):
dependencies = [
('accounts', '0007_auto_20250725_1920'), # Adjust this to your last migration
]
operations = [
migrations.RunPython(create_permissions, reverse_permissions),
]

@ -0,0 +1,29 @@
from django.db import migrations
from django.conf import settings
from django.contrib.auth.hashers import make_password
def create_superuser(apps, schema_editor):
User = apps.get_model('accounts', 'DepotUser')
if not User.objects.filter(email=settings.ADMIN_USER_EMAIL).exists():
user = User.objects.create(
email=settings.ADMIN_USER_EMAIL,
username=settings.ADMIN_USER_NAME,
is_staff=True,
is_superuser=True,
is_active=True,
user_type='AD',
password=make_password(settings.ADMIN_USER_PASSWORD)
)
def reverse_superuser(apps, schema_editor):
User = apps.get_model('accounts', 'DepotUser')
User.objects.filter(email=settings.ADMIN_USER_EMAIL).delete()
class Migration(migrations.Migration):
dependencies = [
('accounts', '0008_populate_permissions'),
]
operations = [
migrations.RunPython(create_superuser, reverse_superuser),
]

@ -3,11 +3,12 @@ from django.contrib.auth import views as auth_views
from accounts import views
urlpatterns = [
path('login/', views.DepotLoginView.as_view(), name='login'),
path('relogin/', auth_views.logout_then_login, name='relogin'),
path('user/', include([
path('', include([
path('', views.UserListView.as_view(), name='user_list'),
path('register/', views.RegisterView.as_view(), name='user_register'),
path('login/', views.DepotLoginView.as_view(), name='login'),
path('relogin/', auth_views.logout_then_login, name='relogin'),
path('change-password/', views.UserChangePasswordView.as_view(), name='change_password'),
path('<int:pk>/update/', views.UserUpdateView.as_view(), name='user_update'),
path('<int:pk>/active/', views.UserActiveView.as_view(), name='user_active'),
])),

@ -8,7 +8,7 @@ from django.views import View
from django.views.generic import TemplateView, FormView, ListView, UpdateView
from rest_framework.generics import get_object_or_404
from accounts.forms import LoginForm, RegisterForm
from accounts.forms import LoginForm, RegisterForm, UserChangePasswordForm
from accounts.models import DepotUser
from django.contrib.auth.decorators import login_required, user_passes_test
@ -106,6 +106,11 @@ class UserListView(ListView):
queryset = super().get_queryset()
user = self.request.user
data_filter = self.request.GET.get('filter')
if data_filter != 'all':
queryset = queryset.filter(is_active=True)
# Filter users based on permissions
if user.is_superuser:
return queryset.all()
@ -185,3 +190,9 @@ class UserActiveView(LoginRequiredMixin, View):
target_user.is_active = not target_user.is_active
target_user.save()
return JsonResponse({'success': True, 'is_active': target_user.is_active})
class UserChangePasswordView(LoginRequiredMixin, View):
template_name = 'registration/change_password.html'
form_class = UserChangePasswordForm
success_url = reverse_lazy('home')

@ -14,3 +14,14 @@ class BookingListView(ListView):
context = super().get_context_data(**kwargs)
context['base_template'] = self.base_template
return context
def get_queryset(self):
queryset = super().get_queryset()
data_filter = self.request.GET.get('filter')
if data_filter != 'all':
queryset = queryset.filter(status='active')
queryset = queryset.order_by('-created_on')
return queryset

@ -0,0 +1,91 @@
from django.db import migrations
def create_initial_data(apps, schema_editor):
ContainerKindModel = apps.get_model('common', 'ContainerKindModel')
ContainerTypeModel = apps.get_model('common', 'ContainerTypeModel')
CompanyModel = apps.get_model('common', 'CompanyModel')
LinesModel = apps.get_model('common', 'LinesModel')
# Container Kinds
container_kinds = [
(1, 'Standart', '', ''),
(2, 'Reefer', '', ''),
(3, 'Opentop', '', ''),
(4, 'FlatRack', '', ''),
(5, 'Tank', '', ''),
(6, 'Platform', '', ''),
]
for _id, name, *rest in container_kinds:
ContainerKindModel.objects.create(id=_id, name=name)
# Container Types
container_types = [
(1, '20GP', 20, False, 1, False),
(2, '40GP', 40, False, 1, False),
(3, '40HC', 40, True, 1, False),
(4, '20RF', 20, False, 2, False),
(5, '40RF', 40, False, 2, False),
(6, '20OT', 20, False, 3, False),
(7, '40OT', 40, False, 3, False),
(8, '20FR', 20, False, 4, False),
(9, '20FRPL', 20, False, 6, False),
(10, '45HC', 45, True, 1, False),
(11, '40FRPL', 40, False, 6, False),
(12, '40HR', 40, True, 2, False),
]
for _id, name, length, height, container_type_id, deleted in container_types:
ContainerTypeModel.objects.create(
id=_id,
name=name,
length=length,
height=height,
container_type_id=container_type_id,
deleted=deleted
)
# Companies and Lines
companies = [
(1, 'GMS', 'GMS', 'Global Maritime Servises'),
(2, 'TO', 'TO', 'Терминален оператор'),
]
for _id, name, short_name, description in companies:
CompanyModel.objects.create(
id=_id,
name=name,
short_name=short_name,
description=description
)
lines = [
(1, 'GMS', 'GMS', 'GMS line', 1),
(2, 'HPG', 'HPG', 'Hapag Lloyds line', 1),
(3, 'TO', 'TO', 'Терминален оператор line', 2),
]
for _id, name, short_name, description, company_id in lines:
LinesModel.objects.create(
id=_id,
name=name,
short_name=short_name,
description=description,
company_id=company_id
)
def reverse_initial_data(apps, schema_editor):
ContainerKindModel = apps.get_model('common', 'ContainerKindModel')
ContainerTypeModel = apps.get_model('common', 'ContainerTypeModel')
CompanyModel = apps.get_model('common', 'CompanyModel')
LinesModel = apps.get_model('common', 'LinesModel')
ContainerKindModel.objects.all().delete()
ContainerTypeModel.objects.all().delete()
CompanyModel.objects.all().delete()
LinesModel.objects.all().delete()
class Migration(migrations.Migration):
dependencies = [
('common', '0003_auto_20250725_1920'), # Adjust this to your last migration
]
operations = [
migrations.RunPython(create_initial_data, reverse_initial_data),
]

@ -5,7 +5,7 @@ class NomenclatureBaseModel(models.Model):
name = models.CharField(max_length=100, unique=True)
short_name = models.CharField(max_length=5, null=True, blank=True)
description = models.TextField(blank=True, null=True)
active = models.BooleanField(default=True)
class Meta:
abstract = True
ordering = ['name']

@ -43,7 +43,16 @@ class EmployeeCompanyListView(LoginRequiredMixin, UserPassesTestMixin, ListView)
context['base_template'] = self.base_template
return context
def get_queryset(self):
queryset = super().get_queryset()
data_filter = self.request.GET.get('filter')
if data_filter != 'all':
queryset = queryset.filter(active=True)
queryset = queryset.order_by('name')
return queryset
class EmployeeCompanyCreateView(LoginRequiredMixin, UserPassesTestMixin, CreateView):
model = CompanyModel
@ -90,7 +99,16 @@ class EmployeeLineListView(LoginRequiredMixin, UserPassesTestMixin, ListView):
context['base_template'] = self.base_template
return context
def get_queryset(self):
queryset = super().get_queryset()
data_filter = self.request.GET.get('filter')
if data_filter != 'all':
queryset = queryset.filter(active=True)
queryset = queryset.order_by('name')
return queryset
class EmployeeLineCreateView(LoginRequiredMixin, UserPassesTestMixin, CreateView):
model = LinesModel

@ -20,7 +20,14 @@ class ContainersListView(ListView):
return context
def get_queryset(self):
return Container.objects.filter(expedited=False).order_by('-received_on')
queryset = super().get_queryset()
data_filter = self.request.GET.get('filter')
if data_filter != 'all':
queryset = queryset.filter(expedited=False)
queryset = queryset.order_by('-received_on')
return queryset
class ReportContainersUnpaidListView(ListView):

@ -0,0 +1,84 @@
version: '3.8'
services:
database:
image: postgres
environment:
- POSTGRES_DB=depot # Matches DB_NAME in production.env
- POSTGRES_USER=postgres # Matches DB_USER in production.env
- POSTGRES_PASSWORD=admin # Matches DB_PASSWORD in production.env
ports:
- "5432:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres -d depot"] # Check specific database
interval: 5s
timeout: 5s
retries: 5
networks:
- app-network
web:
build: .
ports:
- "8000:8000"
env_file:
- production.env
depends_on:
database:
condition: service_healthy
networks:
- app-network
command: >
bash -c "python manage.py migrate &&
python manage.py runserver 0.0.0.0:8000"
minio:
image: minio/minio:latest
ports:
- "9000:9000" # API Port
- "9001:9001" # Console Port
environment:
MINIO_ROOT_USER: kikimor # Change this
MINIO_ROOT_PASSWORD: shushunka1
MINIO_SERVER_URL: http://localhost:9000
MINIO_ADDRESS: "0.0.0.0:9000"
MINIO_BROWSER_REDIRECT_URL: "http://localhost:9001" # Console URL
volumes:
- minio_data:/data
command: server --console-address ":9001" /data
healthcheck:
test: ["CMD", "mc", "ready", "local"]
interval: 30s
timeout: 20s
retries: 3
networks:
- app-network
# Optional: Create buckets and users on startup
createbuckets:
image: minio/mc
depends_on:
- minio
entrypoint: >
/bin/sh -c "
sleep 10;
mc alias set myminio http://minio:9000 kikimor shushunka1;
mc mb myminio/damages;
mc anonymous set download myminio/damages;
mc policy set public myminio/damages;
echo '{\"Version\":\"2012-10-17\",\"Statement\":[{\"Effect\":\"Allow\",\"Principal\":{\"AWS\":[\"*\"]},\"Action\":[\"s3:GetObject\"],\"Resource\":[\"arn:aws:s3:::damages/*\"]}]}' > /tmp/policy.json;
mc admin policy add myminio getonly /tmp/policy.json;
mc admin policy set myminio getonly user=kikimor;
exit 0;
"
networks:
- app-network
volumes:
postgres_data:
minio_data:
networks:
app-network:
driver: bridge

@ -0,0 +1,53 @@
from django.db import migrations
from decimal import Decimal
def create_tariffs(apps, schema_editor):
ContainerTariffPeriod = apps.get_model('payments', 'ContainerTariffPeriod')
AdditionalFees = apps.get_model('payments', 'AdditionalFees')
tariffs_20 = [
('20', 1, 3, Decimal('5.00')),
('20', 4, 7, Decimal('10.00')),
('20', 8, 15, Decimal('15.00')),
('20', 16, None, Decimal('20.00')),
]
tariffs_40 = [
('40', 1, 3, Decimal('10.00')),
('40', 4, 7, Decimal('15.00')),
('40', 8, 15, Decimal('20.00')),
('40', 16, None, Decimal('25.00')),
]
for container_size, from_days, to_days, daily_rate in tariffs_20 + tariffs_40:
ContainerTariffPeriod.objects.create(
container_size=container_size,
from_days=from_days,
to_days=to_days,
daily_rate=daily_rate
)
AdditionalFees.objects.create(
reefer_daily_supplement=Decimal('3.00'),
sweeping_fee=Decimal('35.00'),
fumigation_fee=Decimal('75.00')
)
def reverse_tariffs(apps, schema_editor):
ContainerTariffPeriod = apps.get_model('payments', 'ContainerTariffPeriod')
AdditionalFees = apps.get_model('payments', 'AdditionalFees')
ContainerTariffPeriod.objects.all().delete()
AdditionalFees.objects.all().delete()
class Migration(migrations.Migration):
dependencies = [
('payments', '0003_auto_20250725_1920'), # Adjust this to your last migration
]
operations = [
migrations.RunPython(create_tariffs, reverse_tariffs),
]

@ -18,3 +18,16 @@ class EmployeePreinfoView(LoginRequiredMixin, UserPassesTestMixin, ListView):
context = super().get_context_data(**kwargs)
context['base_template'] = self.base_template
return context
def get_queryset(self):
queryset = super().get_queryset()
data_filter = self.request.GET.get('filter')
if data_filter == 'all':
queryset = queryset.filter(deleted=False)
else:
queryset = queryset.filter(received=False,deleted=False)
queryset = queryset.order_by('-created_on')
return queryset

@ -81,7 +81,7 @@ document.addEventListener('DOMContentLoaded', function() {
deleteModal.style.display = 'none';
});
confirmDelete.addEventListener('click', function() {
confirmDelete.addEventListener('click', function() {
if (selectedId) {
const deleteUrl = deleteBtn.dataset.url.replace('0', selectedId);
@ -104,7 +104,7 @@ confirmDelete.addEventListener('click', function() {
});
}
deleteModal.style.display = 'none';
});
});
window.addEventListener('click', function(event) {
if (event.target === deleteModal) {
@ -126,4 +126,45 @@ confirmDelete.addEventListener('click', function() {
}
return cookieValue;
}
const filterInput = document.getElementById('filterInput');
const activeBtn = document.getElementById('activeBtn');
const allBtn = document.getElementById('allBtn');
const filterForm = document.getElementById('filterForm');
if (activeBtn && allBtn && filterInput && filterForm) {
// Read filter from cookie if present
const filterCookie = getCookie('list_filter');
if (filterCookie && !filterInput.value) {
filterInput.value = filterCookie;
}
function updateButtons() {
if (filterInput.value === 'all') {
allBtn.classList.add('active');
activeBtn.classList.remove('active');
} else {
activeBtn.classList.add('active');
allBtn.classList.remove('active');
}
}
updateButtons();
activeBtn.addEventListener('click', function() {
filterInput.value = 'active';
document.cookie = 'list_filter=active;path=/';
updateButtons();
filterForm.submit();
});
allBtn.addEventListener('click', function() {
filterInput.value = 'all';
document.cookie = 'list_filter=all;path=/';
updateButtons();
filterForm.submit();
});
}
});

@ -101,6 +101,13 @@ button.btn-secondary:hover{
background-color: #EDDECB;
}
.btn.active {
background-color: #0d6efd;
color: #fff;
border-color: #0d6efd;
}
/* Error messages */
.errorlist {
color: #dc3545;
@ -341,3 +348,8 @@ button.btn-secondary:hover{
border: none !important;
}
}
#filterForm {
border: none !important;
margin: 0 !important;
padding: 0 !important;
}

@ -1,4 +1,4 @@
{% extends 'client-base.html' %}
{% extends 'common/base.html' %}
{% block content %}
<div id="preinfoContent" class="tab-content active">

@ -1,4 +1,4 @@
{% extends 'client-base.html' %}
{% extends 'common/base.html' %}
{% block content %}
{# <div id="dashboardContent" class="tab-content active">#}

@ -1,4 +1,4 @@
{% extends 'client-base.html' %}
{% extends 'common/base.html' %}
{% block content %}
<div id="ordersContent" class="tab-content">
<div class="bg-white rounded-lg shadow">

@ -1,4 +1,4 @@
{% extends 'client-base.html' %}
{% extends 'common/base.html' %}
{% block content %}
<div id="preinfoContent" class="tab-content active">

@ -1,4 +1,4 @@
{% extends 'client-base.html' %}
{% extends 'common/base.html' %}
{% load static %}
{% block content %}

@ -1,4 +1,4 @@
{% extends 'client-base.html' %}
{% extends 'common/base.html' %}
{% load static %}
{% block content %}

@ -1,4 +1,4 @@
{% extends 'client-base.html' %}
{% extends 'common/base.html' %}
{% load static %}
{% block content %}

@ -1,4 +1,4 @@
{% extends 'client-base.html' %}
{% extends 'common/base.html' %}
{% load static %}
{% block content %}

@ -1,4 +1,4 @@
{% extends 'client-base.html' %}
{% extends 'common/base.html' %}
{% load static %}
{% block content %}

@ -1,4 +1,4 @@
{% extends 'client-base.html' %}
{% extends 'common/base.html' %}
{% load static %}
{% block content %}

@ -17,6 +17,11 @@
<body>
<aside class="sidebar">
{% block aside %}
{% if user.user_type == 'AD' or user.user_type == 'EM' %}
{% include 'employee-sidebar.html' %}
{% elif user.user_type == 'CL' or user.user_type == 'CA' %}
{% include 'client-sidebar.html' %}
{% endif %}
{% endblock aside %}
</aside>

@ -1,4 +1,4 @@
{% extends 'employee-base.html' %}
{% extends 'common/base.html' %}
{% block content %}
<div class="dashboard-wrapper">

@ -2,6 +2,14 @@
{% load custom_filters %}
{% load static %}
{% block filter %}
<form id="filterForm" method="get" style="display: inline;">
<input type="hidden" name="filter" id="filterInput" value="{{ request.GET.filter|default:'active' }}">
<button type="button" class="btn btn-primary" id="activeBtn">Active</button>
<button type="button" class="btn btn-primary" id="allBtn">All</button>
</form>
{% endblock filter %}
{% block table_header %}
<th style="display: none;">Select</th>
<th>Line</th>

@ -1,4 +1,4 @@
{% extends 'employee-base.html' %}
{% extends 'common/base.html' %}
{% load static %}
{% block content %}

@ -1,6 +1,14 @@
{% extends 'list-crud.html' %}
{% load static %}
{% block filter %}
<form id="filterForm" method="get" style="display: inline;">
<input type="hidden" name="filter" id="filterInput" value="{{ request.GET.filter|default:'active' }}">
<button type="button" class="btn btn-primary" id="activeBtn">Active</button>
<button type="button" class="btn btn-primary" id="allBtn">All</button>
</form>
{% endblock filter %}
{% block table_header %}
<th style="display: none;">Select</th>
<th>Company name</th>

@ -1,4 +1,4 @@
{% extends 'employee-base.html' %}
{% extends 'common/base.html' %}
{% load static %}
{% block content %}

@ -1,6 +1,14 @@
{% extends 'list-crud.html' %}
{% load static %}
{% block filter %}
<form id="filterForm" method="get" style="display: inline;">
<input type="hidden" name="filter" id="filterInput" value="{{ request.GET.filter|default:'active' }}">
<button type="button" class="btn btn-primary" id="activeBtn">Active</button>
<button type="button" class="btn btn-primary" id="allBtn">All</button>
</form>
{% endblock filter %}
{% block table_header %}
<th>Container №</th>
<th>Container type</th>

@ -1,4 +1,4 @@
{% extends 'employee-base.html' %}
{% extends 'common/base.html' %}
{% load static %}
{% block content %}

@ -1,6 +1,14 @@
{% extends 'list-crud.html' %}
{% load static %}
{% block filter %}
<form id="filterForm" method="get" style="display: inline;">
<input type="hidden" name="filter" id="filterInput" value="{{ request.GET.filter|default:'active' }}">
<button type="button" class="btn btn-primary" id="activeBtn">Active</button>
<button type="button" class="btn btn-primary" id="allBtn">All</button>
</form>
{% endblock filter %}
{% block table_header %}
<th style="display: none;">Select</th>
<th>Company</th>

@ -1,4 +1,4 @@
{% extends 'employee-base.html' %}
{% extends 'common/base.html' %}
{% load static %}
{% block content %}

@ -1,4 +1,4 @@
{% extends "employee-base.html" %}
{% extends 'common/base.html' %}
{% block content %}
<form method="POST">

@ -1,6 +1,14 @@
{% extends 'list-crud.html' %}
{% load static %}
{% block filter %}
<form id="filterForm" method="get" style="display: inline;">
<input type="hidden" name="filter" id="filterInput" value="{{ request.GET.filter|default:'active' }}">
<button type="button" class="btn btn-primary" id="activeBtn">Active</button>
<button type="button" class="btn btn-primary" id="allBtn">All</button>
</form>
{% endblock filter %}
{% block table_header %}
<th style="display: none;">Select</th>
<th>Preinfo №</th>

@ -1,4 +1,4 @@
{% extends base_template %}
{% extends 'common/base.html' %}
{% load static %}
{% block content %}

@ -0,0 +1,10 @@
{% extends 'common/base.html' %}
{% block content %}
<h2>Change Password</h2>
<form method="post">
{% csrf_token %}
{{ form.as_p }}
<button type="submit">Change Password</button>
</form>
{% endblock %}

@ -1,4 +1,4 @@
{% extends 'employee-base.html' %}
{% extends 'common/base.html' %}
{% block content %}
<form method="post">

@ -1,6 +1,15 @@
{% extends 'list-crud.html' %}
{% load static %}
{% block filter %}
<form id="filterForm" method="get" style="display: inline;">
<input type="hidden" name="filter" id="filterInput" value="{{ request.GET.filter|default:'active' }}">
<button type="button" class="btn btn-primary" id="activeBtn">Active</button>
<button type="button" class="btn btn-primary" id="allBtn">All</button>
</form>
{% endblock filter %}
{% block table_header %}
<th>Username</th>
<th>User Type</th>

Loading…
Cancel
Save