Compare commits
	
		
			34 commits
		
	
	
		
			main
			...
			production
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 7720926b2b | |||
| 18f37ab513 | |||
| 3752438630 | |||
| c58ccb3977 | |||
| 1b37aa1522 | |||
| c90e19daaa | |||
| 71ca2e58e3 | |||
| d3857d37c5 | |||
| bb1b1a8ebf | |||
| 672e26c89d | |||
| 21e76f8f55 | |||
| 9815aa4c73 | |||
| 2a59c1acb5 | |||
| 92ad9ee301 | |||
| 916c66a281 | |||
| 241f56f550 | |||
| 42971c5e58 | |||
| 494b7743e9 | |||
| 37a5953134 | |||
| 896d66e801 | |||
| af3b043a46 | |||
| 20c5f13ea0 | |||
| 976be64028 | |||
| 20f00b786e | |||
| 8083b6d32e | |||
| ce8584f86b | |||
| 80fcdca876 | |||
| 9124e5d52c | |||
| 6cecb7fa80 | |||
| 3acbeb7770 | |||
| bf4047714c | |||
| 0201779fb5 | |||
| aa09d1e190 | |||
| 2941c7a7fc | 
					 17 changed files with 359 additions and 349 deletions
				
			
		
							
								
								
									
										294
									
								
								.gitignore
									
										
									
									
										vendored
									
									
								
							
							
						
						
									
										294
									
								
								.gitignore
									
										
									
									
										vendored
									
									
								
							| 
						 | 
					@ -1,142 +1,12 @@
 | 
				
			||||||
.idea
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Created by https://www.toptal.com/developers/gitignore/api/django,python,virtualenv
 | 
					 | 
				
			||||||
# Edit at https://www.toptal.com/developers/gitignore?templates=django,python,virtualenv
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Django ###
 | 
					 | 
				
			||||||
*.log
 | 
					 | 
				
			||||||
*.pot
 | 
					 | 
				
			||||||
*.pyc
 | 
					 | 
				
			||||||
__pycache__/
 | 
					 | 
				
			||||||
local_settings.py
 | 
					 | 
				
			||||||
#*.sqlite3
 | 
					 | 
				
			||||||
#db.sqlite3
 | 
					 | 
				
			||||||
db.sqlite3-journal
 | 
					 | 
				
			||||||
media
 | 
					 | 
				
			||||||
#static
 | 
					 | 
				
			||||||
staticfiles
 | 
					 | 
				
			||||||
profile_images
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# If your build process includes running collectstatic, then you probably don't need or want to include staticfiles/
 | 
					 | 
				
			||||||
# in your Git repository. Update and uncomment the following line accordingly.
 | 
					 | 
				
			||||||
# <django-project-name>/staticfiles/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# db.sqlite3
 | 
					 | 
				
			||||||
### Django.Python Stack ###
 | 
					 | 
				
			||||||
# Byte-compiled / optimized / DLL files
 | 
					# Byte-compiled / optimized / DLL files
 | 
				
			||||||
 | 
					__pycache__/
 | 
				
			||||||
*.py[cod]
 | 
					*.py[cod]
 | 
				
			||||||
*$py.class
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# C extensions
 | 
					 | 
				
			||||||
*.so
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Distribution / packaging
 | 
					 | 
				
			||||||
.Python
 | 
					 | 
				
			||||||
build/
 | 
					 | 
				
			||||||
develop-eggs/
 | 
					 | 
				
			||||||
#dist/
 | 
					 | 
				
			||||||
downloads/
 | 
					 | 
				
			||||||
eggs/
 | 
					 | 
				
			||||||
.eggs/
 | 
					 | 
				
			||||||
lib/
 | 
					 | 
				
			||||||
lib64/
 | 
					 | 
				
			||||||
parts/
 | 
					 | 
				
			||||||
sdist/
 | 
					 | 
				
			||||||
var/
 | 
					 | 
				
			||||||
wheels/
 | 
					 | 
				
			||||||
share/python-wheels/
 | 
					 | 
				
			||||||
*.egg-info/
 | 
					 | 
				
			||||||
.installed.cfg
 | 
					 | 
				
			||||||
*.egg
 | 
					 | 
				
			||||||
MANIFEST
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# PyInstaller
 | 
					 | 
				
			||||||
#  Usually these files are written by a python script from a template
 | 
					 | 
				
			||||||
#  before PyInstaller builds the exe, so as to inject date/other infos into it.
 | 
					 | 
				
			||||||
*.manifest
 | 
					 | 
				
			||||||
*.spec
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Installer logs
 | 
					 | 
				
			||||||
pip-log.txt
 | 
					 | 
				
			||||||
pip-delete-this-directory.txt
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Unit test / coverage reports
 | 
					 | 
				
			||||||
htmlcov/
 | 
					 | 
				
			||||||
.tox/
 | 
					 | 
				
			||||||
.nox/
 | 
					 | 
				
			||||||
.coverage
 | 
					 | 
				
			||||||
.coverage.*
 | 
					 | 
				
			||||||
.cache
 | 
					 | 
				
			||||||
nosetests.xml
 | 
					 | 
				
			||||||
coverage.xml
 | 
					 | 
				
			||||||
*.cover
 | 
					 | 
				
			||||||
*.py,cover
 | 
					 | 
				
			||||||
.hypothesis/
 | 
					 | 
				
			||||||
.pytest_cache/
 | 
					 | 
				
			||||||
cover/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Translations
 | 
					 | 
				
			||||||
*.mo
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Django stuff:
 | 
					# Django stuff:
 | 
				
			||||||
 | 
					*.log
 | 
				
			||||||
# Flask stuff:
 | 
					local_settings.py
 | 
				
			||||||
instance/
 | 
					db.sqlite3
 | 
				
			||||||
.webassets-cache
 | 
					db.sqlite3-journal
 | 
				
			||||||
 | 
					 | 
				
			||||||
# Scrapy stuff:
 | 
					 | 
				
			||||||
.scrapy
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Sphinx documentation
 | 
					 | 
				
			||||||
docs/_build/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# PyBuilder
 | 
					 | 
				
			||||||
.pybuilder/
 | 
					 | 
				
			||||||
target/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Jupyter Notebook
 | 
					 | 
				
			||||||
.ipynb_checkpoints
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# IPython
 | 
					 | 
				
			||||||
profile_default/
 | 
					 | 
				
			||||||
ipython_config.py
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# pyenv
 | 
					 | 
				
			||||||
#   For a library or package, you might want to ignore these files since the code is
 | 
					 | 
				
			||||||
#   intended to run in multiple environments; otherwise, check them in:
 | 
					 | 
				
			||||||
# .python-version
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# pipenv
 | 
					 | 
				
			||||||
#   According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
 | 
					 | 
				
			||||||
#   However, in case of collaboration, if having platform-specific dependencies or dependencies
 | 
					 | 
				
			||||||
#   having no cross-platform support, pipenv may install dependencies that don't work, or not
 | 
					 | 
				
			||||||
#   install all needed dependencies.
 | 
					 | 
				
			||||||
#Pipfile.lock
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# poetry
 | 
					 | 
				
			||||||
#   Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
 | 
					 | 
				
			||||||
#   This is especially recommended for binary packages to ensure reproducibility, and is more
 | 
					 | 
				
			||||||
#   commonly ignored for libraries.
 | 
					 | 
				
			||||||
#   https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
 | 
					 | 
				
			||||||
#poetry.lock
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# pdm
 | 
					 | 
				
			||||||
#   Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
 | 
					 | 
				
			||||||
#pdm.lock
 | 
					 | 
				
			||||||
#   pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
 | 
					 | 
				
			||||||
#   in version control.
 | 
					 | 
				
			||||||
#   https://pdm.fming.dev/#use-with-ide
 | 
					 | 
				
			||||||
.pdm.toml
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
 | 
					 | 
				
			||||||
__pypackages__/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Celery stuff
 | 
					 | 
				
			||||||
celerybeat-schedule
 | 
					 | 
				
			||||||
celerybeat.pid
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# SageMath parsed files
 | 
					 | 
				
			||||||
*.sage.py
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Environments
 | 
					# Environments
 | 
				
			||||||
.env
 | 
					.env
 | 
				
			||||||
| 
						 | 
					@ -147,141 +17,29 @@ ENV/
 | 
				
			||||||
env.bak/
 | 
					env.bak/
 | 
				
			||||||
venv.bak/
 | 
					venv.bak/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Spyder project settings
 | 
					# Media & Static Files
 | 
				
			||||||
.spyderproject
 | 
					/media/*
 | 
				
			||||||
.spyproject
 | 
					/staticfiles/*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Rope project settings
 | 
					 | 
				
			||||||
.ropeproject
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
# mkdocs documentation
 | 
					# Cache & Temporary Files
 | 
				
			||||||
/site
 | 
					*.swp
 | 
				
			||||||
 | 
					*.swo
 | 
				
			||||||
 | 
					*.swn
 | 
				
			||||||
 | 
					*.bak
 | 
				
			||||||
 | 
					*.tmp
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# mypy
 | 
					# Editor-specific files
 | 
				
			||||||
.mypy_cache/
 | 
					*.kate-swp
 | 
				
			||||||
.dmypy.json
 | 
					*.backup
 | 
				
			||||||
dmypy.json
 | 
					.vscode/
 | 
				
			||||||
 | 
					.idea/
 | 
				
			||||||
 | 
					.DS_Store
 | 
				
			||||||
 | 
					._*
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Pyre type checker
 | 
					# migrations
 | 
				
			||||||
.pyre/
 | 
					# */migrations/0*.py
 | 
				
			||||||
 | 
					!*/migrations/__init__.py
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# pytype static type analyzer
 | 
					# cursor
 | 
				
			||||||
