settings split for development and production.py
This commit is contained in:
@@ -29,3 +29,5 @@ production.env
|
||||
|
||||
# Other
|
||||
gemini.cmd - Shortcut.lnk
|
||||
|
||||
images/
|
||||
@@ -36,7 +36,6 @@ MINIO_ENDPOINT="localhost:9000"
|
||||
MINIO_ACCESS_KEY="kikimor"
|
||||
MINIO_SECRET_KEY="shushunka1"
|
||||
MINIO_BUCKET_NAME="damages"
|
||||
#MINIO_STATIC_BUCKET_NAME=depot-static
|
||||
#AWS_S3_CUSTOM_DOMAIN='localhost:9000' # For browser acce
|
||||
#AWS_S3_URL_PROTOCOL='http'
|
||||
#MINIO_SERVER_URL="http://localhost:9000"
|
||||
AWS_S3_CUSTOM_DOMAIN='localhost:9000' # For browser acce
|
||||
AWS_S3_URL_PROTOCOL='http'
|
||||
MINIO_SERVER_URL="http://localhost:9000"
|
||||
Generated
+70
-24
@@ -5,19 +5,34 @@
|
||||
</component>
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="7410a44d-51b9-408b-85ad-4fa46776b372" name="Changes" comment="commit unversioned files ;)">
|
||||
<change afterPath="$PROJECT_DIR$/DepoT/settings/__init__.py" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/DepoT/settings/base.py" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/DepoT/settings/development.py" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/unused templates/settings.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/.dockerignore" beforeDir="false" afterPath="$PROJECT_DIR$/.dockerignore" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/.env" beforeDir="false" afterPath="$PROJECT_DIR$/.env" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/common/utils/utils.py" beforeDir="false" afterPath="$PROJECT_DIR$/common/utils/utils.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/common/views/client_views.py" beforeDir="false" afterPath="$PROJECT_DIR$/common/views/client_views.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/common.py" beforeDir="false" afterPath="$PROJECT_DIR$/containers/views/common.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/payments/views.py" beforeDir="false" afterPath="$PROJECT_DIR$/payments/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$/templates/client-dashboard-content.html" beforeDir="false" afterPath="$PROJECT_DIR$/templates/client-dashboard-content.html" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/templates/common/container-details.html" beforeDir="false" afterPath="$PROJECT_DIR$/templates/common/container-details.html" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/templates/common/payment-list.html" beforeDir="false" afterPath="$PROJECT_DIR$/templates/common/payment-list.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-sidebar.html" beforeDir="false" afterPath="$PROJECT_DIR$/templates/employee-sidebar.html" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/web_depot.tar" beforeDir="false" afterPath="$PROJECT_DIR$/web_depot.tar" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/DepoT/settings.py" beforeDir="false" afterPath="$PROJECT_DIR$/DepoT/settings/production.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/booking/models.py" beforeDir="false" afterPath="$PROJECT_DIR$/booking/models.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/booking/tests.py" beforeDir="false" afterPath="$PROJECT_DIR$/booking/tests.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/booking/views/client_views.py" beforeDir="false" afterPath="$PROJECT_DIR$/booking/views/client_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$/containers/tests.py" beforeDir="false" afterPath="$PROJECT_DIR$/containers/tests.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/createbuckets_depot.tar" beforeDir="false" afterPath="$PROJECT_DIR$/images/createbuckets_depot.tar" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/damages_api/tests.py" beforeDir="false" afterPath="$PROJECT_DIR$/damages_api/tests.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/depot-web.tar" beforeDir="false" afterPath="$PROJECT_DIR$/images/depot-web.tar" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/depot_image.tar" beforeDir="false" afterPath="$PROJECT_DIR$/images/depot_image.tar" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/docker-compose-deploy.yml" beforeDir="false" afterPath="$PROJECT_DIR$/docker-compose-deploy.yml" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/dockerfile" beforeDir="false" afterPath="$PROJECT_DIR$/dockerfile" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/manage.py" beforeDir="false" afterPath="$PROJECT_DIR$/manage.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/minio.tar" beforeDir="false" afterPath="$PROJECT_DIR$/images/minio.tar" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/payments/services.py" beforeDir="false" afterPath="$PROJECT_DIR$/payments/services.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/postgres.tar" beforeDir="false" afterPath="$PROJECT_DIR$/images/postgres.tar" 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/common/allowed-vehicles.html" beforeDir="false" afterPath="$PROJECT_DIR$/templates/common/allowed-vehicles.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/unpaid-list.html" beforeDir="false" afterPath="$PROJECT_DIR$/templates/employee/unpaid-list.html" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/web_depot.tar" beforeDir="false" afterPath="$PROJECT_DIR$/images/web_depot.tar" afterDir="false" />
|
||||
</list>
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
@@ -51,8 +66,10 @@
|
||||
</component>
|
||||
<component name="PropertiesComponent"><![CDATA[{
|
||||
"keyToString": {
|
||||
"ASKED_MARK_IGNORED_FILES_AS_EXCLUDED": "true",
|
||||
"DefaultHtmlFileTemplate": "HTML File",
|
||||
"Django Server.DepoT.executor": "Debug",
|
||||
"Django tests.Test: booking.tests.BookingViewsTestCase.executor": "Debug",
|
||||
"RunOnceActivity.OpenDjangoStructureViewOnStart": "true",
|
||||
"RunOnceActivity.ShowReadmeOnStart": "true",
|
||||
"RunOnceActivity.git.unshallow": "true",
|
||||
@@ -60,7 +77,7 @@
|
||||
"django.template.preview.state": "SHOW_EDITOR",
|
||||
"git-widget-placeholder": "deploy__branch",
|
||||
"ignore.virus.scanning.warn.message": "true",
|
||||
"last_opened_file_path": "C:/dev_projects/python/Django/DepoT",
|
||||
"last_opened_file_path": "C:/dev_projects/python/Django/DepoT/DepoT/settings",
|
||||
"list.type.of.created.stylesheet": "CSS",
|
||||
"node.js.detected.package.eslint": "true",
|
||||
"node.js.detected.package.tslint": "true",
|
||||
@@ -77,21 +94,42 @@
|
||||
}]]></component>
|
||||
<component name="RecentsManager">
|
||||
<key name="CopyFile.RECENT_KEYS">
|
||||
<recent name="C:\dev_projects\python\Django\DepoT\DepoT\settings" />
|
||||
<recent name="C:\dev_projects\python\Django\DepoT" />
|
||||
<recent name="C:\dev_projects\python\Django\DepoT\minio_backend" />
|
||||
<recent name="C:\dev_projects\python\Django\DepoT\templates\employee" />
|
||||
<recent name="C:\dev_projects\python\Django\DepoT\templates\client" />
|
||||
<recent name="C:\dev_projects\python\Django\DepoT\templates" />
|
||||
</key>
|
||||
<key name="MoveFile.RECENT_KEYS">
|
||||
<recent name="C:\dev_projects\python\Django\DepoT\images" />
|
||||
<recent name="C:\dev_projects\python\Django\DepoT\unused templates" />
|
||||
<recent name="C:\dev_projects\python\Django\DepoT\DepoT" />
|
||||
<recent name="C:\dev_projects\python\Django\DepoT" />
|
||||
<recent name="C:\dev_projects\python\Django\DepoT\templates\employee" />
|
||||
<recent name="C:\dev_projects\python\Django\DepoT\templates\client" />
|
||||
<recent name="C:\dev_projects\python\Django\DepoT\common\views" />
|
||||
<recent name="C:\dev_projects\python\Django\DepoT\booking\views" />
|
||||
</key>
|
||||
</component>
|
||||
<component name="RunManager">
|
||||
<component name="RunManager" selected="Django Server.DepoT">
|
||||
<configuration name="Test: booking.tests.BookingViewsTestCase" type="DjangoTestsConfigurationType" temporary="true">
|
||||
<module name="DepoT" />
|
||||
<option name="ENV_FILES" value="" />
|
||||
<option name="INTERPRETER_OPTIONS" value="" />
|
||||
<option name="PARENT_ENVS" value="true" />
|
||||
<envs>
|
||||
<env name="PYTHONUNBUFFERED" value="1" />
|
||||
</envs>
|
||||
<option name="SDK_HOME" value="" />
|
||||
<option name="WORKING_DIRECTORY" value="" />
|
||||
<option name="IS_MODULE_SDK" value="true" />
|
||||
<option name="ADD_CONTENT_ROOTS" value="true" />
|
||||
<option name="ADD_SOURCE_ROOTS" value="true" />
|
||||
<EXTENSION ID="PythonCoverageRunConfigurationExtension" runner="coverage.py" />
|
||||
<option name="TARGET" value="booking.tests.BookingViewsTestCase" />
|
||||
<option name="SETTINGS_FILE" value="" />
|
||||
<option name="CUSTOM_SETTINGS" value="false" />
|
||||
<option name="USE_OPTIONS" value="false" />
|
||||
<option name="OPTIONS" value="" />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
<configuration name="DepoT" type="Python.DjangoServer" factoryName="Django server">
|
||||
<module name="DepoT" />
|
||||
<option name="ENV_FILES" value="" />
|
||||
@@ -99,9 +137,10 @@
|
||||
<option name="PARENT_ENVS" value="true" />
|
||||
<envs>
|
||||
<env name="PYTHONUNBUFFERED" value="1" />
|
||||
<env name="DJANGO_SETTINGS_MODULE" value="DepoT.settings" />
|
||||
<env name="DJANGO_SETTINGS_MODULE" value="DepoT.settings.development" />
|
||||
</envs>
|
||||
<option name="SDK_HOME" value="" />
|
||||
<option name="SDK_NAME" value="Python 3.13 (DepoT)" />
|
||||
<option name="WORKING_DIRECTORY" value="" />
|
||||
<option name="IS_MODULE_SDK" value="false" />
|
||||
<option name="ADD_CONTENT_ROOTS" value="true" />
|
||||
@@ -117,6 +156,15 @@
|
||||
<option name="customRunCommand" value="" />
|
||||
<method v="2" />
|
||||
</configuration>
|
||||
<list>
|
||||
<item itemvalue="Django Server.DepoT" />
|
||||
<item itemvalue="Django tests.Test: booking.tests.BookingViewsTestCase" />
|
||||
</list>
|
||||
<recent_temporary>
|
||||
<list>
|
||||
<item itemvalue="Django tests.Test: booking.tests.BookingViewsTestCase" />
|
||||
</list>
|
||||
</recent_temporary>
|
||||
</component>
|
||||
<component name="SharedIndexes">
|
||||
<attachedChunks>
|
||||
@@ -263,11 +311,6 @@
|
||||
<line>7</line>
|
||||
<option name="timeStamp" value="55" />
|
||||
</line-breakpoint>
|
||||
<line-breakpoint enabled="true" suspend="THREAD" type="python-line">
|
||||
<url>file://$PROJECT_DIR$/DepoT/settings.py</url>
|
||||
<line>12</line>
|
||||
<option name="timeStamp" value="100" />
|
||||
</line-breakpoint>
|
||||
<line-breakpoint enabled="true" type="javascript">
|
||||
<url>file://$PROJECT_DIR$/static/js/container_validation.js</url>
|
||||
<line>4</line>
|
||||
@@ -283,4 +326,7 @@
|
||||
</default-breakpoints>
|
||||
</breakpoint-manager>
|
||||
</component>
|
||||
<component name="com.intellij.coverage.CoverageDataManagerImpl">
|
||||
<SUITE FILE_PATH="coverage/DepoT$Test__booking_tests_BookingViewsTestCase.coverage" NAME="Test: booking.tests.BookingViewsTestCase Coverage Results" MODIFIED="1754303647560" SOURCE_PROVIDER="com.intellij.coverage.DefaultCoverageFileProvider" RUNNER="coverage.py" COVERAGE_BY_TEST_ENABLED="false" COVERAGE_TRACING_ENABLED="false" WORKING_DIRECTORY="" />
|
||||
</component>
|
||||
</project>
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,188 @@
|
||||
"""
|
||||
Django settings for DepoT project.
|
||||
|
||||
Generated by 'django-admin startproject' using Django 5.2.3.
|
||||
|
||||
For more information on this file, see
|
||||
https://docs.djangoproject.com/en/5.2/topics/settings/
|
||||
|
||||
For the full list of settings and their values, see
|
||||
https://docs.djangoproject.com/en/5.2/ref/settings/
|
||||
"""
|
||||
|
||||
from pathlib import Path
|
||||
import os
|
||||
import environ
|
||||
|
||||
BASE_DIR = Path(__file__).resolve().parent.parent.parent
|
||||
|
||||
env = environ.Env()
|
||||
environ.Env.read_env(os.path.join(BASE_DIR, '.env'))
|
||||
|
||||
SECRET_KEY = "django-insecure-g%187p84o9^rr)3#9@r3n^o2v1i%@6=+puxm7hlodg+kbsk%n#"
|
||||
|
||||
DEBUG = True
|
||||
|
||||
ALLOWED_HOSTS = ['192.168.24.43', '127.0.0.1', 'localhost', ]
|
||||
|
||||
|
||||
PROJECT_APPS = [
|
||||
'accounts',
|
||||
"booking",
|
||||
"common",
|
||||
"containers",
|
||||
'preinfo',
|
||||
'payments',
|
||||
]
|
||||
|
||||
|
||||
INSTALLED_APPS = [
|
||||
"django.contrib.admin",
|
||||
"django.contrib.auth",
|
||||
"django.contrib.contenttypes",
|
||||
"django.contrib.sessions",
|
||||
"django.contrib.messages",
|
||||
"django.contrib.staticfiles",
|
||||
"rest_framework",
|
||||
"damages_api",
|
||||
] + PROJECT_APPS
|
||||
|
||||
MIDDLEWARE = [
|
||||
"django.middleware.security.SecurityMiddleware",
|
||||
"django.contrib.sessions.middleware.SessionMiddleware",
|
||||
"django.middleware.common.CommonMiddleware",
|
||||
"django.middleware.csrf.CsrfViewMiddleware",
|
||||
"django.contrib.auth.middleware.AuthenticationMiddleware",
|
||||
"django.contrib.messages.middleware.MessageMiddleware",
|
||||
"django.middleware.clickjacking.XFrameOptionsMiddleware",
|
||||
]
|
||||
|
||||
ROOT_URLCONF = "DepoT.urls"
|
||||
|
||||
TEMPLATES = [
|
||||
{
|
||||
"BACKEND": "django.template.backends.django.DjangoTemplates",
|
||||
"DIRS": [BASE_DIR / 'templates']
|
||||
,
|
||||
"APP_DIRS": True,
|
||||
"OPTIONS": {
|
||||
"context_processors": [
|
||||
"django.template.context_processors.request",
|
||||
"django.contrib.auth.context_processors.auth",
|
||||
"django.contrib.messages.context_processors.messages",
|
||||
],
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
WSGI_APPLICATION = "DepoT.wsgi.application"
|
||||
|
||||
|
||||
# Database
|
||||
# https://docs.djangoproject.com/en/5.2/ref/settings/#databases
|
||||
|
||||
# DATABASES = {
|
||||
# "default": {
|
||||
# "ENGINE": "django.db.backends.sqlite3",
|
||||
# "NAME": BASE_DIR / "db.sqlite3",
|
||||
# }
|
||||
# }
|
||||
|
||||
DATABASES = {
|
||||
"default": {
|
||||
"ENGINE": "django.db.backends.postgresql",
|
||||
"NAME": env("DB_NAME"),
|
||||
"USER": env("DB_USER"),
|
||||
"PASSWORD": env("DB_PASSWORD"),
|
||||
"HOST": env("DB_HOST"),
|
||||
"PORT": env("DB_PORT"),
|
||||
}
|
||||
}
|
||||
# Password validation
|
||||
# https://docs.djangoproject.com/en/5.2/ref/settings/#auth-password-validators
|
||||
|
||||
AUTH_USER_MODEL = 'accounts.DepotUser'
|
||||
|
||||
LOGIN_URL = '/user/login/'
|
||||
|
||||
AUTH_PASSWORD_VALIDATORS = [
|
||||
{
|
||||
"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",
|
||||
},
|
||||
{
|
||||
"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",
|
||||
},
|
||||
{
|
||||
"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator",
|
||||
},
|
||||
{
|
||||
"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator",
|
||||
},
|
||||
]
|
||||
|
||||
AUTHENTICATION_BACKENDS = [
|
||||
'django.contrib.auth.backends.ModelBackend',
|
||||
]
|
||||
|
||||
# Internationalization
|
||||
# https://docs.djangoproject.com/en/5.2/topics/i18n/
|
||||
|
||||
LANGUAGE_CODE = "en-us"
|
||||
|
||||
TIME_ZONE = "UTC"
|
||||
|
||||
USE_I18N = True
|
||||
|
||||
USE_TZ = True
|
||||
|
||||
|
||||
# Static files (CSS, JavaScript, Images)
|
||||
# https://docs.djangoproject.com/en/5.2/howto/static-files/
|
||||
|
||||
STATIC_URL = "static/"
|
||||
|
||||
STATICFILES_DIRS = [
|
||||
BASE_DIR / 'static'
|
||||
]
|
||||
|
||||
TEMP_FILE_FOLDER = "/tmp/damages_photos"
|
||||
# Default primary key field type
|
||||
# https://docs.djangoproject.com/en/5.2/ref/settings/#default-auto-field
|
||||
|
||||
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
|
||||
|
||||
|
||||
OWNCLOUD_URL = env('OWNCLOUD_URL')
|
||||
OWNCLOUD_USER = env('OWNCLOUD_USER')
|
||||
OWNCLOUD_PASSWORD = env('OWNCLOUD_PASSWORD')
|
||||
OWNCLOUD_DAMAGES_FOLDER = env('OWNCLOUD_DAMAGES_FOLDER')
|
||||
|
||||
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
|
||||
EMAIL_HOST = env("EMAIL_HOST", cast=str, default=None)
|
||||
EMAIL_PORT = env("EMAIL_PORT", cast=str, default='587') # Recommended
|
||||
EMAIL_HOST_USER = env("EMAIL_HOST_USER", cast=str, default=None)
|
||||
EMAIL_HOST_PASSWORD = env("EMAIL_HOST_PASSWORD", cast=str, default=None)
|
||||
EMAIL_USE_TLS = env("EMAIL_USE_TLS", cast=bool, default=True) # Use EMAIL_PORT 587 for TLS
|
||||
EMAIL_USE_SSL = env("EMAIL_USE_SSL", cast=bool, default=False) # EUse MAIL_PORT 465 for SSL
|
||||
|
||||
ADMIN_USER_NAME=env("ADMIN_USER_NAME")
|
||||
ADMIN_USER_PASSWORD=env("ADMIN_USER_PASSWORD")
|
||||
ADMIN_USER_EMAIL=env("ADMIN_USER_EMAIL")
|
||||
|
||||
MANAGERS=[]
|
||||
ADMINS=[]
|
||||
if all([ADMIN_USER_NAME, ADMIN_USER_EMAIL]):
|
||||
ADMINS +=[
|
||||
(f'{ADMIN_USER_NAME}', f'{ADMIN_USER_EMAIL}')
|
||||
]
|
||||
MANAGERS=ADMINS
|
||||
|
||||
|
||||
MINIO_ENDPOINT = env('MINIO_ENDPOINT')
|
||||
AWS_S3_CUSTOM_DOMAIN = env('AWS_S3_CUSTOM_DOMAIN')
|
||||
MINIO_SERVER_URL = env('MINIO_SERVER_URL')
|
||||
AWS_S3_URL_PROTOCOL = env('AWS_S3_URL_PROTOCOL')
|
||||
MINIO_ACCESS_KEY = env('MINIO_ACCESS_KEY')
|
||||
MINIO_SECRET_KEY = env('MINIO_SECRET_KEY')
|
||||
MINIO_BUCKET_NAME = env('MINIO_BUCKET_NAME')
|
||||
MINIO_SECURE = False # Set to True if using HTTPS
|
||||
@@ -0,0 +1,247 @@
|
||||
"""
|
||||
Django settings for DepoT project.
|
||||
|
||||
Generated by 'django-admin startproject' using Django 5.2.3.
|
||||
|
||||
For more information on this file, see
|
||||
https://docs.djangoproject.com/en/5.2/topics/settings/
|
||||
|
||||
For the full list of settings and their values, see
|
||||
https://docs.djangoproject.com/en/5.2/ref/settings/
|
||||
"""
|
||||
|
||||
from pathlib import Path
|
||||
import os
|
||||
import environ
|
||||
from minio_backend.storage import MinioStaticStorage, MinioMediaStorage
|
||||
|
||||
BASE_DIR = Path(__file__).resolve().parent.parent.parent
|
||||
|
||||
env = environ.Env()
|
||||
environ.Env.read_env(os.path.join(BASE_DIR, 'production.env'))
|
||||
|
||||
SECRET_KEY = "django-insecure-g%187p84o9^rr)3#9@r3n^o2v1i%@6=+puxm7hlodg+kbsk%n#"
|
||||
|
||||
DEBUG = False
|
||||
|
||||
ALLOWED_HOSTS = ['192.168.24.43', '127.0.0.1', 'localhost', 'depot.kikimor.com', ]
|
||||
|
||||
CSRF_TRUSTED_ORIGINS = ['https://depot.kikimor.com']
|
||||
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTO', 'https')
|
||||
USE_X_FORWARDED_HOST = True
|
||||
|
||||
|
||||
PROJECT_APPS = [
|
||||
'accounts',
|
||||
"booking",
|
||||
"common",
|
||||
"containers",
|
||||
'preinfo',
|
||||
'payments',
|
||||
]
|
||||
|
||||
|
||||
INSTALLED_APPS = [
|
||||
"django.contrib.admin",
|
||||
"django.contrib.auth",
|
||||
"django.contrib.contenttypes",
|
||||
"django.contrib.sessions",
|
||||
"django.contrib.messages",
|
||||
"django.contrib.staticfiles",
|
||||
"rest_framework",
|
||||
"damages_api",
|
||||
"django_minio_backend",
|
||||
"minio_backend",
|
||||
] + PROJECT_APPS
|
||||
|
||||
MIDDLEWARE = [
|
||||
"django.middleware.security.SecurityMiddleware",
|
||||
"django.contrib.sessions.middleware.SessionMiddleware",
|
||||
"django.middleware.common.CommonMiddleware",
|
||||
"django.middleware.csrf.CsrfViewMiddleware",
|
||||
"django.contrib.auth.middleware.AuthenticationMiddleware",
|
||||
"django.contrib.messages.middleware.MessageMiddleware",
|
||||
"django.middleware.clickjacking.XFrameOptionsMiddleware",
|
||||
]
|
||||
|
||||
ROOT_URLCONF = "DepoT.urls"
|
||||
|
||||
TEMPLATES = [
|
||||
{
|
||||
"BACKEND": "django.template.backends.django.DjangoTemplates",
|
||||
"DIRS": [BASE_DIR / 'templates']
|
||||
,
|
||||
"APP_DIRS": True,
|
||||
"OPTIONS": {
|
||||
"context_processors": [
|
||||
"django.template.context_processors.request",
|
||||
"django.contrib.auth.context_processors.auth",
|
||||
"django.contrib.messages.context_processors.messages",
|
||||
],
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
WSGI_APPLICATION = "DepoT.wsgi.application"
|
||||
|
||||
|
||||
# Database
|
||||
# https://docs.djangoproject.com/en/5.2/ref/settings/#databases
|
||||
|
||||
# DATABASES = {
|
||||
# "default": {
|
||||
# "ENGINE": "django.db.backends.sqlite3",
|
||||
# "NAME": BASE_DIR / "db.sqlite3",
|
||||
# }
|
||||
# }
|
||||
|
||||
DATABASES = {
|
||||
"default": {
|
||||
"ENGINE": "django.db.backends.postgresql",
|
||||
"NAME": env("DB_NAME"),
|
||||
"USER": env("DB_USER"),
|
||||
"PASSWORD": env("DB_PASSWORD"),
|
||||
"HOST": env("DB_HOST"),
|
||||
"PORT": env("DB_PORT"),
|
||||
}
|
||||
}
|
||||
# Password validation
|
||||
# https://docs.djangoproject.com/en/5.2/ref/settings/#auth-password-validators
|
||||
|
||||
AUTH_USER_MODEL = 'accounts.DepotUser'
|
||||
|
||||
LOGIN_URL = '/user/login/'
|
||||
|
||||
AUTH_PASSWORD_VALIDATORS = [
|
||||
{
|
||||
"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",
|
||||
},
|
||||
{
|
||||
"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",
|
||||
},
|
||||
{
|
||||
"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator",
|
||||
},
|
||||
{
|
||||
"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator",
|
||||
},
|
||||
]
|
||||
|
||||
AUTHENTICATION_BACKENDS = [
|
||||
'django.contrib.auth.backends.ModelBackend',
|
||||
]
|
||||
|
||||
# Internationalization
|
||||
# https://docs.djangoproject.com/en/5.2/topics/i18n/
|
||||
|
||||
LANGUAGE_CODE = "en-us"
|
||||
|
||||
TIME_ZONE = "UTC"
|
||||
|
||||
USE_I18N = True
|
||||
|
||||
USE_TZ = True
|
||||
|
||||
|
||||
# Static files (CSS, JavaScript, Images)
|
||||
# https://docs.djangoproject.com/en/5.2/howto/static-files/
|
||||
|
||||
STATIC_URL = "static/"
|
||||
|
||||
STATICFILES_DIRS = [
|
||||
BASE_DIR / 'static'
|
||||
]
|
||||
|
||||
STATIC_ROOT = BASE_DIR / 'staticfiles'
|
||||
|
||||
TEMP_FILE_FOLDER = "/tmp/damages_photos"
|
||||
# Default primary key field type
|
||||
# https://docs.djangoproject.com/en/5.2/ref/settings/#default-auto-field
|
||||
|
||||
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
|
||||
|
||||
|
||||
OWNCLOUD_URL = env('OWNCLOUD_URL')
|
||||
OWNCLOUD_USER = env('OWNCLOUD_USER')
|
||||
OWNCLOUD_PASSWORD = env('OWNCLOUD_PASSWORD')
|
||||
OWNCLOUD_DAMAGES_FOLDER = env('OWNCLOUD_DAMAGES_FOLDER')
|
||||
|
||||
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
|
||||
EMAIL_HOST = env("EMAIL_HOST", cast=str, default=None)
|
||||
EMAIL_PORT = env("EMAIL_PORT", cast=str, default='587') # Recommended
|
||||
EMAIL_HOST_USER = env("EMAIL_HOST_USER", cast=str, default=None)
|
||||
EMAIL_HOST_PASSWORD = env("EMAIL_HOST_PASSWORD", cast=str, default=None)
|
||||
EMAIL_USE_TLS = env("EMAIL_USE_TLS", cast=bool, default=True) # Use EMAIL_PORT 587 for TLS
|
||||
EMAIL_USE_SSL = env("EMAIL_USE_SSL", cast=bool, default=False) # EUse MAIL_PORT 465 for SSL
|
||||
|
||||
ADMIN_USER_NAME=env("ADMIN_USER_NAME")
|
||||
ADMIN_USER_PASSWORD=env("ADMIN_USER_PASSWORD")
|
||||
ADMIN_USER_EMAIL=env("ADMIN_USER_EMAIL")
|
||||
|
||||
MANAGERS=[]
|
||||
ADMINS=[]
|
||||
if all([ADMIN_USER_NAME, ADMIN_USER_EMAIL]):
|
||||
ADMINS +=[
|
||||
(f'{ADMIN_USER_NAME}', f'{ADMIN_USER_EMAIL}')
|
||||
]
|
||||
MANAGERS=ADMINS
|
||||
|
||||
|
||||
MINIO_ENDPOINT = env('MINIO_ENDPOINT')
|
||||
AWS_S3_CUSTOM_DOMAIN = env('AWS_S3_CUSTOM_DOMAIN')
|
||||
MINIO_SERVER_URL = env('MINIO_SERVER_URL')
|
||||
MINIO_EXTERNAL_ENDPOINT = AWS_S3_CUSTOM_DOMAIN
|
||||
MINIO_EXTERNAL_ENDPOINT_USE_HTTPS = True
|
||||
AWS_S3_URL_PROTOCOL = env('AWS_S3_URL_PROTOCOL')
|
||||
MINIO_ACCESS_KEY = env('MINIO_ACCESS_KEY')
|
||||
MINIO_SECRET_KEY = env('MINIO_SECRET_KEY')
|
||||
MINIO_BUCKET_NAME = env('MINIO_BUCKET_NAME')
|
||||
MINIO_SECURE = False # Set to True if using HTTPS
|
||||
MINIO_USE_HTTPS = False # Add this line
|
||||
MINIO_STATIC_BUCKET = env('MINIO_STATIC_BUCKET_NAME')
|
||||
|
||||
# django-minio-backend settings
|
||||
MINIO_STORAGE_ENDPOINT = AWS_S3_CUSTOM_DOMAIN
|
||||
MINIO_STORAGE_PORT = 443 if MINIO_SECURE else 80 # Add this line
|
||||
MINIO_STORAGE_ACCESS_KEY = env('MINIO_ACCESS_KEY')
|
||||
MINIO_STORAGE_SECRET_KEY = env('MINIO_SECRET_KEY')
|
||||
MINIO_STORAGE_USE_HTTPS = True
|
||||
MINIO_STORAGE_MEDIA_BUCKET_NAME = env('MINIO_BUCKET_NAME') # For user-uploaded media
|
||||
MINIO_STORAGE_STATIC_BUCKET_NAME = env('MINIO_STATIC_BUCKET_NAME') # For static files
|
||||
MINIO_STORAGE_AUTO_CREATE_MEDIA_BUCKET = True
|
||||
MINIO_STORAGE_AUTO_CREATE_STATIC_BUCKET = True
|
||||
MINIO_STORAGE_AUTO_CREATE_POLICY = True
|
||||
MINIO_STORAGE_MEDIA_BASE_URL = f'{AWS_S3_URL_PROTOCOL}://{AWS_S3_CUSTOM_DOMAIN}/{env("MINIO_BUCKET_NAME")}/'
|
||||
MINIO_STORAGE_STATIC_BASE_URL = f'{AWS_S3_URL_PROTOCOL}://{AWS_S3_CUSTOM_DOMAIN}/{env("MINIO_STATIC_BUCKET_NAME")}/'
|
||||
|
||||
MINIO_PRIVATE_BUCKETS = [] # If you have any private buckets
|
||||
|
||||
MINIO_PUBLIC_BUCKETS = [
|
||||
env('MINIO_BUCKET_NAME'), # Just the bucket name as a string
|
||||
env('MINIO_STATIC_BUCKET_NAME') # Just the bucket name as a string
|
||||
]
|
||||
|
||||
MINIO_POLICY_ACTIONS = {
|
||||
'GET': ['get_object'],
|
||||
'PUT': ['put_object'],
|
||||
'DELETE': ['delete_object'],
|
||||
'LIST': ['list_multipart_uploads',
|
||||
'list_parts',
|
||||
'list_objects'],
|
||||
}
|
||||
|
||||
STORAGES = {
|
||||
"default": {
|
||||
"BACKEND": "minio_backend.storage.MinioMediaStorage",
|
||||
},
|
||||
"staticfiles": {
|
||||
"BACKEND": "minio_backend.storage.MinioStaticStorage",
|
||||
},
|
||||
}
|
||||
|
||||
DEFAULT_FILE_STORAGE = 'minio_backend.storage.MinioMediaStorage'
|
||||
STATICFILES_STORAGE = 'minio_backend.storage.MinioStaticStorage'
|
||||
STATIC_URL = f'{AWS_S3_URL_PROTOCOL}://{AWS_S3_CUSTOM_DOMAIN}/{env("MINIO_STATIC_BUCKET_NAME")}/'
|
||||
STATICFILES_LOCATION = 'static'
|
||||
MEDIA_ROOT = BASE_DIR / 'mediafiles'
|
||||
MEDIA_URL = f'{AWS_S3_URL_PROTOCOL}://{AWS_S3_CUSTOM_DOMAIN}/{env("MINIO_BUCKET_NAME")}/'
|
||||
Binary file not shown.
Binary file not shown.
+4
-1
@@ -41,4 +41,7 @@ class Booking(models.Model):
|
||||
|
||||
@property
|
||||
def containers_left(self):
|
||||
return self.container_count - (self.container_expedited_count or 0)
|
||||
return self.container_count - (self.container_expedited_count or 0)
|
||||
|
||||
class Meta:
|
||||
app_label = 'booking'
|
||||
+48
-2
@@ -1,3 +1,49 @@
|
||||
from django.test import TestCase
|
||||
from django.test import TestCase, Client
|
||||
from django.urls import reverse
|
||||
from django.contrib.auth import get_user_model
|
||||
from booking.models import Booking
|
||||
from common.models import LinesModel, ContainerTypeModel
|
||||
|
||||
# Create your tests here.
|
||||
class BookingViewsTestCase(TestCase):
|
||||
def setUp(self):
|
||||
self.client = Client()
|
||||
DepotUser = get_user_model()
|
||||
self.user = DepotUser.objects.create_user(username='testuser', password='password', user_type='EM')
|
||||
self.client.login(username='testuser', password='password')
|
||||
self.line = LinesModel.objects.create(name='Test Line')
|
||||
self.container_type = ContainerTypeModel.objects.create(name='20ft')
|
||||
self.booking = Booking.objects.create(
|
||||
number='BOOK123',
|
||||
container_type=self.container_type,
|
||||
container_count=10,
|
||||
line=self.line,
|
||||
created_by=self.user.id,
|
||||
updated_by=self.user.id
|
||||
)
|
||||
|
||||
def test_booking_list_view(self):
|
||||
response = self.client.get(reverse('booking-list'))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertTemplateUsed(response, 'booking/booking-list.html')
|
||||
self.assertContains(response, self.booking.number)
|
||||
|
||||
def test_booking_create_view(self):
|
||||
response = self.client.post(reverse('booking-create'), {
|
||||
'number': 'BOOK456',
|
||||
'container_type': self.container_type.id,
|
||||
'container_count': 5,
|
||||
'line': self.line.id,
|
||||
})
|
||||
self.assertEqual(response.status_code, 302)
|
||||
self.assertTrue(Booking.objects.filter(number='BOOK456').exists())
|
||||
|
||||
def test_booking_update_view(self):
|
||||
response = self.client.post(reverse('booking-update', args=[self.booking.id]), {
|
||||
'number': 'BOOK123-updated',
|
||||
'container_type': self.container_type.id,
|
||||
'container_count': 15,
|
||||
'line': self.line.id,
|
||||
})
|
||||
self.assertEqual(response.status_code, 302)
|
||||
self.booking.refresh_from_db()
|
||||
self.assertEqual(self.booking.number, 'BOOK123-updated')
|
||||
@@ -44,7 +44,7 @@ class CreateBookingView(LoginRequiredMixin, UserPassesTestMixin, LineFilterFormM
|
||||
return super().form_valid(form)
|
||||
|
||||
def test_func(self):
|
||||
self.request.user.has_company_perm('can_edit_preinfo') or self.request.user.user_type == 'CA'
|
||||
return self.request.user.has_company_perm('can_manage_booking') or self.request.user.user_type == 'CA'
|
||||
|
||||
|
||||
class ClientBookingUpdateView(LoginRequiredMixin, UserPassesTestMixin, LineFilterFormMixin, CreateView):
|
||||
|
||||
Binary file not shown.
+7
-2
@@ -15,7 +15,8 @@ class NomenclatureBaseModel(models.Model):
|
||||
|
||||
|
||||
class CompanyModel(NomenclatureBaseModel):
|
||||
...
|
||||
class Meta:
|
||||
app_label = 'common'
|
||||
|
||||
|
||||
class LinesModel(NomenclatureBaseModel):
|
||||
@@ -25,8 +26,12 @@ class LinesModel(NomenclatureBaseModel):
|
||||
related_name='line_company'
|
||||
)
|
||||
|
||||
class Meta:
|
||||
app_label = 'common'
|
||||
|
||||
class OperationModel(NomenclatureBaseModel):
|
||||
...
|
||||
class Meta:
|
||||
app_label = 'common'
|
||||
|
||||
class ContainerKindModel(NomenclatureBaseModel):
|
||||
...
|
||||
|
||||
+47
-2
@@ -1,3 +1,48 @@
|
||||
from django.test import TestCase
|
||||
from django.test import TestCase, Client
|
||||
from django.urls import reverse
|
||||
from django.contrib.auth import get_user_model
|
||||
from containers.models import Container
|
||||
from common.models import LinesModel, ContainerTypeModel
|
||||
from preinfo.models import Preinfo
|
||||
|
||||
# Create your tests here.
|
||||
class ContainerViewsTestCase(TestCase):
|
||||
def setUp(self):
|
||||
self.client = Client()
|
||||
DepotUser = get_user_model()
|
||||
self.user = DepotUser.objects.create_user(username='testuser', password='password', user_type='E')
|
||||
self.client.login(username='testuser', password='password')
|
||||
self.line = LinesModel.objects.create(name='Test Line')
|
||||
self.container_type = ContainerTypeModel.objects.create(name='20ft')
|
||||
self.preinfo = Preinfo.objects.create(number='PRE123', line=self.line, container_type=self.container_type)
|
||||
self.container = Container.objects.create(
|
||||
number='TEST1234567',
|
||||
line=self.line,
|
||||
container_type=self.container_type,
|
||||
received_by=self.user,
|
||||
preinfo=self.preinfo
|
||||
)
|
||||
|
||||
def test_container_list_view(self):
|
||||
response = self.client.get(reverse('container-list'))
|
||||
self.assertEqual(response.status_code, 200)
|
||||
self.assertTemplateUsed(response, 'containers/container-list.html')
|
||||
self.assertContains(response, self.container.number)
|
||||
|
||||
def test_container_receive_view(self):
|
||||
response = self.client.post(reverse('container-receive'), {
|
||||
'number': 'TEST7654321',
|
||||
'line': self.line.id,
|
||||
'container_type': self.container_type.id,
|
||||
'preinfo': self.preinfo.id,
|
||||
})
|
||||
self.assertEqual(response.status_code, 302)
|
||||
self.assertTrue(Container.objects.filter(number='TEST7654321').exists())
|
||||
|
||||
def test_container_expedition_view(self):
|
||||
response = self.client.post(reverse('container-expedition', args=[self.container.id]), {
|
||||
'expedition_vehicle': 'TRUCK123',
|
||||
})
|
||||
self.assertEqual(response.status_code, 302)
|
||||
self.container.refresh_from_db()
|
||||
self.assertTrue(self.container.expedited)
|
||||
self.assertEqual(self.container.expedition_vehicle, 'TRUCK123')
|
||||
+48
-2
@@ -1,3 +1,49 @@
|
||||
from django.test import TestCase
|
||||
import base64
|
||||
from unittest.mock import patch
|
||||
from django.test import TestCase, Client
|
||||
from django.urls import reverse
|
||||
from rest_framework import status
|
||||
from django.contrib.auth import get_user_model
|
||||
from containers.models import Container, ContainerPhotos
|
||||
from common.models import LinesModel, ContainerTypeModel
|
||||
from preinfo.models import Preinfo
|
||||
|
||||
# Create your tests here.
|
||||
class DamagesAPITestCase(TestCase):
|
||||
def setUp(self):
|
||||
self.client = Client()
|
||||
DepotUser = get_user_model()
|
||||
self.user = DepotUser.objects.create_user(username='testuser', password='password', user_type='E')
|
||||
self.client.login(username='testuser', password='password')
|
||||
self.line = LinesModel.objects.create(name='Test Line')
|
||||
self.container_type = ContainerTypeModel.objects.create(name='20ft')
|
||||
self.preinfo = Preinfo.objects.create(number='PRE123', line=self.line, container_type=self.container_type)
|
||||
self.container = Container.objects.create(
|
||||
number='TEST1234567',
|
||||
line=self.line,
|
||||
container_type=self.container_type,
|
||||
received_by=self.user,
|
||||
preinfo=self.preinfo
|
||||
)
|
||||
|
||||
@patch('damages_api.views.upload_damage_photo')
|
||||
def test_damage_photo_upload(self, mock_upload):
|
||||
mock_upload.return_value = 'http://mock-url.com/photo.jpg'
|
||||
photo_data = base64.b64encode(b'test photo data').decode('utf-8')
|
||||
response = self.client.post(reverse('damages-api', args=[self.container.id]), {
|
||||
'photo': photo_data,
|
||||
'photo_extension': 'jpg',
|
||||
}, content_type='application/json')
|
||||
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
|
||||
self.assertTrue(ContainerPhotos.objects.filter(container=self.container).exists())
|
||||
|
||||
@patch('damages_api.views.boto3.client')
|
||||
def test_damage_photo_retrieval(self, mock_boto_client):
|
||||
mock_s3 = mock_boto_client.return_value
|
||||
mock_s3.list_objects_v2.return_value = {
|
||||
'Contents': [
|
||||
{'Key': f'{self.container.id}/test.jpg'}
|
||||
]
|
||||
}
|
||||
response = self.client.get(reverse('damages-api', args=[self.container.id]))
|
||||
self.assertEqual(response.status_code, status.HTTP_200_OK)
|
||||
self.assertIn('url', response.data[0])
|
||||
@@ -38,8 +38,7 @@ services:
|
||||
networks:
|
||||
- app-network
|
||||
command: >
|
||||
bash -c "sleep 10 &&\
|
||||
python manage.py collectstatic --noinput --verbosity 3 &&\
|
||||
bash -c "python manage.py collectstatic --noinput --verbosity 3 &&\
|
||||
python manage.py migrate &&\
|
||||
gunicorn DepoT.wsgi:application --bind 0.0.0.0:8000 --workers 3"
|
||||
|
||||
@@ -70,7 +69,6 @@ services:
|
||||
condition: service_healthy
|
||||
entrypoint: >
|
||||
/bin/sh -c "
|
||||
sleep 10;
|
||||
mc alias set myminio http://minio:9000 kikimor shushunka1;
|
||||
mc mb myminio/damages;
|
||||
mc mb myminio/static;
|
||||
|
||||
@@ -2,6 +2,7 @@ FROM python:3.11-slim
|
||||
ENV PYTHONUNBUFFERED=1
|
||||
WORKDIR /DepoT
|
||||
ENV PYTHONPATH="${PYTHONPATH}:/DepoT:/."
|
||||
ENV DJANGO_SETTINGS_MODULE=DepoT.settings.production
|
||||
COPY requirements.txt .
|
||||
RUN pip install -r requirements.txt
|
||||
COPY . .
|
||||
|
||||
Binary file not shown.
@@ -6,7 +6,7 @@ import sys
|
||||
|
||||
def main():
|
||||
"""Run administrative tasks."""
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "DepoT.settings")
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "DepoT.settings.development")
|
||||
try:
|
||||
from django.core.management import execute_from_command_line
|
||||
except ImportError as exc:
|
||||
|
||||
Binary file not shown.
Binary file not shown.
@@ -5,9 +5,10 @@ import urllib.parse
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
import requests
|
||||
import environ
|
||||
|
||||
from DepoT.settings import env
|
||||
|
||||
# from DepoT.settings import env
|
||||
env = environ.Env()
|
||||
|
||||
class EPay:
|
||||
payment_types = {
|
||||
@@ -33,8 +34,8 @@ class EPay:
|
||||
datetime.today() + timedelta(days=int(env("INVOICE_EXPIRE_PERIOD")))
|
||||
).strftime("%d.%m.%Y")
|
||||
|
||||
if amount == 0:
|
||||
amount = 1000
|
||||
# if amount == 0:
|
||||
# amount = 1000 # for
|
||||
|
||||
message = f"MIN={client_id}\nINVOICE={invoice}\nAMOUNT={amount}\nCURRENCY={currency}\nEXP_TIME={expiry}\nDESCR={description}"
|
||||
encoded_data, checksum = EPay.encode_message(message)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
{% extends 'list-crud.html' %}
|
||||
{% load static %}
|
||||
{% load filters %}
|
||||
{% load custom_filters %}
|
||||
|
||||
{% block filter %}
|
||||
<form id="filterForm" method="get" style="display: inline;">
|
||||
@@ -32,8 +33,8 @@
|
||||
<td>{{ object.container_number }}</td>
|
||||
<td>{{ object.container_count }}</td>
|
||||
<td>{{ object.containers_left }}</td>
|
||||
<td>{{ object.vehicles }}</td>
|
||||
<td>{{ object.vehicles_left }}</td>
|
||||
<td>{{ object.vehicles|distinct_vehicles }}</td>
|
||||
<td>{{ object.vehicles_left|distinct_vehicles }}</td>
|
||||
<td>{{ object.created_on|bg_date }}</td>
|
||||
<td>{{ object.created_by.username }}</td>
|
||||
<td>{{ object.status }}</td>
|
||||
|
||||
@@ -7,12 +7,14 @@
|
||||
body {
|
||||
font-family: Arial, sans-serif;
|
||||
margin: 40px;
|
||||
background-color: black;
|
||||
color: white;
|
||||
background-color: black;
|
||||
color: white;
|
||||
font-size: 2em;
|
||||
}
|
||||
h1 {
|
||||
font-size: 2.5em;
|
||||
margin-bottom: 20px;
|
||||
text-align: center;
|
||||
}
|
||||
.table-container {
|
||||
width: 90%;
|
||||
@@ -21,14 +23,22 @@
|
||||
table {
|
||||
width: 100%;
|
||||
border-collapse: collapse;
|
||||
margin-bottom: 30px;
|
||||
}
|
||||
th, td {
|
||||
text-align: left;
|
||||
padding: 12px;
|
||||
border: 1px solid #ddd;
|
||||
}
|
||||
|
||||
th {
|
||||
background-color: #f5f5f5;
|
||||
font-size: 2em;
|
||||
background-color: white;
|
||||
color: black;
|
||||
}
|
||||
td {
|
||||
font-size: 2em;
|
||||
color: white;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
@@ -36,20 +46,22 @@
|
||||
|
||||
<h1>Vehicles with bookings</h1>
|
||||
|
||||
<div class="table-container">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Line name</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>BB1234TT, TT1234BB</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% for obj in objects %}
|
||||
<div class="table-container">
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>{{ obj.line }}</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>{{ obj.vehicles|upper}}</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{% endfor %}
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@@ -48,6 +48,10 @@
|
||||
<script src="{% static 'js/container_validation.js' %}"></script>
|
||||
{% endblock extra_js %}
|
||||
|
||||
{% block custom_js %}
|
||||
{% endblock custom_js %}
|
||||
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
||||
@@ -43,7 +43,7 @@
|
||||
{% endblock table_data %}
|
||||
|
||||
{% block buttons %}
|
||||
<button id="createPaymentBtn" class="btn btn-primary" data-requires-selection disabled>Create Payment</button>
|
||||
<button id="createPaymentBtn" class="btn btn-primary" data-requires-selection disabled>Create Payment</button>
|
||||
{% endblock buttons %}
|
||||
|
||||
{% block create_modal_header %}
|
||||
@@ -74,5 +74,6 @@ document.getElementById('createPaymentBtn').addEventListener('click', function()
|
||||
window.location.href = '{% url "payments_create" %}?' + params.toString();
|
||||
}
|
||||
});
|
||||
|
||||
</script>
|
||||
{% endblock custom_js %}
|
||||
Reference in New Issue
Block a user