.pytype/
 | 
					.cursor/*
 | 
				
			||||||
 | 
					 | 
				
			||||||
# Cython debug symbols
 | 
					 | 
				
			||||||
cython_debug/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# PyCharm
 | 
					 | 
				
			||||||
#  JetBrains specific template is maintained in a separate JetBrains.gitignore that can
 | 
					 | 
				
			||||||
#  be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
 | 
					 | 
				
			||||||
#  and can be added to the global gitignore or merged into this file.  For a more nuclear
 | 
					 | 
				
			||||||
#  option (not recommended) you can uncomment the following to ignore the entire idea folder.
 | 
					 | 
				
			||||||
#.idea/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Python ###
 | 
					 | 
				
			||||||
# Byte-compiled / optimized / DLL files
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# C extensions
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Distribution / packaging
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# PyInstaller
 | 
					 | 
				
			||||||
#  Usually these files are written by a python script from a template
 | 
					 | 
				
			||||||
#  before PyInstaller builds the exe, so as to inject date/other infos into it.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Installer logs
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Unit test / coverage reports
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Translations
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Django stuff:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Flask stuff:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Scrapy stuff:
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Sphinx documentation
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# PyBuilder
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Jupyter Notebook
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# IPython
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# pyenv
 | 
					 | 
				
			||||||
#   For a library or package, you might want to ignore these files since the code is
 | 
					 | 
				
			||||||
#   intended to run in multiple environments; otherwise, check them in:
 | 
					 | 
				
			||||||
# .python-version
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# pipenv
 | 
					 | 
				
			||||||
#   According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
 | 
					 | 
				
			||||||
#   However, in case of collaboration, if having platform-specific dependencies or dependencies
 | 
					 | 
				
			||||||
#   having no cross-platform support, pipenv may install dependencies that don't work, or not
 | 
					 | 
				
			||||||
#   install all needed dependencies.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# poetry
 | 
					 | 
				
			||||||
#   Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
 | 
					 | 
				
			||||||
#   This is especially recommended for binary packages to ensure reproducibility, and is more
 | 
					 | 
				
			||||||
#   commonly ignored for libraries.
 | 
					 | 
				
			||||||
#   https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# pdm
 | 
					 | 
				
			||||||
#   Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
 | 
					 | 
				
			||||||
#   pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
 | 
					 | 
				
			||||||
#   in version control.
 | 
					 | 
				
			||||||
#   https://pdm.fming.dev/#use-with-ide
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Celery stuff
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# SageMath parsed files
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Environments
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Spyder project settings
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Rope project settings
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# mkdocs documentation
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# mypy
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Pyre type checker
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# pytype static type analyzer
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Cython debug symbols
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# PyCharm
 | 
					 | 
				
			||||||
#  JetBrains specific template is maintained in a separate JetBrains.gitignore that can
 | 
					 | 
				
			||||||
#  be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
 | 
					 | 
				
			||||||
#  and can be added to the global gitignore or merged into this file.  For a more nuclear
 | 
					 | 
				
			||||||
#  option (not recommended) you can uncomment the following to ignore the entire idea folder.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### Python Patch ###
 | 
					 | 
				
			||||||
# Poetry local configuration file - https://python-poetry.org/docs/configuration/#local-configuration
 | 
					 | 
				
			||||||
poetry.toml
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# ruff
 | 
					 | 
				
			||||||
.ruff_cache/
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# LSP config files
 | 
					 | 
				
			||||||
pyrightconfig.json
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
### VirtualEnv ###
 | 
					 | 
				
			||||||
# Virtualenv
 | 
					 | 
				
			||||||
# http://iamzed.com/2009/05/07/a-primer-on-virtualenv/
 | 
					 | 
				
			||||||
[Bb]in
 | 
					 | 
				
			||||||
[Ii]nclude
 | 
					 | 
				
			||||||
[Ll]ib
 | 
					 | 
				
			||||||
[Ll]ib64
 | 
					 | 
				
			||||||
[Ll]ocal
 | 
					 | 
				
			||||||
[Ss]cripts
 | 
					 | 
				
			||||||
pyvenv.cfg
 | 
					 | 
				
			||||||
pip-selfcheck.json
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# End of https://www.toptal.com/developers/gitignore/api/django,python,virtualenv
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.cursor
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,6 +11,8 @@ https://docs.djangoproject.com/en/5.2/ref/settings/
 | 
				
			||||||
"""
 | 
					"""
 | 
				
			||||||
import os
 | 
					import os
 | 
				
			||||||
from pathlib import Path
 | 
					from pathlib import Path
 | 
				
			||||||
 | 
					from decouple import config
 | 
				
			||||||
 | 
					import dj_database_url
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Build paths inside the project like this: BASE_DIR / 'subdir'.
 | 
					# Build paths inside the project like this: BASE_DIR / 'subdir'.
 | 
				
			||||||
BASE_DIR = Path(__file__).resolve().parent.parent
 | 
					BASE_DIR = Path(__file__).resolve().parent.parent
 | 
				
			||||||
| 
						 | 
					@ -20,16 +22,28 @@ BASE_DIR = Path(__file__).resolve().parent.parent
 | 
				
			||||||
# See https://docs.djangoproject.com/en/5.2/howto/deployment/checklist/
 | 
					# See https://docs.djangoproject.com/en/5.2/howto/deployment/checklist/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# SECURITY WARNING: keep the secret key used in production secret!
 | 
					# SECURITY WARNING: keep the secret key used in production secret!
 | 
				
			||||||
SECRET_KEY = 'django-insecure-h!2hx$h=f6ktgdks!g2_*pg_s1nnuyk+j2yd*_x8r+3+3iyfy*'
 | 
					SECRET_KEY = config('DJANGO_SECRET_KEY', default="unsecure-secretkey-kjhsgfjsfgjsfgjsg")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# SECURITY WARNING: don't run with debug turned on in production!
 | 
					# SECURITY WARNING: don't run with debug turned on in production!
 | 
				
			||||||
DEBUG = True
 | 
					DEBUG = config('DEBUG', cast=bool, default=True)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ALLOWED_HOSTS = []
 | 
					# Allowed hosts
 | 
				
			||||||
 | 
					ALLOWED_HOSTS = [host for host in config("DJANGO_ALLOWED_HOSTS", default="").split() if host]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# URL scheme (http or https)
 | 
				
			||||||
 | 
					URL_SCHEME = config("URL_SCHEME", default="http")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# CSRF trusted origins (add both with and without port if you use a non-standard port)
 | 
				
			||||||
 | 
					CSRF_TRUSTED_ORIGINS = []
 | 
				
			||||||
 | 
					for host in ALLOWED_HOSTS:
 | 
				
			||||||
 | 
					    if host not in ("localhost", "127.0.0.1"):
 | 
				
			||||||
 | 
					        CSRF_TRUSTED_ORIGINS.append(f"{URL_SCHEME}://{host}")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Generate base URL for absolute URLs (use first allowed host)
 | 
				
			||||||
 | 
					BASE_URL = f"{URL_SCHEME}://{ALLOWED_HOSTS[0]}" if ALLOWED_HOSTS else "http://localhost"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Application definition
 | 
					# Application definition
 | 
				
			||||||
 | 
					 | 
				
			||||||
INSTALLED_APPS = [
 | 
					INSTALLED_APPS = [
 | 
				
			||||||
    # ------ theme ------ #
 | 
					    # ------ theme ------ #
 | 
				
			||||||
    'jazzmin',
 | 
					    'jazzmin',
 | 
				
			||||||
| 
						 | 
					@ -45,6 +59,7 @@ INSTALLED_APPS = [
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # ------- third party apps ------- #
 | 
					    # ------- third party apps ------- #
 | 
				
			||||||
    'simple_history',
 | 
					    'simple_history',
 | 
				
			||||||
 | 
					    'django_extensions',
 | 
				
			||||||
    # -------------------------------- #
 | 
					    # -------------------------------- #
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # ------- my apps ------- #
 | 
					    # ------- my apps ------- #
 | 
				
			||||||
| 
						 | 
					@ -96,13 +111,20 @@ WSGI_APPLICATION = '_base.wsgi.application'
 | 
				
			||||||
# Database
 | 
					# Database
 | 
				
			||||||
# https://docs.djangoproject.com/en/5.2/ref/settings/#databases
 | 
					# https://docs.djangoproject.com/en/5.2/ref/settings/#databases
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					DB_TYPE = config('DB_TYPE', default='sqlite').lower()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if DB_TYPE == 'postgres':
 | 
				
			||||||
    DATABASES = {
 | 
					    DATABASES = {
 | 
				
			||||||
    'default': {
 | 
					        'default': dj_database_url.config(default=config('DATABASE_URL'))
 | 
				
			||||||
        'ENGINE': 'django.db.backends.sqlite3',
 | 
					 | 
				
			||||||
        'NAME': BASE_DIR / 'db.sqlite3',
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					else:
 | 
				
			||||||
 | 
					    DATABASES = {
 | 
				
			||||||
 | 
					        "default": {
 | 
				
			||||||
 | 
					            "ENGINE": "django.db.backends.sqlite3",
 | 
				
			||||||
 | 
					            "NAME": BASE_DIR/"db.sqlite3",
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Password validation
 | 
					# Password validation
 | 
				
			||||||
# https://docs.djangoproject.com/en/5.2/ref/settings/#auth-password-validators
 | 
					# https://docs.djangoproject.com/en/5.2/ref/settings/#auth-password-validators
 | 
				
			||||||
| 
						 | 
					@ -139,15 +161,15 @@ USE_TZ = True
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Static files (CSS, JavaScript, Images)
 | 
					# Static files (CSS, JavaScript, Images)
 | 
				
			||||||
# https://docs.djangoproject.com/en/5.2/howto/static-files/
 | 
					STATIC_URL = '/static/'
 | 
				
			||||||
STATIC_ROOT = 'ss'
 | 
					STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
 | 
				
			||||||
STATIC_URL = 'static/'
 | 
					 | 
				
			||||||
STATICFILES_DIRS = [
 | 
					STATICFILES_DIRS = [
 | 
				
			||||||
    os.path.join(BASE_DIR, 'static')
 | 
					    os.path.join(BASE_DIR, 'static'),
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# Media files
 | 
				
			||||||
MEDIA_URL = '/media/'
 | 
					MEDIA_URL = '/media/'
 | 
				
			||||||
MEDIA_ROOT = BASE_DIR / 'media'
 | 
					MEDIA_ROOT = os.path.join(BASE_DIR, 'media')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Default primary key field type
 | 
					# Default primary key field type
 | 
				
			||||||
# https://docs.djangoproject.com/en/5.2/ref/settings/#default-auto-field
 | 
					# https://docs.djangoproject.com/en/5.2/ref/settings/#default-auto-field
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,6 +5,7 @@
 | 
				
			||||||
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
 | 
					  <meta name="viewport" content="width=device-width, initial-scale=1.0">
 | 
				
			||||||
  <title>تاییدیه - {{ instance.code }}</title>
 | 
					  <title>تاییدیه - {{ instance.code }}</title>
 | 
				
			||||||
  {% load static %}
 | 
					  {% load static %}
 | 
				
			||||||
 | 
					  {% load common_tags %}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  <!-- Fonts (match project) -->
 | 
					  <!-- Fonts (match project) -->
 | 
				
			||||||
  <link rel="preconnect" href="https://fonts.googleapis.com">
 | 
					  <link rel="preconnect" href="https://fonts.googleapis.com">
 | 
				
			||||||
| 
						 | 
					@ -52,21 +53,31 @@
 | 
				
			||||||
    <h6 class="my-2">مشخصات چاه و کنتور هوشمند</h6>
 | 
					    <h6 class="my-2">مشخصات چاه و کنتور هوشمند</h6>
 | 
				
			||||||
    <div class="row" style="font-size: 14px;">
 | 
					    <div class="row" style="font-size: 14px;">
 | 
				
			||||||
      <div class="col-4">
 | 
					      <div class="col-4">
 | 
				
			||||||
        <div>موقعیت مکانی (UTM): {{ latest_report.utm_x|default:'-' }} , {{ latest_report.utm_y|default:'-' }}</div>
 | 
					        <div>موقعیت مکانی (UTM): X: {{ latest_report.utm_x|default:'-' }} , Y: {{ latest_report.utm_y|default:'-' }}</div>
 | 
				
			||||||
        <div>نیرو محرکه چاه: {{ latest_report.driving_force|default:'-' }}</div>
 | 
					        <div>نیرو محرکه چاه: {{ latest_report.driving_force|default:'-' }}</div>
 | 
				
			||||||
        <div>نوع کنتور: {{ latest_report.get_meter_type_display|default:'-' }}</div>
 | 
					        <div>نوع کنتور: {{ latest_report.get_meter_type_display|default:'-' }}</div>
 | 
				
			||||||
        <div>قطر لوله آبده (اینچ): {{ latest_report.discharge_pipe_diameter|default:'-' }}</div>
 | 
					        {% if latest_report.meter_type == 'smart' %}
 | 
				
			||||||
 | 
					        <div>مدل کنتور: {{ latest_report.get_meter_model_display|default:'-' }}</div>
 | 
				
			||||||
 | 
					        {% else %}
 | 
				
			||||||
 | 
					        <div>سایز کنتور: {{ latest_report.meter_size|default:'-' }}</div>
 | 
				
			||||||
 | 
					        {% endif %}
 | 
				
			||||||
        <div>نوع مصرف: {{ latest_report.get_usage_type_display|default:'-' }}</div>
 | 
					        <div>نوع مصرف: {{ latest_report.get_usage_type_display|default:'-' }}</div>
 | 
				
			||||||
        <div>شماره سیمکارت: {{ latest_report.sim_number|default:'-' }}</div>
 | 
					        <div>شماره سیمکارت: {{ latest_report.sim_number|default:'-' }}</div>
 | 
				
			||||||
 | 
					        <div>شارژ کنتور (متر مکعب): {{ latest_report.meter_charge|default:'-' }}</div>
 | 
				
			||||||
 | 
					        <div>پایان اعتبار شارژ: {{ latest_report.meter_charge_expiration_date|to_jalali|default:'-' }}</div>
 | 
				
			||||||
 | 
					        <div>شماره سریال کنتور: {{ instance.well.water_meter_serial_number|default:'-' }}</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
      <div class="col-4">
 | 
					      <div class="col-4">
 | 
				
			||||||
        <div>سایز کنتور: {{ latest_report.meter_size|default:'-' }}</div>
 | 
					        <div>قطر لوله آبده (اینچ): {{ latest_report.discharge_pipe_diameter|default:'-' }}</div>
 | 
				
			||||||
        <div>شماره پروانه بهرهبرداری چاه: {{ latest_report.exploitation_license_number|default:'-' }}</div>
 | 
					        <div>شماره پروانه بهرهبرداری چاه: {{ latest_report.exploitation_license_number|default:'-' }}</div>
 | 
				
			||||||
        <div>قدرت موتور: {{ latest_report.motor_power|default:'-' }}</div>
 | 
					        <div>قدرت موتور (کیلووات ساعت): {{ latest_report.motor_power|default:'-' }}</div>
 | 
				
			||||||
        <div>دبی قبل از کالیبراسیون: {{ latest_report.pre_calibration_flow_rate|default:'-' }}</div>
 | 
					        <div>دبی (لیتر بر ثانیه): {{ latest_report.flow_rate|default:'-' }}</div>
 | 
				
			||||||
        <div>دبی بعد از کالیبراسیون: {{ latest_report.post_calibration_flow_rate|default:'-' }}</div>
 | 
					        <div>عدد کنتور (متر مکعب): {{ latest_report.meter_reading|default:'-' }}</div>
 | 
				
			||||||
 | 
					        <div>پلمپ تابلو: {{ latest_report.is_panel_sealed|yesno:'دارد,ندارد' }}</div>
 | 
				
			||||||
 | 
					        <div>تابلو قطع: {{ latest_report.is_panel_cut|yesno:'دارد,ندارد' }}</div>
 | 
				
			||||||
 | 
					        <div>انجام عملیات قطع: {{ latest_report.is_disconnection_done|yesno:'دارد,ندارد' }}</div>
 | 
				
			||||||
        <div>نام شرکت کنتورساز: {{ latest_report.water_meter_manufacturer.name|default:'-' }}</div>
 | 
					        <div>نام شرکت کنتورساز: {{ latest_report.water_meter_manufacturer.name|default:'-' }}</div>
 | 
				
			||||||
        <div>شماره سریال کنتور: {{ instance.well.water_meter_serial_number|default:'-' }}</div>
 | 
					 | 
				
			||||||
      </div>
 | 
					      </div>
 | 
				
			||||||
      <div class="col-4">
 | 
					      <div class="col-4">
 | 
				
			||||||
        <!-- Signature -->
 | 
					        <!-- Signature -->
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,6 +2,7 @@
 | 
				
			||||||
  {% load static %}
 | 
					  {% load static %}
 | 
				
			||||||
  {% load processes_tags %}
 | 
					  {% load processes_tags %}
 | 
				
			||||||
  {% load humanize %}
 | 
					  {% load humanize %}
 | 
				
			||||||
 | 
					  {% load common_tags %}
 | 
				
			||||||
  {% load accounts_tags %}
 | 
					  {% load accounts_tags %}
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  {% block sidebar %}
 | 
					  {% block sidebar %}
 | 
				
			||||||
| 
						 | 
					@ -73,21 +74,30 @@
 | 
				
			||||||
                <h6 class="mb-2">مشخصات چاه و کنتور هوشمند</h6>
 | 
					                <h6 class="mb-2">مشخصات چاه و کنتور هوشمند</h6>
 | 
				
			||||||
                <div class="row g-2 small">
 | 
					                <div class="row g-2 small">
 | 
				
			||||||
                  <div class="col-12 col-md-6">
 | 
					                  <div class="col-12 col-md-6">
 | 
				
			||||||
                    <div class="d-flex gap-2"><span class="text-muted">موقعیت مکانی (UTM):</span><span class="fw-medium">{{ latest_report.utm_x|default:'-' }} , {{ latest_report.utm_y|default:'-' }}</span></div>
 | 
					                    <div class="d-flex gap-2"><span class="text-muted">موقعیت مکانی (UTM):</span><span class="fw-medium">X: {{ latest_report.utm_x|default:'-' }} , Y: {{ latest_report.utm_y|default:'-' }}</span></div>
 | 
				
			||||||
                    <div class="d-flex gap-2"><span class="text-muted">نیرو محرکه چاه:</span><span class="fw-medium">{{ latest_report.driving_force|default:'-' }}</span></div>
 | 
					                    <div class="d-flex gap-2"><span class="text-muted">نیرو محرکه چاه:</span><span class="fw-medium">{{ latest_report.driving_force|default:'-' }}</span></div>
 | 
				
			||||||
                    <div class="d-flex gap-2"><span class="text-muted">نوع کنتور:</span><span class="fw-medium">{{ latest_report.get_meter_type_display|default:'-' }}</span></div>
 | 
					                    <div class="d-flex gap-2"><span class="text-muted">نوع کنتور:</span><span class="fw-medium">{{ latest_report.get_meter_type_display|default:'-' }}</span></div>
 | 
				
			||||||
                    <div class="d-flex gap-2"><span class="text-muted">قطر لوله آبده (اینچ):</span><span class="fw-medium">{{ latest_report.discharge_pipe_diameter|default:'-' }}</span></div>
 | 
					                    {% if latest_report.meter_type == 'smart' %}
 | 
				
			||||||
 | 
					                    <div class="d-flex gap-2"><span class="text-muted">مدل کنتور:</span><span class="fw-medium">{{ latest_report.get_meter_model_display|default:'-' }}</span></div>
 | 
				
			||||||
 | 
					                    {% else %}
 | 
				
			||||||
 | 
					                    <div class="d-flex gap-2"><span class="text-muted">سایز کنتور:</span><span class="fw-medium">{{ latest_report.meter_size|default:'-' }}</span></div>
 | 
				
			||||||
 | 
					                    {% endif %}
 | 
				
			||||||
                    <div class="d-flex gap-2"><span class="text-muted">نوع مصرف:</span><span class="fw-medium">{{ latest_report.get_usage_type_display|default:'-' }}</span></div>
 | 
					                    <div class="d-flex gap-2"><span class="text-muted">نوع مصرف:</span><span class="fw-medium">{{ latest_report.get_usage_type_display|default:'-' }}</span></div>
 | 
				
			||||||
                    <div class="d-flex gap-2"><span class="text-muted">شماره سیمکارت:</span><span class="fw-medium">{{ latest_report.sim_number|default:'-' }}</span></div>
 | 
					                    <div class="d-flex gap-2"><span class="text-muted">شماره سیمکارت:</span><span class="fw-medium">{{ latest_report.sim_number|default:'-' }}</span></div>
 | 
				
			||||||
 | 
					                    <div class="d-flex gap-2"><span class="text-muted">شارژ کنتور (متر مکعب):</span><span class="fw-medium">{{ latest_report.meter_charge|default:'-' }}</span></div>
 | 
				
			||||||
 | 
					                    <div class="d-flex gap-2"><span class="text-muted">پایان اعتبار شارژ:</span><span class="fw-medium">{{ latest_report.meter_charge_expiration_date|to_jalali|default:'-' }}</span></div>
 | 
				
			||||||
 | 
					                    <div class="d-flex gap-2"><span class="text-muted">شماره سریال کنتور:</span><span class="fw-medium">{{ instance.well.water_meter_serial_number|default:'-' }}</span></div>
 | 
				
			||||||
                  </div>
 | 
					                  </div>
 | 
				
			||||||
                  <div class="col-12 col-md-6">
 | 
					                  <div class="col-12 col-md-6">
 | 
				
			||||||
                    <div class="d-flex gap-2"><span class="text-muted">سایز کنتور:</span><span class="fw-medium">{{ latest_report.meter_size|default:'-' }}</span></div>
 | 
					                    <div class="d-flex gap-2"><span class="text-muted">قطر لوله آبده (اینچ):</span><span class="fw-medium">{{ latest_report.discharge_pipe_diameter|default:'-' }}</span></div>
 | 
				
			||||||
                    <div class="d-flex gap-2"><span class="text-muted">شماره پروانه بهرهبرداری چاه:</span><span class="fw-medium">{{ latest_report.exploitation_license_number|default:'-' }}</span></div>
 | 
					                    <div class="d-flex gap-2"><span class="text-muted">شماره پروانه بهرهبرداری چاه:</span><span class="fw-medium">{{ latest_report.exploitation_license_number|default:'-' }}</span></div>
 | 
				
			||||||
                    <div class="d-flex gap-2"><span class="text-muted">قدرت موتور:</span><span class="fw-medium">{{ latest_report.motor_power|default:'-' }}</span></div>
 | 
					                    <div class="d-flex gap-2"><span class="text-muted">قدرت موتور (کیلووات ساعت):</span><span class="fw-medium">{{ latest_report.motor_power|default:'-' }}</span></div>
 | 
				
			||||||
                    <div class="d-flex gap-2"><span class="text-muted">دبی قبل از کالیبراسیون:</span><span class="fw-medium">{{ latest_report.pre_calibration_flow_rate|default:'-' }}</span></div>
 | 
					                    <div class="d-flex gap-2"><span class="text-muted">دبی (لیتر بر ثانیه):</span><span class="fw-medium">{{ latest_report.flow_rate|default:'-' }}</span></div>
 | 
				
			||||||
                    <div class="d-flex gap-2"><span class="text-muted">دبی بعد از کالیبراسیون:</span><span class="fw-medium">{{ latest_report.post_calibration_flow_rate|default:'-' }}</span></div>
 | 
					                    <div class="d-flex gap-2"><span class="text-muted">عدد کنتور (متر مکعب):</span><span class="fw-medium">{{ latest_report.meter_reading|default:'-' }}</span></div>
 | 
				
			||||||
 | 
					                    <div class="d-flex gap-2"><span class="text-muted">پلمپ تابلو:</span><span class="fw-medium">{{ latest_report.is_panel_sealed|yesno:'دارد,ندارد' }}</span></div>
 | 
				
			||||||
 | 
					                    <div class="d-flex gap-2"><span class="text-muted">تابلو قطع:</span><span class="fw-medium">{{ latest_report.is_panel_cut|yesno:'دارد,ندارد' }}</span></div>
 | 
				
			||||||
 | 
					                    <div class="d-flex gap-2"><span class="text-muted">انجام عملیات قطع:</span><span class="fw-medium">{{ latest_report.is_disconnection_done|yesno:'دارد,ندارد' }}</span></div>
 | 
				
			||||||
                    <div class="d-flex gap-2"><span class="text-muted">نام شرکت کنتورساز:</span><span class="fw-medium">{{ latest_report.water_meter_manufacturer.name|default:'-' }}</span></div>
 | 
					                    <div class="d-flex gap-2"><span class="text-muted">نام شرکت کنتورساز:</span><span class="fw-medium">{{ latest_report.water_meter_manufacturer.name|default:'-' }}</span></div>
 | 
				
			||||||
                    <div class="d-flex gap-2"><span class="text-muted">شماره سریال کنتور:</span><span class="fw-medium">{{ instance.well.water_meter_serial_number|default:'-' }}</span></div>
 | 
					 | 
				
			||||||
                  </div>
 | 
					                  </div>
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
                <div class="signature-section d-flex justify-content-end">
 | 
					                <div class="signature-section d-flex justify-content-end">
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								db.sqlite3
									
										
									
									
									
								
							
							
						
						
									
										
											BIN
										
									
								
								db.sqlite3
									
										
									
									
									
								
							
										
											Binary file not shown.
										
									
								
							| 
						 | 
					@ -24,11 +24,12 @@ class InstallationReportAdmin(admin.ModelAdmin):
 | 
				
			||||||
    list_display = (
 | 
					    list_display = (
 | 
				
			||||||
        'assignment', 'visited_date', 'meter_type', 'meter_size', 'water_meter_manufacturer',
 | 
					        'assignment', 'visited_date', 'meter_type', 'meter_size', 'water_meter_manufacturer',
 | 
				
			||||||
        'discharge_pipe_diameter', 'usage_type', 'exploitation_license_number',
 | 
					        'discharge_pipe_diameter', 'usage_type', 'exploitation_license_number',
 | 
				
			||||||
        'motor_power', 'pre_calibration_flow_rate', 'post_calibration_flow_rate',
 | 
					        'motor_power', 'flow_rate', 'meter_reading', 'meter_charge', 'meter_charge_expiration_date',
 | 
				
			||||||
        'new_water_meter_serial', 'seal_number', 'sim_number',
 | 
					        'new_water_meter_serial', 'seal_number', 'sim_number',
 | 
				
			||||||
 | 
					        'is_panel_sealed', 'is_panel_cut', 'is_disconnection_done',
 | 
				
			||||||
        'is_meter_suspicious', 'approved', 'created'
 | 
					        'is_meter_suspicious', 'approved', 'created'
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
    list_filter = ('is_meter_suspicious', 'approved', 'visited_date', 'meter_type', 'usage_type', 'water_meter_manufacturer')
 | 
					    list_filter = ('is_meter_suspicious', 'is_panel_sealed', 'is_panel_cut', 'is_disconnection_done', 'approved', 'visited_date', 'meter_type', 'usage_type', 'water_meter_manufacturer')
 | 
				
			||||||
    search_fields = (
 | 
					    search_fields = (
 | 
				
			||||||
        'assignment__process_instance__code', 'new_water_meter_serial', 'seal_number', 'exploitation_license_number', 'sim_number'
 | 
					        'assignment__process_instance__code', 'new_water_meter_serial', 'seal_number', 'exploitation_license_number', 'sim_number'
 | 
				
			||||||
    )
 | 
					    )
 | 
				
			||||||
| 
						 | 
					@ -43,7 +44,7 @@ class InstallationReportAdmin(admin.ModelAdmin):
 | 
				
			||||||
            )
 | 
					            )
 | 
				
			||||||
        }),
 | 
					        }),
 | 
				
			||||||
        ('مشخصات هیدرولیکی', {
 | 
					        ('مشخصات هیدرولیکی', {
 | 
				
			||||||
            'fields': ('discharge_pipe_diameter', 'pre_calibration_flow_rate', 'post_calibration_flow_rate')
 | 
					            'fields': ('discharge_pipe_diameter', 'flow_rate', 'meter_reading', 'meter_charge', 'meter_charge_expiration_date')
 | 
				
			||||||
        }),
 | 
					        }),
 | 
				
			||||||
        ('کاربری و مجوز', {
 | 
					        ('کاربری و مجوز', {
 | 
				
			||||||
            'fields': ('usage_type', 'exploitation_license_number')
 | 
					            'fields': ('usage_type', 'exploitation_license_number')
 | 
				
			||||||
| 
						 | 
					@ -51,6 +52,9 @@ class InstallationReportAdmin(admin.ModelAdmin):
 | 
				
			||||||
        ('توان و محرکه', {
 | 
					        ('توان و محرکه', {
 | 
				
			||||||
            'fields': ('driving_force', 'motor_power')
 | 
					            'fields': ('driving_force', 'motor_power')
 | 
				
			||||||
        }),
 | 
					        }),
 | 
				
			||||||
 | 
					        ('وضعیت تابلو/قطع', {
 | 
				
			||||||
 | 
					            'fields': ('is_panel_sealed', 'is_panel_cut', 'is_disconnection_done')
 | 
				
			||||||
 | 
					        }),
 | 
				
			||||||
        ('توضیحات', {
 | 
					        ('توضیحات', {
 | 
				
			||||||
            'fields': ('description',)
 | 
					            'fields': ('description',)
 | 
				
			||||||
        }),
 | 
					        }),
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -22,7 +22,8 @@ class InstallationReportForm(forms.ModelForm):
 | 
				
			||||||
            'visited_date', 'new_water_meter_serial', 'seal_number',
 | 
					            'visited_date', 'new_water_meter_serial', 'seal_number',
 | 
				
			||||||
            'utm_x', 'utm_y', 'meter_type', 'meter_size', 'meter_model',
 | 
					            'utm_x', 'utm_y', 'meter_type', 'meter_size', 'meter_model',
 | 
				
			||||||
            'discharge_pipe_diameter', 'usage_type', 'exploitation_license_number',
 | 
					            'discharge_pipe_diameter', 'usage_type', 'exploitation_license_number',
 | 
				
			||||||
            'motor_power', 'pre_calibration_flow_rate', 'post_calibration_flow_rate',
 | 
					            'motor_power', 'flow_rate', 'meter_reading', 'meter_charge', 'meter_charge_expiration_date',
 | 
				
			||||||
 | 
					            'is_panel_sealed', 'is_panel_cut', 'is_disconnection_done',
 | 
				
			||||||
            'water_meter_manufacturer', 'sim_number', 'driving_force',
 | 
					            'water_meter_manufacturer', 'sim_number', 'driving_force',
 | 
				
			||||||
            'is_meter_suspicious', 'description'
 | 
					            'is_meter_suspicious', 'description'
 | 
				
			||||||
        ]
 | 
					        ]
 | 
				
			||||||
| 
						 | 
					@ -90,17 +91,24 @@ class InstallationReportForm(forms.ModelForm):
 | 
				
			||||||
                'class': 'form-control',
 | 
					                'class': 'form-control',
 | 
				
			||||||
                'required': True
 | 
					                'required': True
 | 
				
			||||||
            }),
 | 
					            }),
 | 
				
			||||||
            'pre_calibration_flow_rate': forms.NumberInput(attrs={
 | 
					            'flow_rate': forms.NumberInput(attrs={
 | 
				
			||||||
                'class': 'form-control',
 | 
					                'class': 'form-control',
 | 
				
			||||||
                'min': '0',
 | 
					                'min': '0',
 | 
				
			||||||
                'step': '0.0001',
 | 
					                'step': '0.0001',
 | 
				
			||||||
                'required': True
 | 
					 | 
				
			||||||
            }),
 | 
					            }),
 | 
				
			||||||
            'post_calibration_flow_rate': forms.NumberInput(attrs={
 | 
					            'meter_reading': forms.NumberInput(attrs={
 | 
				
			||||||
                'class': 'form-control',
 | 
					                'class': 'form-control',
 | 
				
			||||||
                'min': '0',
 | 
					                'min': '0',
 | 
				
			||||||
                'step': '0.0001',
 | 
					                'step': '0.0001',
 | 
				
			||||||
                'required': True
 | 
					            }),
 | 
				
			||||||
 | 
					            'meter_charge': forms.NumberInput(attrs={
 | 
				
			||||||
 | 
					                'class': 'form-control',
 | 
				
			||||||
 | 
					                'min': '0',
 | 
				
			||||||
 | 
					                'step': '0.0001',
 | 
				
			||||||
 | 
					            }),
 | 
				
			||||||
 | 
					            'meter_charge_expiration_date': forms.DateInput(attrs={
 | 
				
			||||||
 | 
					                'type': 'date',
 | 
				
			||||||
 | 
					                'class': 'form-control',
 | 
				
			||||||
            }),
 | 
					            }),
 | 
				
			||||||
            'water_meter_manufacturer': forms.Select(attrs={
 | 
					            'water_meter_manufacturer': forms.Select(attrs={
 | 
				
			||||||
                'class': 'form-select',
 | 
					                'class': 'form-select',
 | 
				
			||||||
| 
						 | 
					@ -119,6 +127,15 @@ class InstallationReportForm(forms.ModelForm):
 | 
				
			||||||
                'class': 'form-check-input',
 | 
					                'class': 'form-check-input',
 | 
				
			||||||
                'id': 'id_is_meter_suspicious',
 | 
					                'id': 'id_is_meter_suspicious',
 | 
				
			||||||
            }),
 | 
					            }),
 | 
				
			||||||
 | 
					            'is_panel_sealed': forms.CheckboxInput(attrs={
 | 
				
			||||||
 | 
					                'class': 'form-check-input',
 | 
				
			||||||
 | 
					            }),
 | 
				
			||||||
 | 
					            'is_panel_cut': forms.CheckboxInput(attrs={
 | 
				
			||||||
 | 
					                'class': 'form-check-input',
 | 
				
			||||||
 | 
					            }),
 | 
				
			||||||
 | 
					            'is_disconnection_done': forms.CheckboxInput(attrs={
 | 
				
			||||||
 | 
					                'class': 'form-check-input',
 | 
				
			||||||
 | 
					            }),
 | 
				
			||||||
            'description': forms.Textarea(attrs={
 | 
					            'description': forms.Textarea(attrs={
 | 
				
			||||||
                'class': 'form-control',
 | 
					                'class': 'form-control',
 | 
				
			||||||
                'rows': 3
 | 
					                'rows': 3
 | 
				
			||||||
| 
						 | 
					@ -137,12 +154,17 @@ class InstallationReportForm(forms.ModelForm):
 | 
				
			||||||
            'usage_type': 'نوع مصرف',
 | 
					            'usage_type': 'نوع مصرف',
 | 
				
			||||||
            'exploitation_license_number': 'شماره پروانه بهرهبرداری',
 | 
					            'exploitation_license_number': 'شماره پروانه بهرهبرداری',
 | 
				
			||||||
            'motor_power': 'قدرت موتور (کیلووات ساعت)',
 | 
					            'motor_power': 'قدرت موتور (کیلووات ساعت)',
 | 
				
			||||||
            'pre_calibration_flow_rate': 'دبی قبل از کالیبراسیون (لیتر بر ثانیه)',
 | 
					            'flow_rate': 'دبی (لیتر بر ثانیه)',
 | 
				
			||||||
            'post_calibration_flow_rate': 'دبی بعد از کالیبراسیون (لیتر بر ثانیه)',
 | 
					            'meter_reading': 'عدد کنتور (متر مکعب)',
 | 
				
			||||||
 | 
					            'meter_charge': 'شارژ کنتور (متر مکعب)',
 | 
				
			||||||
 | 
					            'meter_charge_expiration_date': 'تاریخ پایان اعتبار شارژ',
 | 
				
			||||||
            'water_meter_manufacturer': 'شرکت سازنده کنتور',
 | 
					            'water_meter_manufacturer': 'شرکت سازنده کنتور',
 | 
				
			||||||
            'sim_number': 'شماره سیمکارت',
 | 
					            'sim_number': 'شماره سیمکارت',
 | 
				
			||||||
            'driving_force': 'نیرو محرکه چاه',
 | 
					            'driving_force': 'نیرو محرکه چاه',
 | 
				
			||||||
            'is_meter_suspicious': 'کنتور مشکوک است',
 | 
					            'is_meter_suspicious': 'کنتور مشکوک است',
 | 
				
			||||||
 | 
					            'is_panel_sealed': 'پلمپ تابلو',
 | 
				
			||||||
 | 
					            'is_panel_cut': 'تابلو قطع',
 | 
				
			||||||
 | 
					            'is_disconnection_done': 'انجام عملیات قطع',
 | 
				
			||||||
            'description': 'توضیحات'
 | 
					            'description': 'توضیحات'
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,50 @@
 | 
				
			||||||
 | 
					# Generated by Django 5.2.4 on 2025-10-27 03:42
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import django.core.validators
 | 
				
			||||||
 | 
					from decimal import Decimal
 | 
				
			||||||
 | 
					from django.db import migrations, models
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Migration(migrations.Migration):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dependencies = [
 | 
				
			||||||
 | 
					        ('installations', '0011_alter_installationreport_discharge_pipe_diameter'),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    operations = [
 | 
				
			||||||
 | 
					        migrations.AddField(
 | 
				
			||||||
 | 
					            model_name='installationreport',
 | 
				
			||||||
 | 
					            name='flow_rate',
 | 
				
			||||||
 | 
					            field=models.DecimalField(blank=True, decimal_places=4, max_digits=10, null=True, verbose_name='(لیتر بر ثانیه)دبی'),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        migrations.AddField(
 | 
				
			||||||
 | 
					            model_name='installationreport',
 | 
				
			||||||
 | 
					            name='is_disconnection_done',
 | 
				
			||||||
 | 
					            field=models.BooleanField(default=False, verbose_name='انجام عملیات قطع'),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        migrations.AddField(
 | 
				
			||||||
 | 
					            model_name='installationreport',
 | 
				
			||||||
 | 
					            name='is_panel_cut',
 | 
				
			||||||
 | 
					            field=models.BooleanField(default=False, verbose_name='تابلو قطع'),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        migrations.AddField(
 | 
				
			||||||
 | 
					            model_name='installationreport',
 | 
				
			||||||
 | 
					            name='is_panel_sealed',
 | 
				
			||||||
 | 
					            field=models.BooleanField(default=False, verbose_name='پلمپ تابلو'),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        migrations.AddField(
 | 
				
			||||||
 | 
					            model_name='installationreport',
 | 
				
			||||||
 | 
					            name='meter_charge',
 | 
				
			||||||
 | 
					            field=models.DecimalField(blank=True, decimal_places=4, max_digits=10, null=True, validators=[django.core.validators.MinValueValidator(Decimal('0'))], verbose_name='شارژ کنتور (متر مکعب)'),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        migrations.AddField(
 | 
				
			||||||
 | 
					            model_name='installationreport',
 | 
				
			||||||
 | 
					            name='meter_charge_expiration_date',
 | 
				
			||||||
 | 
					            field=models.DateField(blank=True, null=True, verbose_name='تاریخ پایان اعتبار شارژ'),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        migrations.AddField(
 | 
				
			||||||
 | 
					            model_name='installationreport',
 | 
				
			||||||
 | 
					            name='meter_reading',
 | 
				
			||||||
 | 
					            field=models.DecimalField(blank=True, decimal_places=4, max_digits=10, null=True, validators=[django.core.validators.MinValueValidator(Decimal('0'))], verbose_name='عدد کنتور (متر مکعب)'),
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,21 @@
 | 
				
			||||||
 | 
					# Generated by Django 5.2.4 on 2025-10-27 03:47
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from django.db import migrations
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Migration(migrations.Migration):
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    dependencies = [
 | 
				
			||||||
 | 
					        ('installations', '0012_installationreport_flow_rate_and_more'),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    operations = [
 | 
				
			||||||
 | 
					        migrations.RemoveField(
 | 
				
			||||||
 | 
					            model_name='installationreport',
 | 
				
			||||||
 | 
					            name='post_calibration_flow_rate',
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					        migrations.RemoveField(
 | 
				
			||||||
 | 
					            model_name='installationreport',
 | 
				
			||||||
 | 
					            name='pre_calibration_flow_rate',
 | 
				
			||||||
 | 
					        ),
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
| 
						 | 
					@ -55,6 +55,12 @@ class InstallationReport(BaseModel):
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
    meter_model = models.CharField(max_length=20, choices=METER_MODEL_CHOICES, null=True, blank=True, verbose_name='مدل کنتور')
 | 
					    meter_model = models.CharField(max_length=20, choices=METER_MODEL_CHOICES, null=True, blank=True, verbose_name='مدل کنتور')
 | 
				
			||||||
    meter_size = models.CharField(max_length=50, null=True, blank=True, verbose_name='سایز کنتور')
 | 
					    meter_size = models.CharField(max_length=50, null=True, blank=True, verbose_name='سایز کنتور')
 | 
				
			||||||
 | 
					    meter_reading = models.DecimalField(max_digits=10, decimal_places=4, null=True, blank=True, validators=[MinValueValidator(Decimal('0'))], verbose_name='عدد کنتور (متر مکعب)')
 | 
				
			||||||
 | 
					    meter_charge = models.DecimalField(max_digits=10, decimal_places=4, null=True, blank=True, validators=[MinValueValidator(Decimal('0'))], verbose_name='شارژ کنتور (متر مکعب)')
 | 
				
			||||||
 | 
					    meter_charge_expiration_date = models.DateField(null=True, blank=True, verbose_name='تاریخ پایان اعتبار شارژ')
 | 
				
			||||||
 | 
					    is_panel_sealed = models.BooleanField(default=False, verbose_name='پلمپ تابلو')
 | 
				
			||||||
 | 
					    is_panel_cut = models.BooleanField(default=False, verbose_name='تابلو قطع')
 | 
				
			||||||
 | 
					    is_disconnection_done = models.BooleanField(default=False, verbose_name='انجام عملیات قطع')
 | 
				
			||||||
    discharge_pipe_diameter = models.DecimalField(max_digits=10, decimal_places=4, null=True, blank=True, verbose_name='قطر لوله آبده (اینچ)')
 | 
					    discharge_pipe_diameter = models.DecimalField(max_digits=10, decimal_places=4, null=True, blank=True, verbose_name='قطر لوله آبده (اینچ)')
 | 
				
			||||||
    USAGE_TYPE_CHOICES = [
 | 
					    USAGE_TYPE_CHOICES = [
 | 
				
			||||||
        ('domestic', 'شرب و خدمات'),
 | 
					        ('domestic', 'شرب و خدمات'),
 | 
				
			||||||
| 
						 | 
					@ -64,8 +70,7 @@ class InstallationReport(BaseModel):
 | 
				
			||||||
    usage_type = models.CharField(max_length=20, choices=USAGE_TYPE_CHOICES, null=True, verbose_name='نوع مصرف')
 | 
					    usage_type = models.CharField(max_length=20, choices=USAGE_TYPE_CHOICES, null=True, verbose_name='نوع مصرف')
 | 
				
			||||||
    exploitation_license_number = models.CharField(max_length=50, verbose_name='شماره پروانه بهرهبرداری چاه')
 | 
					    exploitation_license_number = models.CharField(max_length=50, verbose_name='شماره پروانه بهرهبرداری چاه')
 | 
				
			||||||
    motor_power = models.DecimalField(max_digits=10, decimal_places=4, null=True, blank=True, verbose_name='(کیلووات ساعت) قدرت موتور')
 | 
					    motor_power = models.DecimalField(max_digits=10, decimal_places=4, null=True, blank=True, verbose_name='(کیلووات ساعت) قدرت موتور')
 | 
				
			||||||
    pre_calibration_flow_rate = models.DecimalField(max_digits=10, decimal_places=4, null=True, blank=True, verbose_name='(لیتر بر ثانیه)دبی قبل از کالیبراسیون')
 | 
					    flow_rate = models.DecimalField(max_digits=10, decimal_places=4, null=True, blank=True, verbose_name='(لیتر بر ثانیه)دبی')
 | 
				
			||||||
    post_calibration_flow_rate = models.DecimalField(max_digits=10, decimal_places=4, null=True, blank=True, verbose_name='(لیتر بر ثانیه)دبی بعد از کالیبراسیون')
 | 
					 | 
				
			||||||
    water_meter_manufacturer = models.ForeignKey('wells.WaterMeterManufacturer', on_delete=models.SET_NULL, null=True, blank=True, verbose_name='شرکت سازنده کنتور آب')
 | 
					    water_meter_manufacturer = models.ForeignKey('wells.WaterMeterManufacturer', on_delete=models.SET_NULL, null=True, blank=True, verbose_name='شرکت سازنده کنتور آب')
 | 
				
			||||||
    sim_number = models.CharField(max_length=20, null=True, blank=True, verbose_name='شماره سیمکارت')
 | 
					    sim_number = models.CharField(max_length=20, null=True, blank=True, verbose_name='شماره سیمکارت')
 | 
				
			||||||
    driving_force = models.CharField(max_length=50, null=True, blank=True, verbose_name='نیرو محرکه چاه')
 | 
					    driving_force = models.CharField(max_length=50, null=True, blank=True, verbose_name='نیرو محرکه چاه')
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -156,8 +156,10 @@
 | 
				
			||||||
                  {% endif %}
 | 
					                  {% endif %}
 | 
				
			||||||
                  <p class="text-nowrap mb-2"><i class="bx bx-tachometer bx-sm me-2"></i>قطر لوله آبده (اینچ): {{ report.discharge_pipe_diameter|default:'-' }}</p>
 | 
					                  <p class="text-nowrap mb-2"><i class="bx bx-tachometer bx-sm me-2"></i>قطر لوله آبده (اینچ): {{ report.discharge_pipe_diameter|default:'-' }}</p>
 | 
				
			||||||
                  <p class="text-nowrap mb-2"><i class="bx bx-building bx-sm me-2"></i>سازنده کنتور: {{ report.water_meter_manufacturer|default:'-' }}</p>
 | 
					                  <p class="text-nowrap mb-2"><i class="bx bx-building bx-sm me-2"></i>سازنده کنتور: {{ report.water_meter_manufacturer|default:'-' }}</p>
 | 
				
			||||||
                  <p class="text-nowrap mb-2"><i class="bx bx-sim-card bx-sm me-2"></i>شماره سیمکارت: {{ report.sim_number|default:'-' }}</p>
 | 
					                  <p class="text-nowrap mb-2"><i class="bx bx-mobile bx-sm me-2"></i>شماره سیمکارت: {{ report.sim_number|default:'-' }}</p>
 | 
				
			||||||
                  <p class="text-nowrap mb-2"><i class="bx bx-cog bx-sm me-2"></i>نیرو محرکه چاه: {{ report.driving_force|default:'-' }}</p>
 | 
					                  <p class="text-nowrap mb-2"><i class="bx bx-cog bx-sm me-2"></i>نیرو محرکه چاه: {{ report.driving_force|default:'-' }}</p>
 | 
				
			||||||
 | 
					                  <p class="text-nowrap mb-2"><i class="bx bx-battery bx-sm me-2"></i>شارژ کنتور (متر مکعب): {{ report.meter_charge|default:'-' }}</p>
 | 
				
			||||||
 | 
					                  <p class="text-nowrap mb-2"><i class="bx bx-calendar-exclamation bx-sm me-2"></i>پایان اعتبار شارژ: {{ report.meter_charge_expiration_date|to_jalali|default:'-' }}</p>
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
                <div class="col-md-6">
 | 
					                <div class="col-md-6">
 | 
				
			||||||
                  <p class="text-nowrap mb-2"><i class="bx bx-help-circle bx-sm me-2"></i>کنتور مشکوک: {{ report.is_meter_suspicious|yesno:'بله,خیر' }}</p>
 | 
					                  <p class="text-nowrap mb-2"><i class="bx bx-help-circle bx-sm me-2"></i>کنتور مشکوک: {{ report.is_meter_suspicious|yesno:'بله,خیر' }}</p>
 | 
				
			||||||
| 
						 | 
					@ -166,8 +168,11 @@
 | 
				
			||||||
                  <p class="text-nowrap mb-2"><i class="bx bx-category bx-sm me-2"></i>نوع مصرف: {{ report.get_usage_type_display|default:'-' }}</p>
 | 
					                  <p class="text-nowrap mb-2"><i class="bx bx-category bx-sm me-2"></i>نوع مصرف: {{ report.get_usage_type_display|default:'-' }}</p>
 | 
				
			||||||
                  <p class="text-nowrap mb-2"><i class="bx bx-id-card bx-sm me-2"></i>شماره پروانه بهرهبرداری: {{ report.exploitation_license_number|default:'-' }}</p>
 | 
					                  <p class="text-nowrap mb-2"><i class="bx bx-id-card bx-sm me-2"></i>شماره پروانه بهرهبرداری: {{ report.exploitation_license_number|default:'-' }}</p>
 | 
				
			||||||
                  <p class="text-nowrap mb-2"><i class="bx bx-bolt-circle bx-sm me-2"></i>قدرت موتور (کیلووات ساعت): {{ report.motor_power|default:'-' }}</p>
 | 
					                  <p class="text-nowrap mb-2"><i class="bx bx-bolt-circle bx-sm me-2"></i>قدرت موتور (کیلووات ساعت): {{ report.motor_power|default:'-' }}</p>
 | 
				
			||||||
                  <p class="text-nowrap mb-2"><i class="bx bx-water bx-sm me-2"></i>دبی قبل کالیبراسیون(لیتر/ثانیه): {{ report.pre_calibration_flow_rate|default:'-' }}</p>
 | 
					                  <p class="text-nowrap mb-2"><i class="bx bx-water bx-sm me-2"></i>دبی (لیتر/ثانیه): {{ report.flow_rate|default:'-' }}</p>
 | 
				
			||||||
                  <p class="text-nowrap mb-2"><i class="bx bx-water bx-sm me-2"></i>دبی بعد کالیبراسیون(لیتر/ثانیه): {{ report.post_calibration_flow_rate|default:'-' }}</p>
 | 
					                  <p class="text-nowrap mb-2"><i class="bx bx-pen bx-sm me-2"></i>عدد کنتور (متر مکعب): {{ report.meter_reading|default:'-' }}</p>
 | 
				
			||||||
 | 
					                  <p class="text-nowrap mb-2"><i class="bx bx-lock-open-alt bx-sm me-2"></i>پلمپ تابلو: {{ report.is_panel_sealed|yesno:'بله,خیر' }}</p>
 | 
				
			||||||
 | 
					                  <p class="text-nowrap mb-2"><i class="bx bx-power-off bx-sm me-2"></i>تابلو قطع: {{ report.is_panel_cut|yesno:'بله,خیر' }}</p>
 | 
				
			||||||
 | 
					                  <p class="text-nowrap mb-2"><i class="bx bx-cut bx-sm me-2"></i>انجام عملیات قطع: {{ report.is_disconnection_done|yesno:'بله,خیر' }}</p>
 | 
				
			||||||
                  
 | 
					                  
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
              </div>
 | 
					              </div>
 | 
				
			||||||
| 
						 | 
					@ -389,17 +394,32 @@
 | 
				
			||||||
                    {% endif %}
 | 
					                    {% endif %}
 | 
				
			||||||
                  </div>
 | 
					                  </div>
 | 
				
			||||||
                  <div class="col-md-3">
 | 
					                  <div class="col-md-3">
 | 
				
			||||||
                    {{ form.pre_calibration_flow_rate.label_tag }}
 | 
					                    {{ form.flow_rate.label_tag }}
 | 
				
			||||||
                    {{ form.pre_calibration_flow_rate }}
 | 
					                    {{ form.flow_rate }}
 | 
				
			||||||
                    {% if form.pre_calibration_flow_rate.errors %}
 | 
					                    {% if form.flow_rate.errors %}
 | 
				
			||||||
                      <div class="invalid-feedback">{{ form.pre_calibration_flow_rate.errors.0 }}</div>
 | 
					                      <div class="invalid-feedback">{{ form.flow_rate.errors.0 }}</div>
 | 
				
			||||||
                    {% endif %}
 | 
					                    {% endif %}
 | 
				
			||||||
                  </div>
 | 
					                  </div>
 | 
				
			||||||
                  <div class="col-md-3">
 | 
					                  <div class="col-md-3">
 | 
				
			||||||
                    {{ form.post_calibration_flow_rate.label_tag }}
 | 
					                    {{ form.meter_reading.label_tag }}
 | 
				
			||||||
                    {{ form.post_calibration_flow_rate }}
 | 
					                    {{ form.meter_reading }}
 | 
				
			||||||
                    {% if form.post_calibration_flow_rate.errors %}
 | 
					                    {% if form.meter_reading.errors %}
 | 
				
			||||||
                      <div class="invalid-feedback">{{ form.post_calibration_flow_rate.errors.0 }}</div>
 | 
					                      <div class="invalid-feedback">{{ form.meter_reading.errors.0 }}</div>
 | 
				
			||||||
 | 
					                    {% endif %}
 | 
				
			||||||
 | 
					                  </div>
 | 
				
			||||||
 | 
					                  <div class="col-md-3">
 | 
				
			||||||
 | 
					                    {{ form.meter_charge.label_tag }}
 | 
				
			||||||
 | 
					                    {{ form.meter_charge }}
 | 
				
			||||||
 | 
					                    {% if form.meter_charge.errors %}
 | 
				
			||||||
 | 
					                      <div class="invalid-feedback">{{ form.meter_charge.errors.0 }}</div>
 | 
				
			||||||
 | 
					                    {% endif %}
 | 
				
			||||||
 | 
					                  </div>
 | 
				
			||||||
 | 
					                  <div class="col-md-3">
 | 
				
			||||||
 | 
					                    {{ form.meter_charge_expiration_date.label_tag }}
 | 
				
			||||||
 | 
					                    <input type="text" id="id_meter_charge_expiration_date_display" class="form-control{% if form.meter_charge_expiration_date.errors %} is-invalid{% endif %}" placeholder="انتخاب تاریخ" {% if not user_is_installer %}disabled{% endif %} readonly value="{% if report and edit_mode and report.meter_charge_expiration_date %}{{ report.meter_charge_expiration_date|date:'Y/m/d' }}{% elif form.meter_charge_expiration_date.value %}{{ form.meter_charge_expiration_date.value|date:'Y/m/d' }}{% endif %}">
 | 
				
			||||||
 | 
					                    <input type="hidden" id="id_meter_charge_expiration_date" name="meter_charge_expiration_date" value="{% if report and edit_mode and report.meter_charge_expiration_date %}{{ report.meter_charge_expiration_date|date:'Y-m-d' }}{% elif form.meter_charge_expiration_date.value %}{{ form.meter_charge_expiration_date.value }}{% endif %}">
 | 
				
			||||||
 | 
					                    {% if form.meter_charge_expiration_date.errors %}
 | 
				
			||||||
 | 
					                      <div class="invalid-feedback">{{ form.meter_charge_expiration_date.errors.0 }}</div>
 | 
				
			||||||
                    {% endif %}
 | 
					                    {% endif %}
 | 
				
			||||||
                  </div>
 | 
					                  </div>
 | 
				
			||||||
                  <div class="col-md-3">
 | 
					                  <div class="col-md-3">
 | 
				
			||||||
| 
						 | 
					@ -432,6 +452,7 @@
 | 
				
			||||||
                      <div class="invalid-feedback">{{ form.driving_force.errors.0 }}</div>
 | 
					                      <div class="invalid-feedback">{{ form.driving_force.errors.0 }}</div>
 | 
				
			||||||
                    {% endif %}
 | 
					                    {% endif %}
 | 
				
			||||||
                  </div>
 | 
					                  </div>
 | 
				
			||||||
 | 
					                  <div class="row mt-3">
 | 
				
			||||||
                    <div class="col-md-3 d-flex align-items-end">
 | 
					                    <div class="col-md-3 d-flex align-items-end">
 | 
				
			||||||
                      <div class="form-check">
 | 
					                      <div class="form-check">
 | 
				
			||||||
                        {{ form.is_meter_suspicious }}
 | 
					                        {{ form.is_meter_suspicious }}
 | 
				
			||||||
| 
						 | 
					@ -441,6 +462,34 @@
 | 
				
			||||||
                        <div class="invalid-feedback">{{ form.is_meter_suspicious.errors.0 }}</div>
 | 
					                        <div class="invalid-feedback">{{ form.is_meter_suspicious.errors.0 }}</div>
 | 
				
			||||||
                      {% endif %}
 | 
					                      {% endif %}
 | 
				
			||||||
                    </div>
 | 
					                    </div>
 | 
				
			||||||
 | 
					                    <div class="col-md-3 d-flex align-items-end">
 | 
				
			||||||
 | 
					                      <div class="form-check">
 | 
				
			||||||
 | 
					                        {{ form.is_panel_sealed }}
 | 
				
			||||||
 | 
					                        {{ form.is_panel_sealed.label_tag }}
 | 
				
			||||||
 | 
					                      </div>
 | 
				
			||||||
 | 
					                      {% if form.is_panel_sealed.errors %}
 | 
				
			||||||
 | 
					                        <div class="invalid-feedback">{{ form.is_panel_sealed.errors.0 }}</div>
 | 
				
			||||||
 | 
					                      {% endif %}
 | 
				
			||||||
 | 
					                    </div>
 | 
				
			||||||
 | 
					                    <div class="col-md-3 d-flex align-items-end">
 | 
				
			||||||
 | 
					                      <div class="form-check">
 | 
				
			||||||
 | 
					                        {{ form.is_panel_cut }}
 | 
				
			||||||
 | 
					                        {{ form.is_panel_cut.label_tag }}
 | 
				
			||||||
 | 
					                      </div>
 | 
				
			||||||
 | 
					                      {% if form.is_panel_cut.errors %}
 | 
				
			||||||
 | 
					                        <div class="invalid-feedback">{{ form.is_panel_cut.errors.0 }}</div>
 | 
				
			||||||
 | 
					                      {% endif %}
 | 
				
			||||||
 | 
					                    </div>
 | 
				
			||||||
 | 
					                    <div class="col-md-3 d-flex align-items-end">
 | 
				
			||||||
 | 
					                      <div class="form-check">
 | 
				
			||||||
 | 
					                        {{ form.is_disconnection_done }}
 | 
				
			||||||
 | 
					                        {{ form.is_disconnection_done.label_tag }}
 | 
				
			||||||
 | 
					                      </div>
 | 
				
			||||||
 | 
					                      {% if form.is_disconnection_done.errors %}
 | 
				
			||||||
 | 
					                        <div class="invalid-feedback">{{ form.is_disconnection_done.errors.0 }}</div>
 | 
				
			||||||
 | 
					                      {% endif %}
 | 
				
			||||||
 | 
					                    </div>
 | 
				
			||||||
 | 
					                  </div>
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
                <div class="my-3">
 | 
					                <div class="my-3">
 | 
				
			||||||
                  {{ form.description.label_tag }}
 | 
					                  {{ form.description.label_tag }}
 | 
				
			||||||
| 
						 | 
					@ -653,7 +702,7 @@
 | 
				
			||||||
<script src="https://unpkg.com/persian-date@latest/dist/persian-date.min.js"></script>
 | 
					<script src="https://unpkg.com/persian-date@latest/dist/persian-date.min.js"></script>
 | 
				
			||||||
<script src="https://unpkg.com/persian-datepicker@latest/dist/js/persian-datepicker.min.js"></script>
 | 
					<script src="https://unpkg.com/persian-datepicker@latest/dist/js/persian-datepicker.min.js"></script>
 | 
				
			||||||
<script>
 | 
					<script>
 | 
				
			||||||
  // Persian datepicker for visited_date (exact pattern like sample: display + altField)
 | 
					  // Persian datepicker helper for date fields (DRY)
 | 
				
			||||||
  (function(){
 | 
					  (function(){
 | 
				
			||||||
    function convertPersianToEnglishNumbers(str) {
 | 
					    function convertPersianToEnglishNumbers(str) {
 | 
				
			||||||
      const persianNumbers = '۰۱۲۳۴۵۶۷۸۹';
 | 
					      const persianNumbers = '۰۱۲۳۴۵۶۷۸۹';
 | 
				
			||||||
| 
						 | 
					@ -664,12 +713,12 @@
 | 
				
			||||||
      }).join('');
 | 
					      }).join('');
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (window.$ && $.fn.persianDatepicker && $('#id_visited_date_display').length) {
 | 
					    function initPersianDateField(displaySelector, hiddenSelector){
 | 
				
			||||||
 | 
					      if (!(window.$ && $.fn.persianDatepicker)) return;
 | 
				
			||||||
 | 
					      var $display = $(displaySelector);
 | 
				
			||||||
 | 
					      var $hidden = $(hiddenSelector);
 | 
				
			||||||
 | 
					      if (!$display.length || !$hidden.length) return;
 | 
				
			||||||
      try {
 | 
					      try {
 | 
				
			||||||
        var $display = $('#id_visited_date_display');
 | 
					 | 
				
			||||||
        var $hidden = $('#id_visited_date');
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        // Prefill from hidden Gregorian to visible Jalali
 | 
					 | 
				
			||||||
        var initialGregorian = $hidden.val();
 | 
					        var initialGregorian = $hidden.val();
 | 
				
			||||||
        if (initialGregorian) {
 | 
					        if (initialGregorian) {
 | 
				
			||||||
          try {
 | 
					          try {
 | 
				
			||||||
| 
						 | 
					@ -678,10 +727,9 @@
 | 
				
			||||||
          } catch (e) {}
 | 
					          } catch (e) {}
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // Initialize datepicker with altField exactly like the sample
 | 
					        $display.persianDatepicker({
 | 
				
			||||||
        var picker = $display.persianDatepicker({
 | 
					 | 
				
			||||||
          calendarType: 'persian',
 | 
					          calendarType: 'persian',
 | 
				
			||||||
          altField: '#id_visited_date',
 | 
					          altField: hiddenSelector,
 | 
				
			||||||
          format: 'YYYY/MM/DD',
 | 
					          format: 'YYYY/MM/DD',
 | 
				
			||||||
          altFormat: 'YYYY-MM-DD',
 | 
					          altFormat: 'YYYY-MM-DD',
 | 
				
			||||||
          observer: true,
 | 
					          observer: true,
 | 
				
			||||||
| 
						 | 
					@ -694,8 +742,12 @@
 | 
				
			||||||
            $hidden.val(g);
 | 
					            $hidden.val(g);
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        });
 | 
					        });
 | 
				
			||||||
      } catch (e) { console.error('Error initializing Persian Date Picker:', e); }
 | 
					      } catch (e) { console.error('Error initializing Persian Date Picker:', displaySelector, e); }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Initialize both fields
 | 
				
			||||||
 | 
					    initPersianDateField('#id_visited_date_display', '#id_visited_date');
 | 
				
			||||||
 | 
					    initPersianDateField('#id_meter_charge_expiration_date_display', '#id_meter_charge_expiration_date');
 | 
				
			||||||
  })();
 | 
					  })();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  // Require date and show success toast on submit (persist across redirect)
 | 
					  // Require date and show success toast on submit (persist across redirect)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -23,7 +23,7 @@ def installation_assign_step(request, instance_id, step_id):
 | 
				
			||||||
    next_step = instance.process.steps.filter(order__gt=step.order).first()
 | 
					    next_step = instance.process.steps.filter(order__gt=step.order).first()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Installers list (profiles that have installer role)
 | 
					    # Installers list (profiles that have installer role)
 | 
				
			||||||
    installers = Profile.objects.filter(roles__slug=UserRoles.INSTALLER.value, county=instance.well.county).select_related('user').all()
 | 
					    installers = Profile.objects.filter(roles__slug=UserRoles.INSTALLER.value, county__city=instance.well.county.city).select_related('user').all()
 | 
				
			||||||
    assignment, _ = InstallationAssignment.objects.get_or_create(process_instance=instance)
 | 
					    assignment, _ = InstallationAssignment.objects.get_or_create(process_instance=instance)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # Role flags
 | 
					    # Role flags
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										14
									
								
								liara.json
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								liara.json
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,14 @@
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  "app": "meterplus",
 | 
				
			||||||
 | 
					  "port": 80,
 | 
				
			||||||
 | 
					  "team-id": "68822f40f04e5bc3027fc2b7",
 | 
				
			||||||
 | 
					  "build": {
 | 
				
			||||||
 | 
					    "location": "iran"
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "disks": [
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      "name": "media",
 | 
				
			||||||
 | 
					      "mountTo": "/usr/src/app/media"
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  ]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -143,12 +143,16 @@
 | 
				
			||||||
                  <div class="col-12 col-md-4">
 | 
					                  <div class="col-12 col-md-4">
 | 
				
			||||||
                    <p class="text-nowrap mb-2"><i class="bx bx-category bx-sm me-2"></i>نوع کنتور: {{ latest_report.get_meter_type_display }}</p>
 | 
					                    <p class="text-nowrap mb-2"><i class="bx bx-category bx-sm me-2"></i>نوع کنتور: {{ latest_report.get_meter_type_display }}</p>
 | 
				
			||||||
                  </div>
 | 
					                  </div>
 | 
				
			||||||
                  {% endif %}
 | 
					                  {% if latest_report.meter_type == 'smart' %}
 | 
				
			||||||
                  {% if latest_report.meter_size %}
 | 
					                  <div class="col-12 col-md-4">
 | 
				
			||||||
 | 
					                    <p class="text-nowrap mb-2"><i class="bx bx-chip bx-sm me-2"></i>مدل کنتور: {{ latest_report.get_meter_model_display|default:'-' }}</p>
 | 
				
			||||||
 | 
					                  </div>
 | 
				
			||||||
 | 
					                  {% else %}
 | 
				
			||||||
                  <div class="col-12 col-md-4">
 | 
					                  <div class="col-12 col-md-4">
 | 
				
			||||||
                    <p class="text-nowrap mb-2"><i class="bx bx-ruler bx-sm me-2"></i>سایز کنتور: {{ latest_report.meter_size }}</p>
 | 
					                    <p class="text-nowrap mb-2"><i class="bx bx-ruler bx-sm me-2"></i>سایز کنتور: {{ latest_report.meter_size }}</p>
 | 
				
			||||||
                  </div>
 | 
					                  </div>
 | 
				
			||||||
                  {% endif %}
 | 
					                  {% endif %}
 | 
				
			||||||
 | 
					                  {% endif %}
 | 
				
			||||||
                  {% if latest_report.water_meter_manufacturer %}
 | 
					                  {% if latest_report.water_meter_manufacturer %}
 | 
				
			||||||
                  <div class="col-12 col-md-4">
 | 
					                  <div class="col-12 col-md-4">
 | 
				
			||||||
                    <p class="text-nowrap mb-2"><i class="bx bx-buildings bx-sm me-2"></i>سازنده: {{ latest_report.water_meter_manufacturer.name }}</p>
 | 
					                    <p class="text-nowrap mb-2"><i class="bx bx-buildings bx-sm me-2"></i>سازنده: {{ latest_report.water_meter_manufacturer.name }}</p>
 | 
				
			||||||
| 
						 | 
					@ -179,16 +183,35 @@
 | 
				
			||||||
                    <p class="text-nowrap mb-2"><i class="bx bx-id-card bx-sm me-2"></i>شماره پروانه: {{ latest_report.exploitation_license_number }}</p>
 | 
					                    <p class="text-nowrap mb-2"><i class="bx bx-id-card bx-sm me-2"></i>شماره پروانه: {{ latest_report.exploitation_license_number }}</p>
 | 
				
			||||||
                  </div>
 | 
					                  </div>
 | 
				
			||||||
                  {% endif %}
 | 
					                  {% endif %}
 | 
				
			||||||
                  {% if latest_report.pre_calibration_flow_rate %}
 | 
					                  {% if latest_report.flow_rate %}
 | 
				
			||||||
                  <div class="col-12 col-md-4">
 | 
					                  <div class="col-12 col-md-4">
 | 
				
			||||||
                    <p class="text-nowrap mb-2"><i class="bx bx-water bx-sm me-2"></i>دبی قبل از کالیبراسیون: {{ latest_report.pre_calibration_flow_rate }} لیتر/ثانیه</p>
 | 
					                    <p class="text-nowrap mb-2"><i class="bx bx-water bx-sm me-2"></i>دبی: {{ latest_report.flow_rate }} لیتر/ثانیه</p>
 | 
				
			||||||
                  </div>
 | 
					                  </div>
 | 
				
			||||||
                  {% endif %}
 | 
					                  {% endif %}
 | 
				
			||||||
                  {% if latest_report.post_calibration_flow_rate %}
 | 
					                  {% if latest_report.meter_reading %}
 | 
				
			||||||
                  <div class="col-12 col-md-4">
 | 
					                  <div class="col-12 col-md-4">
 | 
				
			||||||
                    <p class="text-nowrap mb-2"><i class="bx bx-tachometer bx-sm me-2"></i>دبی بعد از کالیبراسیون: {{ latest_report.post_calibration_flow_rate }} لیتر/ثانیه</p>
 | 
					                    <p class="text-nowrap mb-2"><i class="bx bx-pen bx-sm me-2"></i>عدد کنتور: {{ latest_report.meter_reading }} متر مکعب</p>
 | 
				
			||||||
                  </div>
 | 
					                  </div>
 | 
				
			||||||
                  {% endif %}
 | 
					                  {% endif %}
 | 
				
			||||||
 | 
					                  {% if latest_report.meter_charge %}
 | 
				
			||||||
 | 
					                  <div class="col-12 col-md-4">
 | 
				
			||||||
 | 
					                    <p class="text-nowrap mb-2"><i class="bx bx-battery bx-sm me-2"></i>شارژ کنتور: {{ latest_report.meter_charge }} متر مکعب</p>
 | 
				
			||||||
 | 
					                  </div>
 | 
				
			||||||
 | 
					                  {% endif %}
 | 
				
			||||||
 | 
					                  {% if latest_report.meter_charge_expiration_date %}
 | 
				
			||||||
 | 
					                  <div class="col-12 col-md-4">
 | 
				
			||||||
 | 
					                    <p class="text-nowrap mb-2"><i class="bx bx-calendar-exclamation bx-sm me-2"></i>پایان اعتبار شارژ: {{ latest_report.meter_charge_expiration_date|to_jalali }}</p>
 | 
				
			||||||
 | 
					                  </div>
 | 
				
			||||||
 | 
					                  {% endif %}
 | 
				
			||||||
 | 
					                  <div class="col-12 col-md-4">
 | 
				
			||||||
 | 
					                    <p class="text-nowrap mb-2"><i class="bx bx-lock-open-alt bx-sm me-2"></i>پلمپ تابلو: {{ latest_report.is_panel_sealed|yesno:'دارد,ندارد' }}</p>
 | 
				
			||||||
 | 
					                  </div>
 | 
				
			||||||
 | 
					                  <div class="col-12 col-md-4">
 | 
				
			||||||
 | 
					                    <p class="text-nowrap mb-2"><i class="bx bx-power-off bx-sm me-2"></i>تابلو قطع: {{ latest_report.is_panel_cut|yesno:'دارد,ندارد' }}</p>
 | 
				
			||||||
 | 
					                  </div>
 | 
				
			||||||
 | 
					                  <div class="col-12 col-md-4">
 | 
				
			||||||
 | 
					                    <p class="text-nowrap mb-2"><i class="bx bx-cut bx-sm me-2"></i>انجام عملیات قطع: {{ latest_report.is_disconnection_done|yesno:'دارد,ندارد' }}</p>
 | 
				
			||||||
 | 
					                  </div>
 | 
				
			||||||
                  <div class="col-12 col-md-4">
 | 
					                  <div class="col-12 col-md-4">
 | 
				
			||||||
                    <p class="text-nowrap mb-2"><i class="bx bx-map bx-sm me-2"></i>UTM X: {{ latest_report.utm_x|default:'-' }}</p>
 | 
					                    <p class="text-nowrap mb-2"><i class="bx bx-map bx-sm me-2"></i>UTM X: {{ latest_report.utm_x|default:'-' }}</p>
 | 
				
			||||||
                  </div>
 | 
					                  </div>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -21,7 +21,7 @@ def scope_instances_queryset(user, queryset=None):
 | 
				
			||||||
        if profile.has_role(UserRoles.BROKER):
 | 
					        if profile.has_role(UserRoles.BROKER):
 | 
				
			||||||
            return qs.filter(broker=profile.broker)
 | 
					            return qs.filter(broker=profile.broker)
 | 
				
			||||||
        if profile.has_role(UserRoles.ACCOUNTANT) or profile.has_role(UserRoles.MANAGER) or profile.has_role(UserRoles.WATER_RESOURCE_MANAGER):
 | 
					        if profile.has_role(UserRoles.ACCOUNTANT) or profile.has_role(UserRoles.MANAGER) or profile.has_role(UserRoles.WATER_RESOURCE_MANAGER):
 | 
				
			||||||
            return qs.filter(broker__affairs__county=profile.county)
 | 
					            return qs.filter(broker__affairs__county__city=profile.county.city)
 | 
				
			||||||
        if profile.has_role(UserRoles.ADMIN):
 | 
					        if profile.has_role(UserRoles.ADMIN):
 | 
				
			||||||
            return qs
 | 
					            return qs
 | 
				
			||||||
        # if profile.has_role(UserRoles.WATER_RESOURCE_MANAGER) or profile.has_role(UserRoles.HEADQUARTER):
 | 
					        # if profile.has_role(UserRoles.WATER_RESOURCE_MANAGER) or profile.has_role(UserRoles.HEADQUARTER):
 | 
				
			||||||
| 
						 | 
					@ -70,7 +70,7 @@ def scope_wells_queryset(user, queryset=None):
 | 
				
			||||||
        if profile.has_role(UserRoles.BROKER):
 | 
					        if profile.has_role(UserRoles.BROKER):
 | 
				
			||||||
            return qs.filter(broker=profile.broker)
 | 
					            return qs.filter(broker=profile.broker)
 | 
				
			||||||
        if profile.has_role(UserRoles.ACCOUNTANT) or profile.has_role(UserRoles.MANAGER) or profile.has_role(UserRoles.WATER_RESOURCE_MANAGER):
 | 
					        if profile.has_role(UserRoles.ACCOUNTANT) or profile.has_role(UserRoles.MANAGER) or profile.has_role(UserRoles.WATER_RESOURCE_MANAGER):
 | 
				
			||||||
            return qs.filter(broker__affairs__county=profile.county)
 | 
					            return qs.filter(broker__affairs__county__city=profile.county.city)
 | 
				
			||||||
        if profile.has_role(UserRoles.INSTALLER):
 | 
					        if profile.has_role(UserRoles.INSTALLER):
 | 
				
			||||||
            # Wells that have instances assigned to this installer
 | 
					            # Wells that have instances assigned to this installer
 | 
				
			||||||
            from installations.models import InstallationAssignment
 | 
					            from installations.models import InstallationAssignment
 | 
				
			||||||
| 
						 | 
					@ -103,7 +103,7 @@ def scope_customers_queryset(user, queryset=None):
 | 
				
			||||||
        if profile.has_role(UserRoles.BROKER):
 | 
					        if profile.has_role(UserRoles.BROKER):
 | 
				
			||||||
            return qs.filter(broker=profile.broker)
 | 
					            return qs.filter(broker=profile.broker)
 | 
				
			||||||
        if profile.has_role(UserRoles.ACCOUNTANT) or profile.has_role(UserRoles.MANAGER) or profile.has_role(UserRoles.WATER_RESOURCE_MANAGER):
 | 
					        if profile.has_role(UserRoles.ACCOUNTANT) or profile.has_role(UserRoles.MANAGER) or profile.has_role(UserRoles.WATER_RESOURCE_MANAGER):
 | 
				
			||||||
            return qs.filter(county=profile.county)
 | 
					            return qs.filter(county__city=profile.county.city)
 | 
				
			||||||
        if profile.has_role(UserRoles.INSTALLER):
 | 
					        if profile.has_role(UserRoles.INSTALLER):
 | 
				
			||||||
            # Customers that are representatives of instances assigned to this installer
 | 
					            # Customers that are representatives of instances assigned to this installer
 | 
				
			||||||
            from installations.models import InstallationAssignment
 | 
					            from installations.models import InstallationAssignment
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -45,6 +45,9 @@ def request_list(request):
 | 
				
			||||||
    status_q = (request.GET.get('status') or '').strip()
 | 
					    status_q = (request.GET.get('status') or '').strip()
 | 
				
			||||||
    affairs_q = (request.GET.get('affairs') or '').strip()
 | 
					    affairs_q = (request.GET.get('affairs') or '').strip()
 | 
				
			||||||
    broker_q = (request.GET.get('broker') or '').strip()
 | 
					    broker_q = (request.GET.get('broker') or '').strip()
 | 
				
			||||||
 | 
					    if request.user.profile.roles.filter(slug='inst'):
 | 
				
			||||||
 | 
					        step_q = (request.GET.get('step') or '6').strip()
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
        step_q = (request.GET.get('step') or '').strip()
 | 
					        step_q = (request.GET.get('step') or '').strip()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if status_q:
 | 
					    if status_q:
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										15
									
								
								requirements.txt
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								requirements.txt
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,15 @@
 | 
				
			||||||
 | 
					asgiref==3.9.1
 | 
				
			||||||
 | 
					dj-database-url==3.0.1
 | 
				
			||||||
 | 
					Django==5.2.5
 | 
				
			||||||
 | 
					django-extensions==4.1
 | 
				
			||||||
 | 
					django-jazzmin==3.0.1
 | 
				
			||||||
 | 
					django-simple-history==3.10.1
 | 
				
			||||||
 | 
					et_xmlfile==2.0.0
 | 
				
			||||||
 | 
					openpyxl==3.1.5
 | 
				
			||||||
 | 
					pillow==11.3.0
 | 
				
			||||||
 | 
					psycopg2==2.9.10
 | 
				
			||||||
 | 
					psycopg2-binary==2.9.10
 | 
				
			||||||
 | 
					python-decouple==3.8
 | 
				
			||||||
 | 
					sqlparse==0.5.3
 | 
				
			||||||
 | 
					typing_extensions==4.15.0
 | 
				
			||||||
 | 
					utm==0.8.1
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue