Compare commits
43 Commits
d7a58053f5
...
master
Author | SHA1 | Date | |
---|---|---|---|
4663b4c026 | |||
1a581420fa | |||
ac39be54cc | |||
7a74048f57 | |||
18d7c8e56a | |||
330515d8c4 | |||
95a0c7e842 | |||
d4fd598923 | |||
36f5d7a77f | |||
ba2c1e3b0f | |||
07ac60e228 | |||
bfc50aba46 | |||
a188d48c89 | |||
7540f4f18a | |||
5dcec4dfc6 | |||
e601ed70c2 | |||
4998290549 | |||
8d479aa6b3 | |||
9d4f8df207 | |||
c79a6068e9 | |||
a49f192125 | |||
ddbc36b8aa | |||
a321a69336 | |||
5100c8b922 | |||
12176aabf4 | |||
66a2aab6b7 | |||
2cd502caa5 | |||
65f3d73a47 | |||
7c4ca62a2d | |||
de2e200551 | |||
c3671d0cae | |||
a7f5635440 | |||
b048ef44c5 | |||
ed6879b7f1 | |||
485307b78e | |||
1edae44647 | |||
832a8ca880 | |||
67320359fe | |||
aa3342946f | |||
5d9b7a71d7 | |||
e761864c3e | |||
2fa124f529 | |||
5ebba78346 |
2
.gitignore
vendored
2
.gitignore
vendored
@ -5,3 +5,5 @@ test
|
|||||||
*.mo
|
*.mo
|
||||||
db.sqlite3
|
db.sqlite3
|
||||||
.env
|
.env
|
||||||
|
doc/_build/
|
||||||
|
doc/output/
|
||||||
|
@ -1,3 +1,8 @@
|
|||||||
# poli_planning
|
Het 1,5 meter ziekenhuis
|
||||||
|
========================
|
||||||
|
|
||||||
Poliklinieken planning vanwege 1,5 meter afstand (Corona virus)
|
Ziekenhuizen in Nederland zijn volop bezig met het hervatten van de reguliere zorg. Uitgestelde afspraken en nieuwe afspraken worden weer ingepland. De veiligheid van patiënten staat daarbij voorop. Patiënten moeten ook in een ziekenhuis onderling een afstand van 1,5 meter aanhouden in deze tijd van COVID-19. Dus in de wachtkamer moet er minimaal 1,5 meter ruimte tussen stoelen zijn. En een patiënt die naar een lege stoel loopt, mag ook lopend niet te dicht in de buurt komen van andere patiënten. Er kunnen daardoor veel minder patiënten tegelijk in een wachtkamer op hun afspraak wachten. Bijvoorbeeld een wachtkamer die vroeger 22 zitplaatsen had, heeft nu misschien nog maar 6 of 7 zitplaatsen. Het weghalen van stoelen uit de wachtkamer is meestal nog wel redelijk eenvoudig te regelen. Maar hoe kan het aantal wachtende patiënten worden beperkt?
|
||||||
|
|
||||||
|
https://www.rug.nl/cope/projecten/het-anderhalve-meter-ziekenhuis/
|
||||||
|
|
||||||
|
See the <a href="poli_planning/src/branch/master/doc">doc</a> for more information.
|
20
doc/Makefile
Normal file
20
doc/Makefile
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
# Minimal makefile for Sphinx documentation
|
||||||
|
#
|
||||||
|
|
||||||
|
# You can set these variables from the command line, and also
|
||||||
|
# from the environment for the first two.
|
||||||
|
SPHINXOPTS ?=
|
||||||
|
SPHINXBUILD ?= sphinx-build
|
||||||
|
SOURCEDIR = .
|
||||||
|
BUILDDIR = output
|
||||||
|
|
||||||
|
# Put it first so that "make" without argument is like "make help".
|
||||||
|
help:
|
||||||
|
@$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
||||||
|
|
||||||
|
.PHONY: help Makefile
|
||||||
|
|
||||||
|
# Catch-all target: route all unknown targets to Sphinx using the new
|
||||||
|
# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
|
||||||
|
%: Makefile
|
||||||
|
@$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
|
BIN
doc/_static/RUG_Logo.jpg
vendored
Normal file
BIN
doc/_static/RUG_Logo.jpg
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 53 KiB |
10
doc/_static/custom.css
vendored
Normal file
10
doc/_static/custom.css
vendored
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
/* override table width restrictions as found on https://github.com/getpelican/pelican/issues/1311 */
|
||||||
|
.wy-table-responsive table td, .wy-table-responsive table th {
|
||||||
|
/* !important prevents the common CSS stylesheets from
|
||||||
|
overriding this as on RTD they are loaded after this stylesheet */
|
||||||
|
white-space: normal !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.wy-table-responsive {
|
||||||
|
overflow: visible !important;
|
||||||
|
}
|
251
doc/conf.py
Normal file
251
doc/conf.py
Normal file
@ -0,0 +1,251 @@
|
|||||||
|
# Configuration file for the Sphinx documentation builder.
|
||||||
|
#
|
||||||
|
# This file only contains a selection of the most common options. For a full
|
||||||
|
# list see the documentation:
|
||||||
|
# https://www.sphinx-doc.org/en/master/usage/configuration.html
|
||||||
|
|
||||||
|
# -- Path setup --------------------------------------------------------------
|
||||||
|
|
||||||
|
# If extensions (or modules to document with autodoc) are in another directory,
|
||||||
|
# add these directories to sys.path here. If the directory is relative to the
|
||||||
|
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
||||||
|
#
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
# sys.path.insert(0, os.path.abspath('.'))
|
||||||
|
|
||||||
|
# Django autodoc
|
||||||
|
sys.path.insert(0, os.path.abspath('../polyclinic_scheduling'))
|
||||||
|
os.environ['DJANGO_SETTINGS_MODULE'] = 'polyclinic_scheduling.settings'
|
||||||
|
import django
|
||||||
|
django.setup()
|
||||||
|
|
||||||
|
# -- Project information -----------------------------------------------------
|
||||||
|
|
||||||
|
project = 'Poliklinieken Planning Tool'
|
||||||
|
copyright = '2020, Joshua Rubingh'
|
||||||
|
author = 'Joshua Rubingh'
|
||||||
|
|
||||||
|
# The full version, including alpha/beta/rc tags
|
||||||
|
release = '1.0'
|
||||||
|
|
||||||
|
# The master toctree document.
|
||||||
|
master_doc = 'index'
|
||||||
|
|
||||||
|
# -- General configuration ---------------------------------------------------
|
||||||
|
|
||||||
|
# Add any Sphinx extension module names here, as strings. They can be
|
||||||
|
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
||||||
|
# ones.
|
||||||
|
extensions = [
|
||||||
|
'sphinx.ext.napoleon',
|
||||||
|
'sphinx.ext.autodoc',
|
||||||
|
'sphinx.ext.viewcode',
|
||||||
|
'sphinx.ext.coverage',
|
||||||
|
'sphinx_markdown_builder',
|
||||||
|
]
|
||||||
|
|
||||||
|
# Add any paths that contain templates here, relative to this directory.
|
||||||
|
templates_path = ['_templates']
|
||||||
|
|
||||||
|
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||||
|
# for a list of supported languages.
|
||||||
|
#
|
||||||
|
# This is also used if you do content translation via gettext catalogs.
|
||||||
|
# Usually you set "language" from the command line for these cases.
|
||||||
|
language = 'en'
|
||||||
|
|
||||||
|
# List of patterns, relative to source directory, that match files and
|
||||||
|
# directories to ignore when looking for source files.
|
||||||
|
# This pattern also affects html_static_path and html_extra_path.
|
||||||
|
exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store','build/*']
|
||||||
|
|
||||||
|
# -- Options for HTML output -------------------------------------------------
|
||||||
|
|
||||||
|
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||||
|
# a list of builtin themes.
|
||||||
|
#
|
||||||
|
html_theme = 'alabaster'
|
||||||
|
|
||||||
|
# Add any paths that contain custom static files (such as style sheets) here,
|
||||||
|
# relative to this directory. They are copied after the builtin static files,
|
||||||
|
# so a file named "default.css" will overwrite the builtin "default.css".
|
||||||
|
html_static_path = ['_static']
|
||||||
|
|
||||||
|
html_theme_options = {
|
||||||
|
'logo': 'RUG_Logo.jpg',
|
||||||
|
'logo_name' : True
|
||||||
|
}
|
||||||
|
|
||||||
|
# -- Options for LaTeX output ---------------------------------------------
|
||||||
|
# Install Ubuntu/Debian package(s): texlive-latex-recommended, texlive-fonts-recommended, texlive-latex-extra, netpbm
|
||||||
|
latex_engine = 'pdflatex'
|
||||||
|
latex_elements = {
|
||||||
|
# The paper size ('letterpaper' or 'a4paper').
|
||||||
|
#
|
||||||
|
'papersize': 'a4paper',
|
||||||
|
'releasename':" ",
|
||||||
|
# Sonny, Lenny, Glenn, Conny, Rejne, Bjarne and Bjornstrup
|
||||||
|
# 'fncychap': '\\usepackage[Lenny]{fncychap}',
|
||||||
|
'fncychap': '\\usepackage{fncychap}',
|
||||||
|
'fontpkg': '\\usepackage{amsmath,amsfonts,amssymb,amsthm}',
|
||||||
|
|
||||||
|
'figure_align':'htbp',
|
||||||
|
# The font size ('10pt', '11pt' or '12pt').
|
||||||
|
#
|
||||||
|
'pointsize': '10pt',
|
||||||
|
|
||||||
|
# Additional stuff for the LaTeX preamble.
|
||||||
|
#
|
||||||
|
'preamble': r'''
|
||||||
|
%%%%%%%%%%%%%%%%%%%% Meher %%%%%%%%%%%%%%%%%%
|
||||||
|
%%%add number to subsubsection 2=subsection, 3=subsubsection
|
||||||
|
%%% below subsubsection is not good idea.
|
||||||
|
\setcounter{secnumdepth}{3}
|
||||||
|
%
|
||||||
|
%%%% Table of content upto 2=subsection, 3=subsubsection
|
||||||
|
\setcounter{tocdepth}{1}
|
||||||
|
|
||||||
|
\usepackage{amsmath,amsfonts,amssymb,amsthm}
|
||||||
|
\usepackage{graphicx}
|
||||||
|
|
||||||
|
%%% reduce spaces for Table of contents, figures and tables
|
||||||
|
%%% it is used "\addtocontents{toc}{\vskip -1.2cm}" etc. in the document
|
||||||
|
\usepackage[notlot,nottoc,notlof]{}
|
||||||
|
|
||||||
|
\usepackage{color}
|
||||||
|
\usepackage{transparent}
|
||||||
|
\usepackage{eso-pic}
|
||||||
|
\usepackage{lipsum}
|
||||||
|
|
||||||
|
\usepackage{footnotebackref} %%link at the footnote to go to the place of footnote in the text
|
||||||
|
|
||||||
|
%% spacing between line
|
||||||
|
\usepackage{setspace}
|
||||||
|
%%%%\onehalfspacing
|
||||||
|
%%%%\doublespacing
|
||||||
|
\singlespacing
|
||||||
|
|
||||||
|
|
||||||
|
%%%%%%%%%%% datetime
|
||||||
|
\usepackage{datetime}
|
||||||
|
|
||||||
|
\newdateformat{MonthYearFormat}{%
|
||||||
|
\monthname[\THEMONTH], \THEYEAR}
|
||||||
|
|
||||||
|
|
||||||
|
%% RO, LE will not work for 'oneside' layout.
|
||||||
|
%% Change oneside to twoside in document class
|
||||||
|
\usepackage{fancyhdr}
|
||||||
|
\pagestyle{fancy}
|
||||||
|
\fancyhf{}
|
||||||
|
|
||||||
|
%%% Alternating Header for oneside
|
||||||
|
\fancyhead[L]{\ifthenelse{\isodd{\value{page}}}{ \small \nouppercase{\leftmark} }{}}
|
||||||
|
\fancyhead[R]{\ifthenelse{\isodd{\value{page}}}{}{ \small \nouppercase{\rightmark} }}
|
||||||
|
|
||||||
|
%%% Alternating Header for two side
|
||||||
|
%\fancyhead[RO]{\small \nouppercase{\rightmark}}
|
||||||
|
%\fancyhead[LE]{\small \nouppercase{\leftmark}}
|
||||||
|
|
||||||
|
%% for oneside: change footer at right side. If you want to use Left and right then use same as header defined above.
|
||||||
|
%% \fancyfoot[R]{\ifthenelse{\isodd{\value{page}}}{{\tiny Meher Krishna Patel} }{\href{http://pythondsp.readthedocs.io/en/latest/pythondsp/toc.html}{\tiny PythonDSP}}}
|
||||||
|
|
||||||
|
%%% Alternating Footer for two side
|
||||||
|
%% %\fancyfoot[RO, RE]{\scriptsize Meher Krishna Patel (mekrip@gmail.com)}
|
||||||
|
|
||||||
|
%%% page number
|
||||||
|
\fancyfoot[CO, CE]{\thepage}
|
||||||
|
|
||||||
|
\renewcommand{\headrulewidth}{0.5pt}
|
||||||
|
\renewcommand{\footrulewidth}{0.5pt}
|
||||||
|
|
||||||
|
\RequirePackage{tocbibind} %%% comment this to remove page number for following
|
||||||
|
\addto\captionsenglish{\renewcommand{\contentsname}{Table of contents}}
|
||||||
|
%% \addto\captionsenglish{\renewcommand{\listfigurename}{List of figures}}
|
||||||
|
%% \addto\captionsenglish{\renewcommand{\listtablename}{List of tables}}
|
||||||
|
%% % \addto\captionsenglish{\renewcommand{\chaptername}{Chapter}}
|
||||||
|
|
||||||
|
|
||||||
|
%%reduce spacing for itemize
|
||||||
|
\usepackage{enumitem}
|
||||||
|
\setlist{nosep}
|
||||||
|
|
||||||
|
%%%%%%%%%%% Quote Styles at the top of chapter
|
||||||
|
%% \usepackage{epigraph}
|
||||||
|
%% \setlength{\epigraphwidth}{0.8\columnwidth}
|
||||||
|
%% \newcommand{\chapterquote}[2]{\epigraphhead[60]{\epigraph{\textit{#1}}{\textbf {\textit{--#2}}}}}
|
||||||
|
%%%%%%%%%%% Quote for all places except Chapter
|
||||||
|
%% \newcommand{\sectionquote}[2]{{\quote{\textit{``#1''}}{\textbf {\textit{--#2}}}}}
|
||||||
|
''',
|
||||||
|
|
||||||
|
|
||||||
|
'maketitle': r'''
|
||||||
|
\pagenumbering{Roman} %%% to avoid page 1 conflict with actual page 1
|
||||||
|
|
||||||
|
\begin{titlepage}
|
||||||
|
|
||||||
|
\begingroup % for PDF information dictionary
|
||||||
|
\def\endgraf{ }\def\and{\& }%
|
||||||
|
\pdfstringdefDisableCommands{\def\\{, }}% overwrite hyperref setup
|
||||||
|
\hypersetup{pdfauthor={\@author}, pdftitle={\@title}}%
|
||||||
|
\endgroup
|
||||||
|
|
||||||
|
\centering
|
||||||
|
|
||||||
|
\vspace*{40mm} %%% * is used to give space from top
|
||||||
|
\textbf{\Huge {RUG Poliklinieken Planning Tool} }
|
||||||
|
|
||||||
|
\vspace{0mm}
|
||||||
|
\begin{figure}[!h]
|
||||||
|
\centering
|
||||||
|
\includegraphics[scale=0.4]{RUG_Logo.jpg}
|
||||||
|
\end{figure}
|
||||||
|
|
||||||
|
\vspace{100mm}
|
||||||
|
\Large \textbf{{Joshua Rubingh}}
|
||||||
|
|
||||||
|
|
||||||
|
\small Created on : May, 2020
|
||||||
|
|
||||||
|
\vspace*{0mm}
|
||||||
|
\small Last updated : \MonthYearFormat\today
|
||||||
|
|
||||||
|
|
||||||
|
%% \vfill adds at the bottom
|
||||||
|
\vfill
|
||||||
|
%% \small \textit{More documents are freely available at }{\href{http://pythondsp.readthedocs.io/en/latest/pythondsp/toc.html}{PythonDSP}}
|
||||||
|
\end{titlepage}
|
||||||
|
|
||||||
|
\clearpage
|
||||||
|
\pagenumbering{roman}
|
||||||
|
\tableofcontents
|
||||||
|
\listoffigures
|
||||||
|
\listoftables
|
||||||
|
\clearpage
|
||||||
|
\pagenumbering{arabic}
|
||||||
|
''',
|
||||||
|
|
||||||
|
# Latex figure (float) alignment
|
||||||
|
#
|
||||||
|
# 'figure_align': 'htbp',
|
||||||
|
'sphinxsetup': \
|
||||||
|
'hmargin={0.7in,0.7in}, vmargin={1in,1in}, \
|
||||||
|
verbatimwithframe=true, \
|
||||||
|
TitleColor={rgb}{0,0,0}, \
|
||||||
|
HeaderFamily=\\rmfamily\\bfseries, \
|
||||||
|
InnerLinkColor={rgb}{0,0,1}, \
|
||||||
|
OuterLinkColor={rgb}{0,0,1}',
|
||||||
|
|
||||||
|
'tableofcontents':' ',
|
||||||
|
}
|
||||||
|
|
||||||
|
latex_logo = '_static/RUG_Logo.jpg'
|
||||||
|
|
||||||
|
# Grouping the document tree into LaTeX files. List of tuples
|
||||||
|
# (source start file, target name, title,
|
||||||
|
# author, documentclass [howto, manual, or own class]).
|
||||||
|
latex_documents = [
|
||||||
|
(master_doc, 'documentation.tex', project,
|
||||||
|
author, 'report')
|
||||||
|
]
|
BIN
doc/documentation.pdf
Normal file
BIN
doc/documentation.pdf
Normal file
Binary file not shown.
25
doc/index.rst
Normal file
25
doc/index.rst
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
.. Poliklinieken Planning documentation master file, created by
|
||||||
|
sphinx-quickstart on Mon May 18 13:21:06 2020.
|
||||||
|
You can adapt this file completely to your liking, but it should at least
|
||||||
|
contain the root `toctree` directive.
|
||||||
|
|
||||||
|
=====================================================
|
||||||
|
Welcome to Poliklinieken Planning Tool documentation!
|
||||||
|
=====================================================
|
||||||
|
|
||||||
|
Here you can read more information about the Poliklinieken Planning Tool.
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:caption: Table of Contents
|
||||||
|
:maxdepth: 2
|
||||||
|
|
||||||
|
install
|
||||||
|
models
|
||||||
|
views
|
||||||
|
|
||||||
|
Indices and tables
|
||||||
|
==================
|
||||||
|
|
||||||
|
* :ref:`genindex`
|
||||||
|
* :ref:`modindex`
|
||||||
|
* :ref:`search`
|
96
doc/install.rst
Normal file
96
doc/install.rst
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
============
|
||||||
|
Installation
|
||||||
|
============
|
||||||
|
|
||||||
|
In order to install this Polyclinic Schedule Tool, we use the following packages / software.
|
||||||
|
|
||||||
|
* NGINX
|
||||||
|
* MySQL
|
||||||
|
* Django
|
||||||
|
|
||||||
|
First we need to checkout the code.
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
git clone https://git.web.rug.nl/P300021/poli_planning.git /opt/poli_planning
|
||||||
|
|
||||||
|
-----
|
||||||
|
NGINX
|
||||||
|
-----
|
||||||
|
Install NGINX. For Ubuntu this would be
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
|
sudo apt install nginx
|
||||||
|
|
||||||
|
Also configure SSL (https://letsencrypt.org/) to make the connections secure. This is outside this installation scope.
|
||||||
|
|
||||||
|
Setup
|
||||||
|
-----
|
||||||
|
After installation of the packages, create a symbolic link in the `/etc/nginx/sites-enabled` so that a new VHost is created.
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
|
ln -s /opt/poli_planning/nginx/vhost.conf /etc/nginx/sites-enabled/poli_planning
|
||||||
|
|
||||||
|
Important parts of the VHost configuration:
|
||||||
|
|
||||||
|
.. literalinclude:: ../nginx/vhost.conf
|
||||||
|
:language: bash
|
||||||
|
|
||||||
|
In order to test if NGINX is configured correctly run `nginx -t` and it should give an OK message:
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
|
||||||
|
nginx: configuration file /etc/nginx/nginx.conf test is successful
|
||||||
|
|
||||||
|
------
|
||||||
|
Django
|
||||||
|
------
|
||||||
|
We install Django with standard settings. We could run it in Aync way, but then you need some more steps: https://docs.djangoproject.com/en/3.0/howto/deployment/asgi/ So for now, we keep it simple.
|
||||||
|
|
||||||
|
Install
|
||||||
|
=======
|
||||||
|
Create a python virtual environment
|
||||||
|
|
||||||
|
.. code-block:: bash
|
||||||
|
|
||||||
|
cd /opt/poli_planning
|
||||||
|
python3 -m venv python3_env
|
||||||
|
source python3_env/bin/activate
|
||||||
|
|
||||||
|
Finally we install the required Python modules
|
||||||
|
|
||||||
|
.. code-block:: python
|
||||||
|
|
||||||
|
pip install -r requirements
|
||||||
|
|
||||||
|
This will install all the needed Python modules we need to run this Django project.
|
||||||
|
|
||||||
|
Settings
|
||||||
|
--------
|
||||||
|
The settings for Django are set in an `.env` file so that you can easily change the environment from production to testing. There is an `.env.example` file that could be used as a template.
|
||||||
|
|
||||||
|
.. literalinclude:: ../polyclinic_scheduling/polyclinic_scheduling/.env.example
|
||||||
|
:language: jproperties
|
||||||
|
|
||||||
|
Next we have to make the database structure. If you are using SQLite3 as a backend, make sure the database file **DOES** exist on disk.
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
|
touch /opt/poli_planning/polyclinic_scheduling/db.sqlite3
|
||||||
|
|
||||||
|
Then in the Python virtual environment we run the following commands:
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
|
./manage.py migrate
|
||||||
|
./manage.py compilemessages
|
||||||
|
./manage.py collectstatic
|
||||||
|
|
||||||
|
And finally you should be able to start the Django application
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
|
./manage.py runserver
|
35
doc/make.bat
Normal file
35
doc/make.bat
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
@ECHO OFF
|
||||||
|
|
||||||
|
pushd %~dp0
|
||||||
|
|
||||||
|
REM Command file for Sphinx documentation
|
||||||
|
|
||||||
|
if "%SPHINXBUILD%" == "" (
|
||||||
|
set SPHINXBUILD=sphinx-build
|
||||||
|
)
|
||||||
|
set SOURCEDIR=source
|
||||||
|
set BUILDDIR=build
|
||||||
|
|
||||||
|
if "%1" == "" goto help
|
||||||
|
|
||||||
|
%SPHINXBUILD% >NUL 2>NUL
|
||||||
|
if errorlevel 9009 (
|
||||||
|
echo.
|
||||||
|
echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
|
||||||
|
echo.installed, then set the SPHINXBUILD environment variable to point
|
||||||
|
echo.to the full path of the 'sphinx-build' executable. Alternatively you
|
||||||
|
echo.may add the Sphinx directory to PATH.
|
||||||
|
echo.
|
||||||
|
echo.If you don't have Sphinx installed, grab it from
|
||||||
|
echo.http://sphinx-doc.org/
|
||||||
|
exit /b 1
|
||||||
|
)
|
||||||
|
|
||||||
|
%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
|
||||||
|
goto end
|
||||||
|
|
||||||
|
:help
|
||||||
|
%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
|
||||||
|
|
||||||
|
:end
|
||||||
|
popd
|
18
doc/models.rst
Normal file
18
doc/models.rst
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
======
|
||||||
|
Models
|
||||||
|
======
|
||||||
|
|
||||||
|
.. automodule:: lib.models.base
|
||||||
|
:members:
|
||||||
|
|
||||||
|
.. automodule:: apps.employee.models
|
||||||
|
:members:
|
||||||
|
|
||||||
|
.. automodule:: apps.hospital.models
|
||||||
|
:members:
|
||||||
|
|
||||||
|
.. automodule:: apps.polyclinic.models
|
||||||
|
:members:
|
||||||
|
|
||||||
|
.. automodule:: apps.schedule.models
|
||||||
|
:members:
|
2
doc/requirements.txt
Normal file
2
doc/requirements.txt
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
Sphinx==3.0.0
|
||||||
|
sphinx-markdown-builder==0.5.4
|
6
doc/views.rst
Normal file
6
doc/views.rst
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
======
|
||||||
|
Vieuws
|
||||||
|
======
|
||||||
|
|
||||||
|
.. automodule:: apps.schedule.views
|
||||||
|
:members:
|
92
nginx/vhost.conf
Normal file
92
nginx/vhost.conf
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
# You should look at the following URL's in order to grasp a solid understanding
|
||||||
|
# of Nginx configuration files in order to fully unleash the power of Nginx.
|
||||||
|
# https://www.nginx.com/resources/wiki/start/
|
||||||
|
# https://www.nginx.com/resources/wiki/start/topics/tutorials/config_pitfalls/
|
||||||
|
# https://wiki.debian.org/Nginx/DirectoryStructure
|
||||||
|
#
|
||||||
|
# In most cases, administrators will remove this file from sites-enabled/ and
|
||||||
|
# leave it as reference inside of sites-available where it will continue to be
|
||||||
|
# updated by the nginx packaging team.
|
||||||
|
#
|
||||||
|
# This file will automatically load configuration files provided by other
|
||||||
|
# applications, such as Drupal or Wordpress. These applications will be made
|
||||||
|
# available underneath a path with that package name, such as /drupal8.
|
||||||
|
#
|
||||||
|
# Please see /usr/share/doc/nginx-doc/examples/ for more detailed examples.
|
||||||
|
##
|
||||||
|
|
||||||
|
# Default server configuration
|
||||||
|
#
|
||||||
|
|
||||||
|
server {
|
||||||
|
# SSL configuration
|
||||||
|
#
|
||||||
|
# listen 443 ssl default_server;
|
||||||
|
# listen [::]:443 ssl default_server;
|
||||||
|
#
|
||||||
|
# Note: You should disable gzip for SSL traffic.
|
||||||
|
# See: https://bugs.debian.org/773332
|
||||||
|
#
|
||||||
|
# Read up on ssl_ciphers to ensure a secure configuration.
|
||||||
|
# See: https://bugs.debian.org/765782
|
||||||
|
#
|
||||||
|
# Self signed certs generated by the ssl-cert package
|
||||||
|
# Don't use them in a production server!
|
||||||
|
#
|
||||||
|
# include snippets/snakeoil.conf;
|
||||||
|
|
||||||
|
root /var/www/html;
|
||||||
|
|
||||||
|
# Add index.php to the list if you are using PHP
|
||||||
|
index index.html index.htm index.nginx-debian.html;
|
||||||
|
|
||||||
|
server_name poli-planning.hpc.rug.nl localhost;
|
||||||
|
|
||||||
|
access_log /var/log/nginx/poli-planning.hpc.rug.nl.access.log;
|
||||||
|
error_log /var/log/nginx/poli-planning.hpc.rug.nl.error.log;
|
||||||
|
|
||||||
|
location /static {
|
||||||
|
alias /opt/poli_planning/static;
|
||||||
|
}
|
||||||
|
|
||||||
|
location / {
|
||||||
|
# First attempt to serve request as file, then
|
||||||
|
# as directory, then fall back to displaying a 404.
|
||||||
|
# try_files $uri $uri/ =404;
|
||||||
|
|
||||||
|
proxy_pass http://localhost:8000;
|
||||||
|
proxy_http_version 1.1;
|
||||||
|
proxy_set_header Upgrade $http_upgrade;
|
||||||
|
proxy_set_header Connection "upgrade";
|
||||||
|
|
||||||
|
proxy_redirect off;
|
||||||
|
proxy_set_header Host $host;
|
||||||
|
proxy_set_header X-Real-IP $remote_addr;
|
||||||
|
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||||
|
proxy_set_header X-Forwarded-Host $server_name;
|
||||||
|
proxy_set_header X-Forwarded-Proto $scheme;
|
||||||
|
}
|
||||||
|
|
||||||
|
listen [::]:443 ssl ipv6only=on; # managed by Certbot
|
||||||
|
listen 443 ssl; # managed by Certbot
|
||||||
|
|
||||||
|
ssl_certificate /etc/letsencrypt/live/poli-planning.hpc.rug.nl/fullchain.pem; # managed by Certbot
|
||||||
|
ssl_certificate_key /etc/letsencrypt/live/poli-planning.hpc.rug.nl/privkey.pem; # managed by Certbot
|
||||||
|
|
||||||
|
include /etc/letsencrypt/options-ssl-nginx.conf; # managed by Certbot
|
||||||
|
ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by Certbot
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
server {
|
||||||
|
if ($host = poli-planning.hpc.rug.nl) {
|
||||||
|
return 301 https://$host$request_uri;
|
||||||
|
} # managed by Certbot
|
||||||
|
|
||||||
|
listen 80;
|
||||||
|
listen [::]:80;
|
||||||
|
|
||||||
|
server_name poli-planning.hpc.rug.nl localhost;
|
||||||
|
return 404; # managed by Certbot
|
||||||
|
}
|
||||||
|
|
@ -8,7 +8,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2020-05-18 09:07+0000\n"
|
"POT-Creation-Date: 2020-06-08 13:43+0200\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
@ -42,7 +42,7 @@ msgstr ""
|
|||||||
msgid "Welcome at RUG"
|
msgid "Welcome at RUG"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: apps/RUG_template/templates/base.html:85
|
#: apps/RUG_template/templates/base.html:83
|
||||||
msgid "Language selection"
|
msgid "Language selection"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -147,7 +147,7 @@ msgid ""
|
|||||||
"\n"
|
"\n"
|
||||||
"%(protocol)s://%(domain)s%(reset_url)s\n"
|
"%(protocol)s://%(domain)s%(reset_url)s\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Your username, in case you’ve forgotten: %(user)s\n"
|
"Your username, in case you've forgotten: %(user)s\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Thanks for using our site!\n"
|
"Thanks for using our site!\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
@ -7,8 +7,8 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: \n"
|
"Project-Id-Version: \n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2020-05-18 09:07+0000\n"
|
"POT-Creation-Date: 2020-06-08 13:43+0200\n"
|
||||||
"PO-Revision-Date: 2020-05-15 12:52+0200\n"
|
"PO-Revision-Date: 2020-05-19 12:05+0200\n"
|
||||||
"Last-Translator: Joshua Rubingh <j.g.rubingh@rug.nl>\n"
|
"Last-Translator: Joshua Rubingh <j.g.rubingh@rug.nl>\n"
|
||||||
"Language-Team: \n"
|
"Language-Team: \n"
|
||||||
"Language: nl\n"
|
"Language: nl\n"
|
||||||
@ -42,7 +42,7 @@ msgstr "Logouit"
|
|||||||
msgid "Welcome at RUG"
|
msgid "Welcome at RUG"
|
||||||
msgstr "Welkom bij de RUG"
|
msgstr "Welkom bij de RUG"
|
||||||
|
|
||||||
#: apps/RUG_template/templates/base.html:85
|
#: apps/RUG_template/templates/base.html:83
|
||||||
msgid "Language selection"
|
msgid "Language selection"
|
||||||
msgstr "Taal keuze"
|
msgstr "Taal keuze"
|
||||||
|
|
||||||
@ -155,7 +155,7 @@ msgid ""
|
|||||||
"\n"
|
"\n"
|
||||||
"%(protocol)s://%(domain)s%(reset_url)s\n"
|
"%(protocol)s://%(domain)s%(reset_url)s\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Your username, in case you’ve forgotten: %(user)s\n"
|
"Your username, in case you've forgotten: %(user)s\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Thanks for using our site!\n"
|
"Thanks for using our site!\n"
|
||||||
"\n"
|
"\n"
|
||||||
@ -168,7 +168,7 @@ msgstr ""
|
|||||||
"\n"
|
"\n"
|
||||||
"%(protocol)s://%(domain)s%(reset_url)s\n"
|
"%(protocol)s://%(domain)s%(reset_url)s\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Uw gebruikersnaam, voor het geval u het bent vergeten:%(user)s\n"
|
"Uw gebruikersnaam, voor het geval u het bent vergeten: %(user)s\n"
|
||||||
"\n"
|
"\n"
|
||||||
"Bedankt voor het gebruiken van onze site!\n"
|
"Bedankt voor het gebruiken van onze site!\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
38
polyclinic_scheduling/apps/RUG_template/middleware.py
Normal file
38
polyclinic_scheduling/apps/RUG_template/middleware.py
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
import pytz
|
||||||
|
import requests
|
||||||
|
|
||||||
|
from ipware import get_client_ip
|
||||||
|
from django.utils import timezone
|
||||||
|
|
||||||
|
# make sure you add `TimezoneMiddleware` appropriately in settings.py: 'apps.RUG_template.middleware.TimezoneMiddleware'
|
||||||
|
class TimezoneMiddleware:
|
||||||
|
""" Middleware to check user timezone. """
|
||||||
|
def __init__(self, get_response):
|
||||||
|
self.get_response = get_response
|
||||||
|
# One-time configuration and initialization.
|
||||||
|
|
||||||
|
def __call__(self, request):
|
||||||
|
# Code to be executed for each request before
|
||||||
|
# the view (and later middleware) are called.
|
||||||
|
client_ip, is_routable = get_client_ip(request)
|
||||||
|
user_time_zone = request.session.get('user_time_zone', None)
|
||||||
|
try:
|
||||||
|
if user_time_zone is None and is_routable and client_ip is not None:
|
||||||
|
# Here we use an online service to get visitor info. Maybe not the nicest way to do it, but it is a way
|
||||||
|
# Also we only check when we get a public IP address. Local networks will not be checked online
|
||||||
|
# https://freegeoip.app
|
||||||
|
freegeoip_response = requests.get('https://freegeoip.app/json/{0}'.format(client_ip))
|
||||||
|
freegeoip_response_json = freegeoip_response.json()
|
||||||
|
user_time_zone = freegeoip_response_json['time_zone']
|
||||||
|
if user_time_zone:
|
||||||
|
request.session['user_time_zone'] = user_time_zone
|
||||||
|
timezone.activate(pytz.timezone(user_time_zone))
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
response = self.get_response(request)
|
||||||
|
|
||||||
|
# Code to be executed for each request/response after
|
||||||
|
# the view is called.
|
||||||
|
|
||||||
|
return response
|
@ -31,10 +31,18 @@ table {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
form#new_schedule_form input {
|
.pointer {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
form#new_schedule_form input:not([type=checkbox]) {
|
||||||
width: 100%
|
width: 100%
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.text-danger {
|
||||||
|
color: #721c24;
|
||||||
|
}
|
||||||
|
|
||||||
.alert-warning {
|
.alert-warning {
|
||||||
color: #856404;
|
color: #856404;
|
||||||
background-color: #fff3cd;
|
background-color: #fff3cd;
|
||||||
|
18
polyclinic_scheduling/apps/RUG_template/static/RUG_template/javascript/formdata.min.js
vendored
Normal file
18
polyclinic_scheduling/apps/RUG_template/static/RUG_template/javascript/formdata.min.js
vendored
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
;(function(){var k;function m(a){var b=0;return function(){return b<a.length?{done:!1,value:a[b++]}:{done:!0}}}var p="function"==typeof Object.defineProperties?Object.defineProperty:function(a,b,c){a!=Array.prototype&&a!=Object.prototype&&(a[b]=c.value)},q="undefined"!=typeof window&&window===this?this:"undefined"!=typeof global&&null!=global?global:this;function r(){r=function(){};q.Symbol||(q.Symbol=u)}function v(a,b){this.s=a;p(this,"description",{configurable:!0,writable:!0,value:b})}
|
||||||
|
v.prototype.toString=function(){return this.s};var u=function(){function a(c){if(this instanceof a)throw new TypeError("Symbol is not a constructor");return new v("jscomp_symbol_"+(c||"")+"_"+b++,c)}var b=0;return a}();function w(){r();var a=q.Symbol.iterator;a||(a=q.Symbol.iterator=q.Symbol("Symbol.iterator"));"function"!=typeof Array.prototype[a]&&p(Array.prototype,a,{configurable:!0,writable:!0,value:function(){return x(m(this))}});w=function(){}}
|
||||||
|
function x(a){w();a={next:a};a[q.Symbol.iterator]=function(){return this};return a}function y(a){var b="undefined"!=typeof Symbol&&Symbol.iterator&&a[Symbol.iterator];return b?b.call(a):{next:m(a)}}var z;if("function"==typeof Object.setPrototypeOf)z=Object.setPrototypeOf;else{var A;a:{var B={v:!0},C={};try{C.__proto__=B;A=C.v;break a}catch(a){}A=!1}z=A?function(a,b){a.__proto__=b;if(a.__proto__!==b)throw new TypeError(a+" is not extensible");return a}:null}var D=z;
|
||||||
|
function E(){this.h=!1;this.c=null;this.o=void 0;this.b=1;this.m=this.w=0;this.g=null}function F(a){if(a.h)throw new TypeError("Generator is already running");a.h=!0}E.prototype.i=function(a){this.o=a};E.prototype.j=function(a){this.g={A:a,B:!0};this.b=this.w||this.m};E.prototype["return"]=function(a){this.g={"return":a};this.b=this.m};function G(a,b,c){a.b=c;return{value:b}}function H(a){this.C=a;this.l=[];for(var b in a)this.l.push(b);this.l.reverse()}function I(a){this.a=new E;this.D=a}
|
||||||
|
I.prototype.i=function(a){F(this.a);if(this.a.c)return J(this,this.a.c.next,a,this.a.i);this.a.i(a);return K(this)};function L(a,b){F(a.a);var c=a.a.c;if(c)return J(a,"return"in c?c["return"]:function(d){return{value:d,done:!0}},b,a.a["return"]);a.a["return"](b);return K(a)}I.prototype.j=function(a){F(this.a);if(this.a.c)return J(this,this.a.c["throw"],a,this.a.i);this.a.j(a);return K(this)};
|
||||||
|
function J(a,b,c,d){try{var e=b.call(a.a.c,c);if(!(e instanceof Object))throw new TypeError("Iterator result "+e+" is not an object");if(!e.done)return a.a.h=!1,e;var f=e.value}catch(g){return a.a.c=null,a.a.j(g),K(a)}a.a.c=null;d.call(a.a,f);return K(a)}function K(a){for(;a.a.b;)try{var b=a.D(a.a);if(b)return a.a.h=!1,{value:b.value,done:!1}}catch(c){a.a.o=void 0,a.a.j(c)}a.a.h=!1;if(a.a.g){b=a.a.g;a.a.g=null;if(b.B)throw b.A;return{value:b["return"],done:!0}}return{value:void 0,done:!0}}
|
||||||
|
function M(a){this.next=function(b){return a.i(b)};this["throw"]=function(b){return a.j(b)};this["return"]=function(b){return L(a,b)};w();this[Symbol.iterator]=function(){return this}}function N(a,b){var c=new M(new I(b));D&&D(c,a.prototype);return c}
|
||||||
|
if("undefined"!==typeof Blob&&("undefined"===typeof FormData||!FormData.prototype.keys)){var O=function(a,b){for(var c=0;c<a.length;c++)b(a[c])},P=function(a,b,c){return b instanceof Blob?[String(a),b,void 0!==c?c+"":"string"===typeof b.name?b.name:"blob"]:[String(a),String(b)]},Q=function(a,b){if(a.length<b)throw new TypeError(b+" argument required, but only "+a.length+" present.");},S=function(a){var b=y(a);a=b.next().value;b=b.next().value;a instanceof Blob&&(a=new File([a],b,{type:a.type,lastModified:a.lastModified}));
|
||||||
|
return a},T="object"===typeof window?window:"object"===typeof self?self:this,U=T.FormData,V=T.XMLHttpRequest&&T.XMLHttpRequest.prototype.send,W=T.Request&&T.fetch,X=T.navigator&&T.navigator.sendBeacon;r();var Y=T.Symbol&&Symbol.toStringTag;Y&&(Blob.prototype[Y]||(Blob.prototype[Y]="Blob"),"File"in T&&!File.prototype[Y]&&(File.prototype[Y]="File"));try{new File([],"")}catch(a){T.File=function(b,c,d){b=new Blob(b,d);d=d&&void 0!==d.lastModified?new Date(d.lastModified):new Date;Object.defineProperties(b,
|
||||||
|
{name:{value:c},lastModifiedDate:{value:d},lastModified:{value:+d},toString:{value:function(){return"[object File]"}}});Y&&Object.defineProperty(b,Y,{value:"File"});return b}}r();w();var Z=function(a){this.f=Object.create(null);if(!a)return this;var b=this;O(a.elements,function(c){if(c.name&&!c.disabled&&"submit"!==c.type&&"button"!==c.type)if("file"===c.type){var d=c.files&&c.files.length?c.files:[new File([],"",{type:"application/octet-stream"})];O(d,function(e){b.append(c.name,e)})}else"select-multiple"===
|
||||||
|
c.type||"select-one"===c.type?O(c.options,function(e){!e.disabled&&e.selected&&b.append(c.name,e.value)}):"checkbox"===c.type||"radio"===c.type?c.checked&&b.append(c.name,c.value):(d="textarea"===c.type?c.value.replace(/\r\n/g,"\n").replace(/\n/g,"\r\n"):c.value,b.append(c.name,d))})};k=Z.prototype;k.append=function(a,b,c){Q(arguments,2);var d=y(P.apply(null,arguments));a=d.next().value;b=d.next().value;c=d.next().value;d=this.f;d[a]||(d[a]=[]);d[a].push([b,c])};k["delete"]=function(a){Q(arguments,
|
||||||
|
1);delete this.f[String(a)]};k.entries=function b(){var c=this,d,e,f,g,h,t;return N(b,function(l){switch(l.b){case 1:d=c.f,f=new H(d);case 2:var n;a:{for(n=f;0<n.l.length;){var R=n.l.pop();if(R in n.C){n=R;break a}}n=null}if(null==(e=n)){l.b=0;break}g=y(d[e]);h=g.next();case 5:if(h.done){l.b=2;break}t=h.value;return G(l,[e,S(t)],6);case 6:h=g.next(),l.b=5}})};k.forEach=function(b,c){Q(arguments,1);for(var d=y(this),e=d.next();!e.done;e=d.next()){var f=y(e.value);e=f.next().value;f=f.next().value;
|
||||||
|
b.call(c,f,e,this)}};k.get=function(b){Q(arguments,1);var c=this.f;b=String(b);return c[b]?S(c[b][0]):null};k.getAll=function(b){Q(arguments,1);return(this.f[String(b)]||[]).map(S)};k.has=function(b){Q(arguments,1);return String(b)in this.f};k.keys=function c(){var d=this,e,f,g,h,t;return N(c,function(l){1==l.b&&(e=y(d),f=e.next());if(3!=l.b){if(f.done){l.b=0;return}g=f.value;h=y(g);t=h.next().value;return G(l,t,3)}f=e.next();l.b=2})};k.set=function(c,d,e){Q(arguments,2);var f=P.apply(null,arguments);
|
||||||
|
this.f[f[0]]=[[f[1],f[2]]]};k.values=function d(){var e=this,f,g,h,t,l;return N(d,function(n){1==n.b&&(f=y(e),g=f.next());if(3!=n.b){if(g.done){n.b=0;return}h=g.value;t=y(h);t.next();l=t.next().value;return G(n,l,3)}g=f.next();n.b=2})};Z.prototype._asNative=function(){for(var d=new U,e=y(this),f=e.next();!f.done;f=e.next()){var g=y(f.value);f=g.next().value;g=g.next().value;d.append(f,g)}return d};Z.prototype._blob=function(){for(var d="----formdata-polyfill-"+Math.random(),e=[],f=y(this),g=f.next();!g.done;g=
|
||||||
|
f.next()){var h=y(g.value);g=h.next().value;h=h.next().value;e.push("--"+d+"\r\n");h instanceof Blob?e.push('Content-Disposition: form-data; name="'+g+'"; filename="'+h.name+'"\r\n',"Content-Type: "+(h.type||"application/octet-stream")+"\r\n\r\n",h,"\r\n"):e.push('Content-Disposition: form-data; name="'+g+'"\r\n\r\n'+h+"\r\n")}e.push("--"+d+"--");return new Blob(e,{type:"multipart/form-data; boundary="+d})};Z.prototype[Symbol.iterator]=function(){return this.entries()};Z.prototype.toString=function(){return"[object FormData]"};
|
||||||
|
Y&&(Z.prototype[Y]="FormData");if(V){var aa=T.XMLHttpRequest.prototype.setRequestHeader;T.XMLHttpRequest.prototype.setRequestHeader=function(d,e){aa.call(this,d,e);"content-type"===d.toLowerCase()&&(this.u=!0)};T.XMLHttpRequest.prototype.send=function(d){d instanceof Z?(d=d._blob(),this.u||this.setRequestHeader("Content-Type",d.type),V.call(this,d)):V.call(this,d)}}if(W){var ba=T.fetch;T.fetch=function(d,e){e&&e.body&&e.body instanceof Z&&(e.body=e.body._blob());return ba.call(this,d,e)}}X&&(T.navigator.sendBeacon=
|
||||||
|
function(d,e){e instanceof Z&&(e=e._asNative());return X.call(this,d,e)});T.FormData=Z};
|
||||||
|
})();
|
@ -0,0 +1,806 @@
|
|||||||
|
// HumanizeDuration.js - https://git.io/j0HgmQ
|
||||||
|
|
||||||
|
;(function () {
|
||||||
|
// This has to be defined separately because of a bug: we want to alias
|
||||||
|
// `gr` and `el` for backwards-compatiblity. In a breaking change, we can
|
||||||
|
// remove `gr` entirely.
|
||||||
|
// See https://github.com/EvanHahn/HumanizeDuration.js/issues/143 for more.
|
||||||
|
var greek = {
|
||||||
|
y: function (c) { return c === 1 ? 'χρόνος' : 'χρόνια' },
|
||||||
|
mo: function (c) { return c === 1 ? 'μήνας' : 'μήνες' },
|
||||||
|
w: function (c) { return c === 1 ? 'εβδομάδα' : 'εβδομάδες' },
|
||||||
|
d: function (c) { return c === 1 ? 'μέρα' : 'μέρες' },
|
||||||
|
h: function (c) { return c === 1 ? 'ώρα' : 'ώρες' },
|
||||||
|
m: function (c) { return c === 1 ? 'λεπτό' : 'λεπτά' },
|
||||||
|
s: function (c) { return c === 1 ? 'δευτερόλεπτο' : 'δευτερόλεπτα' },
|
||||||
|
ms: function (c) { return c === 1 ? 'χιλιοστό του δευτερολέπτου' : 'χιλιοστά του δευτερολέπτου' },
|
||||||
|
decimal: ','
|
||||||
|
}
|
||||||
|
|
||||||
|
var languages = {
|
||||||
|
ar: {
|
||||||
|
y: function (c) { return c === 1 ? 'سنة' : 'سنوات' },
|
||||||
|
mo: function (c) { return c === 1 ? 'شهر' : 'أشهر' },
|
||||||
|
w: function (c) { return c === 1 ? 'أسبوع' : 'أسابيع' },
|
||||||
|
d: function (c) { return c === 1 ? 'يوم' : 'أيام' },
|
||||||
|
h: function (c) { return c === 1 ? 'ساعة' : 'ساعات' },
|
||||||
|
m: function (c) {
|
||||||
|
return ['دقيقة', 'دقائق'][getArabicForm(c)]
|
||||||
|
},
|
||||||
|
s: function (c) { return c === 1 ? 'ثانية' : 'ثواني' },
|
||||||
|
ms: function (c) { return c === 1 ? 'جزء من الثانية' : 'أجزاء من الثانية' },
|
||||||
|
decimal: ','
|
||||||
|
},
|
||||||
|
bg: {
|
||||||
|
y: function (c) { return ['години', 'година', 'години'][getSlavicForm(c)] },
|
||||||
|
mo: function (c) { return ['месеца', 'месец', 'месеца'][getSlavicForm(c)] },
|
||||||
|
w: function (c) { return ['седмици', 'седмица', 'седмици'][getSlavicForm(c)] },
|
||||||
|
d: function (c) { return ['дни', 'ден', 'дни'][getSlavicForm(c)] },
|
||||||
|
h: function (c) { return ['часа', 'час', 'часа'][getSlavicForm(c)] },
|
||||||
|
m: function (c) { return ['минути', 'минута', 'минути'][getSlavicForm(c)] },
|
||||||
|
s: function (c) { return ['секунди', 'секунда', 'секунди'][getSlavicForm(c)] },
|
||||||
|
ms: function (c) { return ['милисекунди', 'милисекунда', 'милисекунди'][getSlavicForm(c)] },
|
||||||
|
decimal: ','
|
||||||
|
},
|
||||||
|
ca: {
|
||||||
|
y: function (c) { return 'any' + (c === 1 ? '' : 's') },
|
||||||
|
mo: function (c) { return 'mes' + (c === 1 ? '' : 'os') },
|
||||||
|
w: function (c) { return 'setman' + (c === 1 ? 'a' : 'es') },
|
||||||
|
d: function (c) { return 'di' + (c === 1 ? 'a' : 'es') },
|
||||||
|
h: function (c) { return 'hor' + (c === 1 ? 'a' : 'es') },
|
||||||
|
m: function (c) { return 'minut' + (c === 1 ? '' : 's') },
|
||||||
|
s: function (c) { return 'segon' + (c === 1 ? '' : 's') },
|
||||||
|
ms: function (c) { return 'milisegon' + (c === 1 ? '' : 's') },
|
||||||
|
decimal: ','
|
||||||
|
},
|
||||||
|
cs: {
|
||||||
|
y: function (c) { return ['rok', 'roku', 'roky', 'let'][getCzechOrSlovakForm(c)] },
|
||||||
|
mo: function (c) { return ['měsíc', 'měsíce', 'měsíce', 'měsíců'][getCzechOrSlovakForm(c)] },
|
||||||
|
w: function (c) { return ['týden', 'týdne', 'týdny', 'týdnů'][getCzechOrSlovakForm(c)] },
|
||||||
|
d: function (c) { return ['den', 'dne', 'dny', 'dní'][getCzechOrSlovakForm(c)] },
|
||||||
|
h: function (c) { return ['hodina', 'hodiny', 'hodiny', 'hodin'][getCzechOrSlovakForm(c)] },
|
||||||
|
m: function (c) { return ['minuta', 'minuty', 'minuty', 'minut'][getCzechOrSlovakForm(c)] },
|
||||||
|
s: function (c) { return ['sekunda', 'sekundy', 'sekundy', 'sekund'][getCzechOrSlovakForm(c)] },
|
||||||
|
ms: function (c) { return ['milisekunda', 'milisekundy', 'milisekundy', 'milisekund'][getCzechOrSlovakForm(c)] },
|
||||||
|
decimal: ','
|
||||||
|
},
|
||||||
|
da: {
|
||||||
|
y: 'år',
|
||||||
|
mo: function (c) { return 'måned' + (c === 1 ? '' : 'er') },
|
||||||
|
w: function (c) { return 'uge' + (c === 1 ? '' : 'r') },
|
||||||
|
d: function (c) { return 'dag' + (c === 1 ? '' : 'e') },
|
||||||
|
h: function (c) { return 'time' + (c === 1 ? '' : 'r') },
|
||||||
|
m: function (c) { return 'minut' + (c === 1 ? '' : 'ter') },
|
||||||
|
s: function (c) { return 'sekund' + (c === 1 ? '' : 'er') },
|
||||||
|
ms: function (c) { return 'millisekund' + (c === 1 ? '' : 'er') },
|
||||||
|
decimal: ','
|
||||||
|
},
|
||||||
|
de: {
|
||||||
|
y: function (c) { return 'Jahr' + (c === 1 ? '' : 'e') },
|
||||||
|
mo: function (c) { return 'Monat' + (c === 1 ? '' : 'e') },
|
||||||
|
w: function (c) { return 'Woche' + (c === 1 ? '' : 'n') },
|
||||||
|
d: function (c) { return 'Tag' + (c === 1 ? '' : 'e') },
|
||||||
|
h: function (c) { return 'Stunde' + (c === 1 ? '' : 'n') },
|
||||||
|
m: function (c) { return 'Minute' + (c === 1 ? '' : 'n') },
|
||||||
|
s: function (c) { return 'Sekunde' + (c === 1 ? '' : 'n') },
|
||||||
|
ms: function (c) { return 'Millisekunde' + (c === 1 ? '' : 'n') },
|
||||||
|
decimal: ','
|
||||||
|
},
|
||||||
|
el: greek,
|
||||||
|
en: {
|
||||||
|
y: function (c) { return 'year' + (c === 1 ? '' : 's') },
|
||||||
|
mo: function (c) { return 'month' + (c === 1 ? '' : 's') },
|
||||||
|
w: function (c) { return 'week' + (c === 1 ? '' : 's') },
|
||||||
|
d: function (c) { return 'day' + (c === 1 ? '' : 's') },
|
||||||
|
h: function (c) { return 'hour' + (c === 1 ? '' : 's') },
|
||||||
|
m: function (c) { return 'minute' + (c === 1 ? '' : 's') },
|
||||||
|
s: function (c) { return 'second' + (c === 1 ? '' : 's') },
|
||||||
|
ms: function (c) { return 'millisecond' + (c === 1 ? '' : 's') },
|
||||||
|
decimal: '.'
|
||||||
|
},
|
||||||
|
es: {
|
||||||
|
y: function (c) { return 'año' + (c === 1 ? '' : 's') },
|
||||||
|
mo: function (c) { return 'mes' + (c === 1 ? '' : 'es') },
|
||||||
|
w: function (c) { return 'semana' + (c === 1 ? '' : 's') },
|
||||||
|
d: function (c) { return 'día' + (c === 1 ? '' : 's') },
|
||||||
|
h: function (c) { return 'hora' + (c === 1 ? '' : 's') },
|
||||||
|
m: function (c) { return 'minuto' + (c === 1 ? '' : 's') },
|
||||||
|
s: function (c) { return 'segundo' + (c === 1 ? '' : 's') },
|
||||||
|
ms: function (c) { return 'milisegundo' + (c === 1 ? '' : 's') },
|
||||||
|
decimal: ','
|
||||||
|
},
|
||||||
|
et: {
|
||||||
|
y: function (c) { return 'aasta' + (c === 1 ? '' : 't') },
|
||||||
|
mo: function (c) { return 'kuu' + (c === 1 ? '' : 'd') },
|
||||||
|
w: function (c) { return 'nädal' + (c === 1 ? '' : 'at') },
|
||||||
|
d: function (c) { return 'päev' + (c === 1 ? '' : 'a') },
|
||||||
|
h: function (c) { return 'tund' + (c === 1 ? '' : 'i') },
|
||||||
|
m: function (c) { return 'minut' + (c === 1 ? '' : 'it') },
|
||||||
|
s: function (c) { return 'sekund' + (c === 1 ? '' : 'it') },
|
||||||
|
ms: function (c) { return 'millisekund' + (c === 1 ? '' : 'it') },
|
||||||
|
decimal: ','
|
||||||
|
},
|
||||||
|
fa: {
|
||||||
|
y: 'سال',
|
||||||
|
mo: 'ماه',
|
||||||
|
w: 'هفته',
|
||||||
|
d: 'روز',
|
||||||
|
h: 'ساعت',
|
||||||
|
m: 'دقیقه',
|
||||||
|
s: 'ثانیه',
|
||||||
|
ms: 'میلی ثانیه',
|
||||||
|
decimal: '.'
|
||||||
|
},
|
||||||
|
fi: {
|
||||||
|
y: function (c) { return c === 1 ? 'vuosi' : 'vuotta' },
|
||||||
|
mo: function (c) { return c === 1 ? 'kuukausi' : 'kuukautta' },
|
||||||
|
w: function (c) { return 'viikko' + (c === 1 ? '' : 'a') },
|
||||||
|
d: function (c) { return 'päivä' + (c === 1 ? '' : 'ä') },
|
||||||
|
h: function (c) { return 'tunti' + (c === 1 ? '' : 'a') },
|
||||||
|
m: function (c) { return 'minuutti' + (c === 1 ? '' : 'a') },
|
||||||
|
s: function (c) { return 'sekunti' + (c === 1 ? '' : 'a') },
|
||||||
|
ms: function (c) { return 'millisekunti' + (c === 1 ? '' : 'a') },
|
||||||
|
decimal: ','
|
||||||
|
},
|
||||||
|
fo: {
|
||||||
|
y: 'ár',
|
||||||
|
mo: function (c) { return c === 1 ? 'mánaður' : 'mánaðir' },
|
||||||
|
w: function (c) { return c === 1 ? 'vika' : 'vikur' },
|
||||||
|
d: function (c) { return c === 1 ? 'dagur' : 'dagar' },
|
||||||
|
h: function (c) { return c === 1 ? 'tími' : 'tímar' },
|
||||||
|
m: function (c) { return c === 1 ? 'minuttur' : 'minuttir' },
|
||||||
|
s: 'sekund',
|
||||||
|
ms: 'millisekund',
|
||||||
|
decimal: ','
|
||||||
|
},
|
||||||
|
fr: {
|
||||||
|
y: function (c) { return 'an' + (c >= 2 ? 's' : '') },
|
||||||
|
mo: 'mois',
|
||||||
|
w: function (c) { return 'semaine' + (c >= 2 ? 's' : '') },
|
||||||
|
d: function (c) { return 'jour' + (c >= 2 ? 's' : '') },
|
||||||
|
h: function (c) { return 'heure' + (c >= 2 ? 's' : '') },
|
||||||
|
m: function (c) { return 'minute' + (c >= 2 ? 's' : '') },
|
||||||
|
s: function (c) { return 'seconde' + (c >= 2 ? 's' : '') },
|
||||||
|
ms: function (c) { return 'milliseconde' + (c >= 2 ? 's' : '') },
|
||||||
|
decimal: ','
|
||||||
|
},
|
||||||
|
gr: greek,
|
||||||
|
he: {
|
||||||
|
y: function (c) { return c === 1 ? 'שנה' : 'שנים' },
|
||||||
|
mo: function (c) { return c === 1 ? 'חודש' : 'חודשים' },
|
||||||
|
w: function (c) { return c === 1 ? 'שבוע' : 'שבועות' },
|
||||||
|
d: function (c) { return c === 1 ? 'יום' : 'ימים' },
|
||||||
|
h: function (c) { return c === 1 ? 'שעה' : 'שעות' },
|
||||||
|
m: function (c) { return c === 1 ? 'דקה' : 'דקות' },
|
||||||
|
s: function (c) { return c === 1 ? 'שניה' : 'שניות' },
|
||||||
|
ms: function (c) { return c === 1 ? 'מילישנייה' : 'מילישניות' },
|
||||||
|
decimal: '.'
|
||||||
|
},
|
||||||
|
hr: {
|
||||||
|
y: function (c) {
|
||||||
|
if (c % 10 === 2 || c % 10 === 3 || c % 10 === 4) {
|
||||||
|
return 'godine'
|
||||||
|
}
|
||||||
|
return 'godina'
|
||||||
|
},
|
||||||
|
mo: function (c) {
|
||||||
|
if (c === 1) {
|
||||||
|
return 'mjesec'
|
||||||
|
} else if (c === 2 || c === 3 || c === 4) {
|
||||||
|
return 'mjeseca'
|
||||||
|
}
|
||||||
|
return 'mjeseci'
|
||||||
|
},
|
||||||
|
w: function (c) {
|
||||||
|
if (c % 10 === 1 && c !== 11) {
|
||||||
|
return 'tjedan'
|
||||||
|
}
|
||||||
|
return 'tjedna'
|
||||||
|
},
|
||||||
|
d: function (c) { return c === 1 ? 'dan' : 'dana' },
|
||||||
|
h: function (c) {
|
||||||
|
if (c === 1) {
|
||||||
|
return 'sat'
|
||||||
|
} else if (c === 2 || c === 3 || c === 4) {
|
||||||
|
return 'sata'
|
||||||
|
}
|
||||||
|
return 'sati'
|
||||||
|
},
|
||||||
|
m: function (c) {
|
||||||
|
var mod10 = c % 10
|
||||||
|
if ((mod10 === 2 || mod10 === 3 || mod10 === 4) && (c < 10 || c > 14)) {
|
||||||
|
return 'minute'
|
||||||
|
}
|
||||||
|
return 'minuta'
|
||||||
|
},
|
||||||
|
s: function (c) {
|
||||||
|
if ((c === 10 || c === 11 || c === 12 || c === 13 || c === 14 || c === 16 || c === 17 || c === 18 || c === 19) || (c % 10 === 5)) {
|
||||||
|
return 'sekundi'
|
||||||
|
} else if (c % 10 === 1) {
|
||||||
|
return 'sekunda'
|
||||||
|
} else if (c % 10 === 2 || c % 10 === 3 || c % 10 === 4) {
|
||||||
|
return 'sekunde'
|
||||||
|
}
|
||||||
|
return 'sekundi'
|
||||||
|
},
|
||||||
|
ms: function (c) {
|
||||||
|
if (c === 1) {
|
||||||
|
return 'milisekunda'
|
||||||
|
} else if (c % 10 === 2 || c % 10 === 3 || c % 10 === 4) {
|
||||||
|
return 'milisekunde'
|
||||||
|
}
|
||||||
|
return 'milisekundi'
|
||||||
|
},
|
||||||
|
decimal: ','
|
||||||
|
},
|
||||||
|
hu: {
|
||||||
|
y: 'év',
|
||||||
|
mo: 'hónap',
|
||||||
|
w: 'hét',
|
||||||
|
d: 'nap',
|
||||||
|
h: 'óra',
|
||||||
|
m: 'perc',
|
||||||
|
s: 'másodperc',
|
||||||
|
ms: 'ezredmásodperc',
|
||||||
|
decimal: ','
|
||||||
|
},
|
||||||
|
id: {
|
||||||
|
y: 'tahun',
|
||||||
|
mo: 'bulan',
|
||||||
|
w: 'minggu',
|
||||||
|
d: 'hari',
|
||||||
|
h: 'jam',
|
||||||
|
m: 'menit',
|
||||||
|
s: 'detik',
|
||||||
|
ms: 'milidetik',
|
||||||
|
decimal: '.'
|
||||||
|
},
|
||||||
|
is: {
|
||||||
|
y: 'ár',
|
||||||
|
mo: function (c) { return 'mánuð' + (c === 1 ? 'ur' : 'ir') },
|
||||||
|
w: function (c) { return 'vik' + (c === 1 ? 'a' : 'ur') },
|
||||||
|
d: function (c) { return 'dag' + (c === 1 ? 'ur' : 'ar') },
|
||||||
|
h: function (c) { return 'klukkutím' + (c === 1 ? 'i' : 'ar') },
|
||||||
|
m: function (c) { return 'mínút' + (c === 1 ? 'a' : 'ur') },
|
||||||
|
s: function (c) { return 'sekúnd' + (c === 1 ? 'a' : 'ur') },
|
||||||
|
ms: function (c) { return 'millisekúnd' + (c === 1 ? 'a' : 'ur') },
|
||||||
|
decimal: '.'
|
||||||
|
},
|
||||||
|
it: {
|
||||||
|
y: function (c) { return 'ann' + (c === 1 ? 'o' : 'i') },
|
||||||
|
mo: function (c) { return 'mes' + (c === 1 ? 'e' : 'i') },
|
||||||
|
w: function (c) { return 'settiman' + (c === 1 ? 'a' : 'e') },
|
||||||
|
d: function (c) { return 'giorn' + (c === 1 ? 'o' : 'i') },
|
||||||
|
h: function (c) { return 'or' + (c === 1 ? 'a' : 'e') },
|
||||||
|
m: function (c) { return 'minut' + (c === 1 ? 'o' : 'i') },
|
||||||
|
s: function (c) { return 'second' + (c === 1 ? 'o' : 'i') },
|
||||||
|
ms: function (c) { return 'millisecond' + (c === 1 ? 'o' : 'i') },
|
||||||
|
decimal: ','
|
||||||
|
},
|
||||||
|
ja: {
|
||||||
|
y: '年',
|
||||||
|
mo: '月',
|
||||||
|
w: '週',
|
||||||
|
d: '日',
|
||||||
|
h: '時間',
|
||||||
|
m: '分',
|
||||||
|
s: '秒',
|
||||||
|
ms: 'ミリ秒',
|
||||||
|
decimal: '.'
|
||||||
|
},
|
||||||
|
ko: {
|
||||||
|
y: '년',
|
||||||
|
mo: '개월',
|
||||||
|
w: '주일',
|
||||||
|
d: '일',
|
||||||
|
h: '시간',
|
||||||
|
m: '분',
|
||||||
|
s: '초',
|
||||||
|
ms: '밀리 초',
|
||||||
|
decimal: '.'
|
||||||
|
},
|
||||||
|
lo: {
|
||||||
|
y: 'ປີ',
|
||||||
|
mo: 'ເດືອນ',
|
||||||
|
w: 'ອາທິດ',
|
||||||
|
d: 'ມື້',
|
||||||
|
h: 'ຊົ່ວໂມງ',
|
||||||
|
m: 'ນາທີ',
|
||||||
|
s: 'ວິນາທີ',
|
||||||
|
ms: 'ມິນລິວິນາທີ',
|
||||||
|
decimal: ','
|
||||||
|
},
|
||||||
|
lt: {
|
||||||
|
y: function (c) { return ((c % 10 === 0) || (c % 100 >= 10 && c % 100 <= 20)) ? 'metų' : 'metai' },
|
||||||
|
mo: function (c) { return ['mėnuo', 'mėnesiai', 'mėnesių'][getLithuanianForm(c)] },
|
||||||
|
w: function (c) { return ['savaitė', 'savaitės', 'savaičių'][getLithuanianForm(c)] },
|
||||||
|
d: function (c) { return ['diena', 'dienos', 'dienų'][getLithuanianForm(c)] },
|
||||||
|
h: function (c) { return ['valanda', 'valandos', 'valandų'][getLithuanianForm(c)] },
|
||||||
|
m: function (c) { return ['minutė', 'minutės', 'minučių'][getLithuanianForm(c)] },
|
||||||
|
s: function (c) { return ['sekundė', 'sekundės', 'sekundžių'][getLithuanianForm(c)] },
|
||||||
|
ms: function (c) { return ['milisekundė', 'milisekundės', 'milisekundžių'][getLithuanianForm(c)] },
|
||||||
|
decimal: ','
|
||||||
|
},
|
||||||
|
lv: {
|
||||||
|
y: function (c) { return ['gads', 'gadi'][getLatvianForm(c)] },
|
||||||
|
mo: function (c) { return ['mēnesis', 'mēneši'][getLatvianForm(c)] },
|
||||||
|
w: function (c) { return ['nedēļa', 'nedēļas'][getLatvianForm(c)] },
|
||||||
|
d: function (c) { return ['diena', 'dienas'][getLatvianForm(c)] },
|
||||||
|
h: function (c) { return ['stunda', 'stundas'][getLatvianForm(c)] },
|
||||||
|
m: function (c) { return ['minūte', 'minūtes'][getLatvianForm(c)] },
|
||||||
|
s: function (c) { return ['sekunde', 'sekundes'][getLatvianForm(c)] },
|
||||||
|
ms: function (c) { return ['milisekunde', 'milisekundes'][getLatvianForm(c)] },
|
||||||
|
decimal: ','
|
||||||
|
},
|
||||||
|
ms: {
|
||||||
|
y: 'tahun',
|
||||||
|
mo: 'bulan',
|
||||||
|
w: 'minggu',
|
||||||
|
d: 'hari',
|
||||||
|
h: 'jam',
|
||||||
|
m: 'minit',
|
||||||
|
s: 'saat',
|
||||||
|
ms: 'milisaat',
|
||||||
|
decimal: '.'
|
||||||
|
},
|
||||||
|
nl: {
|
||||||
|
y: 'jaar',
|
||||||
|
mo: function (c) { return c === 1 ? 'maand' : 'maanden' },
|
||||||
|
w: function (c) { return c === 1 ? 'week' : 'weken' },
|
||||||
|
d: function (c) { return c === 1 ? 'dag' : 'dagen' },
|
||||||
|
h: 'uur',
|
||||||
|
m: function (c) { return c === 1 ? 'minuut' : 'minuten' },
|
||||||
|
s: function (c) { return c === 1 ? 'seconde' : 'seconden' },
|
||||||
|
ms: function (c) { return c === 1 ? 'milliseconde' : 'milliseconden' },
|
||||||
|
decimal: ','
|
||||||
|
},
|
||||||
|
no: {
|
||||||
|
y: 'år',
|
||||||
|
mo: function (c) { return 'måned' + (c === 1 ? '' : 'er') },
|
||||||
|
w: function (c) { return 'uke' + (c === 1 ? '' : 'r') },
|
||||||
|
d: function (c) { return 'dag' + (c === 1 ? '' : 'er') },
|
||||||
|
h: function (c) { return 'time' + (c === 1 ? '' : 'r') },
|
||||||
|
m: function (c) { return 'minutt' + (c === 1 ? '' : 'er') },
|
||||||
|
s: function (c) { return 'sekund' + (c === 1 ? '' : 'er') },
|
||||||
|
ms: function (c) { return 'millisekund' + (c === 1 ? '' : 'er') },
|
||||||
|
decimal: ','
|
||||||
|
},
|
||||||
|
pl: {
|
||||||
|
y: function (c) { return ['rok', 'roku', 'lata', 'lat'][getPolishForm(c)] },
|
||||||
|
mo: function (c) { return ['miesiąc', 'miesiąca', 'miesiące', 'miesięcy'][getPolishForm(c)] },
|
||||||
|
w: function (c) { return ['tydzień', 'tygodnia', 'tygodnie', 'tygodni'][getPolishForm(c)] },
|
||||||
|
d: function (c) { return ['dzień', 'dnia', 'dni', 'dni'][getPolishForm(c)] },
|
||||||
|
h: function (c) { return ['godzina', 'godziny', 'godziny', 'godzin'][getPolishForm(c)] },
|
||||||
|
m: function (c) { return ['minuta', 'minuty', 'minuty', 'minut'][getPolishForm(c)] },
|
||||||
|
s: function (c) { return ['sekunda', 'sekundy', 'sekundy', 'sekund'][getPolishForm(c)] },
|
||||||
|
ms: function (c) { return ['milisekunda', 'milisekundy', 'milisekundy', 'milisekund'][getPolishForm(c)] },
|
||||||
|
decimal: ','
|
||||||
|
},
|
||||||
|
pt: {
|
||||||
|
y: function (c) { return 'ano' + (c === 1 ? '' : 's') },
|
||||||
|
mo: function (c) { return c === 1 ? 'mês' : 'meses' },
|
||||||
|
w: function (c) { return 'semana' + (c === 1 ? '' : 's') },
|
||||||
|
d: function (c) { return 'dia' + (c === 1 ? '' : 's') },
|
||||||
|
h: function (c) { return 'hora' + (c === 1 ? '' : 's') },
|
||||||
|
m: function (c) { return 'minuto' + (c === 1 ? '' : 's') },
|
||||||
|
s: function (c) { return 'segundo' + (c === 1 ? '' : 's') },
|
||||||
|
ms: function (c) { return 'milissegundo' + (c === 1 ? '' : 's') },
|
||||||
|
decimal: ','
|
||||||
|
},
|
||||||
|
ro: {
|
||||||
|
y: function (c) { return c === 1 ? 'an' : 'ani' },
|
||||||
|
mo: function (c) { return c === 1 ? 'lună' : 'luni' },
|
||||||
|
w: function (c) { return c === 1 ? 'săptămână' : 'săptămâni' },
|
||||||
|
d: function (c) { return c === 1 ? 'zi' : 'zile' },
|
||||||
|
h: function (c) { return c === 1 ? 'oră' : 'ore' },
|
||||||
|
m: function (c) { return c === 1 ? 'minut' : 'minute' },
|
||||||
|
s: function (c) { return c === 1 ? 'secundă' : 'secunde' },
|
||||||
|
ms: function (c) { return c === 1 ? 'milisecundă' : 'milisecunde' },
|
||||||
|
decimal: ','
|
||||||
|
},
|
||||||
|
ru: {
|
||||||
|
y: function (c) { return ['лет', 'год', 'года'][getSlavicForm(c)] },
|
||||||
|
mo: function (c) { return ['месяцев', 'месяц', 'месяца'][getSlavicForm(c)] },
|
||||||
|
w: function (c) { return ['недель', 'неделя', 'недели'][getSlavicForm(c)] },
|
||||||
|
d: function (c) { return ['дней', 'день', 'дня'][getSlavicForm(c)] },
|
||||||
|
h: function (c) { return ['часов', 'час', 'часа'][getSlavicForm(c)] },
|
||||||
|
m: function (c) { return ['минут', 'минута', 'минуты'][getSlavicForm(c)] },
|
||||||
|
s: function (c) { return ['секунд', 'секунда', 'секунды'][getSlavicForm(c)] },
|
||||||
|
ms: function (c) { return ['миллисекунд', 'миллисекунда', 'миллисекунды'][getSlavicForm(c)] },
|
||||||
|
decimal: ','
|
||||||
|
},
|
||||||
|
uk: {
|
||||||
|
y: function (c) { return ['років', 'рік', 'роки'][getSlavicForm(c)] },
|
||||||
|
mo: function (c) { return ['місяців', 'місяць', 'місяці'][getSlavicForm(c)] },
|
||||||
|
w: function (c) { return ['тижнів', 'тиждень', 'тижні'][getSlavicForm(c)] },
|
||||||
|
d: function (c) { return ['днів', 'день', 'дні'][getSlavicForm(c)] },
|
||||||
|
h: function (c) { return ['годин', 'година', 'години'][getSlavicForm(c)] },
|
||||||
|
m: function (c) { return ['хвилин', 'хвилина', 'хвилини'][getSlavicForm(c)] },
|
||||||
|
s: function (c) { return ['секунд', 'секунда', 'секунди'][getSlavicForm(c)] },
|
||||||
|
ms: function (c) { return ['мілісекунд', 'мілісекунда', 'мілісекунди'][getSlavicForm(c)] },
|
||||||
|
decimal: ','
|
||||||
|
},
|
||||||
|
ur: {
|
||||||
|
y: 'سال',
|
||||||
|
mo: function (c) { return c === 1 ? 'مہینہ' : 'مہینے' },
|
||||||
|
w: function (c) { return c === 1 ? 'ہفتہ' : 'ہفتے' },
|
||||||
|
d: 'دن',
|
||||||
|
h: function (c) { return c === 1 ? 'گھنٹہ' : 'گھنٹے' },
|
||||||
|
m: 'منٹ',
|
||||||
|
s: 'سیکنڈ',
|
||||||
|
ms: 'ملی سیکنڈ',
|
||||||
|
decimal: '.'
|
||||||
|
},
|
||||||
|
sk: {
|
||||||
|
y: function (c) { return ['rok', 'roky', 'roky', 'rokov'][getCzechOrSlovakForm(c)] },
|
||||||
|
mo: function (c) { return ['mesiac', 'mesiace', 'mesiace', 'mesiacov'][getCzechOrSlovakForm(c)] },
|
||||||
|
w: function (c) { return ['týždeň', 'týždne', 'týždne', 'týždňov'][getCzechOrSlovakForm(c)] },
|
||||||
|
d: function (c) { return ['deň', 'dni', 'dni', 'dní'][getCzechOrSlovakForm(c)] },
|
||||||
|
h: function (c) { return ['hodina', 'hodiny', 'hodiny', 'hodín'][getCzechOrSlovakForm(c)] },
|
||||||
|
m: function (c) { return ['minúta', 'minúty', 'minúty', 'minút'][getCzechOrSlovakForm(c)] },
|
||||||
|
s: function (c) { return ['sekunda', 'sekundy', 'sekundy', 'sekúnd'][getCzechOrSlovakForm(c)] },
|
||||||
|
ms: function (c) { return ['milisekunda', 'milisekundy', 'milisekundy', 'milisekúnd'][getCzechOrSlovakForm(c)] },
|
||||||
|
decimal: ','
|
||||||
|
},
|
||||||
|
sv: {
|
||||||
|
y: 'år',
|
||||||
|
mo: function (c) { return 'månad' + (c === 1 ? '' : 'er') },
|
||||||
|
w: function (c) { return 'veck' + (c === 1 ? 'a' : 'or') },
|
||||||
|
d: function (c) { return 'dag' + (c === 1 ? '' : 'ar') },
|
||||||
|
h: function (c) { return 'timm' + (c === 1 ? 'e' : 'ar') },
|
||||||
|
m: function (c) { return 'minut' + (c === 1 ? '' : 'er') },
|
||||||
|
s: function (c) { return 'sekund' + (c === 1 ? '' : 'er') },
|
||||||
|
ms: function (c) { return 'millisekund' + (c === 1 ? '' : 'er') },
|
||||||
|
decimal: ','
|
||||||
|
},
|
||||||
|
sw: {
|
||||||
|
y: function (c) { return c === 1 ? 'mwaka' : 'miaka' },
|
||||||
|
mo: function (c) { return c === 1 ? 'mwezi' : 'miezi' },
|
||||||
|
w: 'wiki',
|
||||||
|
d: function (c) { return c === 1 ? 'siku' : 'masiku' },
|
||||||
|
h: function (c) { return c === 1 ? 'saa' : 'masaa' },
|
||||||
|
m: 'dakika',
|
||||||
|
s: 'sekunde',
|
||||||
|
ms: 'milisekunde',
|
||||||
|
decimal: '.'
|
||||||
|
},
|
||||||
|
tr: {
|
||||||
|
y: 'yıl',
|
||||||
|
mo: 'ay',
|
||||||
|
w: 'hafta',
|
||||||
|
d: 'gün',
|
||||||
|
h: 'saat',
|
||||||
|
m: 'dakika',
|
||||||
|
s: 'saniye',
|
||||||
|
ms: 'milisaniye',
|
||||||
|
decimal: ','
|
||||||
|
},
|
||||||
|
th: {
|
||||||
|
y: 'ปี',
|
||||||
|
mo: 'เดือน',
|
||||||
|
w: 'อาทิตย์',
|
||||||
|
d: 'วัน',
|
||||||
|
h: 'ชั่วโมง',
|
||||||
|
m: 'นาที',
|
||||||
|
s: 'วินาที',
|
||||||
|
ms: 'มิลลิวินาที',
|
||||||
|
decimal: '.'
|
||||||
|
},
|
||||||
|
vi: {
|
||||||
|
y: 'năm',
|
||||||
|
mo: 'tháng',
|
||||||
|
w: 'tuần',
|
||||||
|
d: 'ngày',
|
||||||
|
h: 'giờ',
|
||||||
|
m: 'phút',
|
||||||
|
s: 'giây',
|
||||||
|
ms: 'mili giây',
|
||||||
|
decimal: ','
|
||||||
|
},
|
||||||
|
zh_CN: {
|
||||||
|
y: '年',
|
||||||
|
mo: '个月',
|
||||||
|
w: '周',
|
||||||
|
d: '天',
|
||||||
|
h: '小时',
|
||||||
|
m: '分钟',
|
||||||
|
s: '秒',
|
||||||
|
ms: '毫秒',
|
||||||
|
decimal: '.'
|
||||||
|
},
|
||||||
|
zh_TW: {
|
||||||
|
y: '年',
|
||||||
|
mo: '個月',
|
||||||
|
w: '周',
|
||||||
|
d: '天',
|
||||||
|
h: '小時',
|
||||||
|
m: '分鐘',
|
||||||
|
s: '秒',
|
||||||
|
ms: '毫秒',
|
||||||
|
decimal: '.'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// You can create a humanizer, which returns a function with default
|
||||||
|
// parameters.
|
||||||
|
function humanizer (passedOptions) {
|
||||||
|
var result = function humanizer (ms, humanizerOptions) {
|
||||||
|
var options = extend({}, result, humanizerOptions || {})
|
||||||
|
return doHumanization(ms, options)
|
||||||
|
}
|
||||||
|
|
||||||
|
return extend(result, {
|
||||||
|
language: 'en',
|
||||||
|
delimiter: ', ',
|
||||||
|
spacer: ' ',
|
||||||
|
conjunction: '',
|
||||||
|
serialComma: true,
|
||||||
|
units: ['y', 'mo', 'w', 'd', 'h', 'm', 's'],
|
||||||
|
languages: {},
|
||||||
|
round: false,
|
||||||
|
unitMeasures: {
|
||||||
|
y: 31557600000,
|
||||||
|
mo: 2629800000,
|
||||||
|
w: 604800000,
|
||||||
|
d: 86400000,
|
||||||
|
h: 3600000,
|
||||||
|
m: 60000,
|
||||||
|
s: 1000,
|
||||||
|
ms: 1
|
||||||
|
}
|
||||||
|
}, passedOptions)
|
||||||
|
}
|
||||||
|
|
||||||
|
// The main function is just a wrapper around a default humanizer.
|
||||||
|
var humanizeDuration = humanizer({})
|
||||||
|
|
||||||
|
// Build dictionary from options
|
||||||
|
function getDictionary (options) {
|
||||||
|
var languagesFromOptions = [options.language]
|
||||||
|
|
||||||
|
if (has(options, 'fallbacks')) {
|
||||||
|
if (isArray(options.fallbacks) && options.fallbacks.length) {
|
||||||
|
languagesFromOptions = languagesFromOptions.concat(options.fallbacks)
|
||||||
|
} else {
|
||||||
|
throw new Error('fallbacks must be an array with at least one element')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < languagesFromOptions.length; i++) {
|
||||||
|
var languageToTry = languagesFromOptions[i]
|
||||||
|
if (has(options.languages, languageToTry)) {
|
||||||
|
return options.languages[languageToTry]
|
||||||
|
} else if (has(languages, languageToTry)) {
|
||||||
|
return languages[languageToTry]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error('No language found.')
|
||||||
|
}
|
||||||
|
|
||||||
|
// doHumanization does the bulk of the work.
|
||||||
|
function doHumanization (ms, options) {
|
||||||
|
var i, len, piece
|
||||||
|
|
||||||
|
// Make sure we have a positive number.
|
||||||
|
// Has the nice sideffect of turning Number objects into primitives.
|
||||||
|
ms = Math.abs(ms)
|
||||||
|
|
||||||
|
var dictionary = getDictionary(options)
|
||||||
|
var pieces = []
|
||||||
|
|
||||||
|
// Start at the top and keep removing units, bit by bit.
|
||||||
|
var unitName, unitMS, unitCount
|
||||||
|
for (i = 0, len = options.units.length; i < len; i++) {
|
||||||
|
unitName = options.units[i]
|
||||||
|
unitMS = options.unitMeasures[unitName]
|
||||||
|
|
||||||
|
// What's the number of full units we can fit?
|
||||||
|
if (i + 1 === len) {
|
||||||
|
if (has(options, 'maxDecimalPoints')) {
|
||||||
|
// We need to use this expValue to avoid rounding functionality of toFixed call
|
||||||
|
var expValue = Math.pow(10, options.maxDecimalPoints)
|
||||||
|
var unitCountFloat = (ms / unitMS)
|
||||||
|
unitCount = parseFloat((Math.floor(expValue * unitCountFloat) / expValue).toFixed(options.maxDecimalPoints))
|
||||||
|
} else {
|
||||||
|
unitCount = ms / unitMS
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
unitCount = Math.floor(ms / unitMS)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add the string.
|
||||||
|
pieces.push({
|
||||||
|
unitCount: unitCount,
|
||||||
|
unitName: unitName
|
||||||
|
})
|
||||||
|
|
||||||
|
// Remove what we just figured out.
|
||||||
|
ms -= unitCount * unitMS
|
||||||
|
}
|
||||||
|
|
||||||
|
var firstOccupiedUnitIndex = 0
|
||||||
|
for (i = 0; i < pieces.length; i++) {
|
||||||
|
if (pieces[i].unitCount) {
|
||||||
|
firstOccupiedUnitIndex = i
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (options.round) {
|
||||||
|
var ratioToLargerUnit, previousPiece
|
||||||
|
for (i = pieces.length - 1; i >= 0; i--) {
|
||||||
|
piece = pieces[i]
|
||||||
|
piece.unitCount = Math.round(piece.unitCount)
|
||||||
|
|
||||||
|
if (i === 0) { break }
|
||||||
|
|
||||||
|
previousPiece = pieces[i - 1]
|
||||||
|
|
||||||
|
ratioToLargerUnit = options.unitMeasures[previousPiece.unitName] / options.unitMeasures[piece.unitName]
|
||||||
|
if ((piece.unitCount % ratioToLargerUnit) === 0 || (options.largest && ((options.largest - 1) < (i - firstOccupiedUnitIndex)))) {
|
||||||
|
previousPiece.unitCount += piece.unitCount / ratioToLargerUnit
|
||||||
|
piece.unitCount = 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = []
|
||||||
|
for (i = 0, pieces.length; i < len; i++) {
|
||||||
|
piece = pieces[i]
|
||||||
|
if (piece.unitCount) {
|
||||||
|
result.push(render(piece.unitCount, piece.unitName, dictionary, options))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.length === options.largest) { break }
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.length) {
|
||||||
|
if (!options.conjunction || result.length === 1) {
|
||||||
|
return result.join(options.delimiter)
|
||||||
|
} else if (result.length === 2) {
|
||||||
|
return result.join(options.conjunction)
|
||||||
|
} else if (result.length > 2) {
|
||||||
|
return result.slice(0, -1).join(options.delimiter) + (options.serialComma ? ',' : '') + options.conjunction + result.slice(-1)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return render(0, options.units[options.units.length - 1], dictionary, options)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function render (count, type, dictionary, options) {
|
||||||
|
var decimal
|
||||||
|
if (has(options, 'decimal')) {
|
||||||
|
decimal = options.decimal
|
||||||
|
} else if (has(dictionary, 'decimal')) {
|
||||||
|
decimal = dictionary.decimal
|
||||||
|
} else {
|
||||||
|
decimal = '.'
|
||||||
|
}
|
||||||
|
|
||||||
|
var countStr = count.toString().replace('.', decimal)
|
||||||
|
|
||||||
|
var dictionaryValue = dictionary[type]
|
||||||
|
var word
|
||||||
|
if (typeof dictionaryValue === 'function') {
|
||||||
|
word = dictionaryValue(count)
|
||||||
|
} else {
|
||||||
|
word = dictionaryValue
|
||||||
|
}
|
||||||
|
|
||||||
|
return countStr + options.spacer + word
|
||||||
|
}
|
||||||
|
|
||||||
|
function extend (destination) {
|
||||||
|
var source
|
||||||
|
for (var i = 1; i < arguments.length; i++) {
|
||||||
|
source = arguments[i]
|
||||||
|
for (var prop in source) {
|
||||||
|
if (has(source, prop)) {
|
||||||
|
destination[prop] = source[prop]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return destination
|
||||||
|
}
|
||||||
|
|
||||||
|
// Internal helper function for Polish language.
|
||||||
|
function getPolishForm (c) {
|
||||||
|
if (c === 1) {
|
||||||
|
return 0
|
||||||
|
} else if (Math.floor(c) !== c) {
|
||||||
|
return 1
|
||||||
|
} else if (c % 10 >= 2 && c % 10 <= 4 && !(c % 100 > 10 && c % 100 < 20)) {
|
||||||
|
return 2
|
||||||
|
} else {
|
||||||
|
return 3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Internal helper function for Russian and Ukranian languages.
|
||||||
|
function getSlavicForm (c) {
|
||||||
|
if (Math.floor(c) !== c) {
|
||||||
|
return 2
|
||||||
|
} else if ((c % 100 >= 5 && c % 100 <= 20) || (c % 10 >= 5 && c % 10 <= 9) || c % 10 === 0) {
|
||||||
|
return 0
|
||||||
|
} else if (c % 10 === 1) {
|
||||||
|
return 1
|
||||||
|
} else if (c > 1) {
|
||||||
|
return 2
|
||||||
|
} else {
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Internal helper function for Slovak language.
|
||||||
|
function getCzechOrSlovakForm (c) {
|
||||||
|
if (c === 1) {
|
||||||
|
return 0
|
||||||
|
} else if (Math.floor(c) !== c) {
|
||||||
|
return 1
|
||||||
|
} else if (c % 10 >= 2 && c % 10 <= 4 && c % 100 < 10) {
|
||||||
|
return 2
|
||||||
|
} else {
|
||||||
|
return 3
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Internal helper function for Lithuanian language.
|
||||||
|
function getLithuanianForm (c) {
|
||||||
|
if (c === 1 || (c % 10 === 1 && c % 100 > 20)) {
|
||||||
|
return 0
|
||||||
|
} else if (Math.floor(c) !== c || (c % 10 >= 2 && c % 100 > 20) || (c % 10 >= 2 && c % 100 < 10)) {
|
||||||
|
return 1
|
||||||
|
} else {
|
||||||
|
return 2
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Internal helper function for Latvian language.
|
||||||
|
function getLatvianForm (c) {
|
||||||
|
if (c === 1 || (c % 10 === 1 && c % 100 !== 11)) {
|
||||||
|
return 0
|
||||||
|
} else {
|
||||||
|
return 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Internal helper function for Arabic language.
|
||||||
|
function getArabicForm (c) {
|
||||||
|
if (c <= 2) { return 0 }
|
||||||
|
if (c > 2 && c < 11) { return 1 }
|
||||||
|
return 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// We need to make sure we support browsers that don't have
|
||||||
|
// `Array.isArray`, so we define a fallback here.
|
||||||
|
var isArray = Array.isArray || function (arg) {
|
||||||
|
return Object.prototype.toString.call(arg) === '[object Array]'
|
||||||
|
}
|
||||||
|
|
||||||
|
function has (obj, key) {
|
||||||
|
return Object.prototype.hasOwnProperty.call(obj, key)
|
||||||
|
}
|
||||||
|
|
||||||
|
humanizeDuration.getSupportedLanguages = function getSupportedLanguages () {
|
||||||
|
var result = []
|
||||||
|
for (var language in languages) {
|
||||||
|
if (has(languages, language) && language !== 'gr') {
|
||||||
|
result.push(language)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
humanizeDuration.humanizer = humanizer
|
||||||
|
|
||||||
|
if (typeof define === 'function' && define.amd) {
|
||||||
|
define(function () {
|
||||||
|
return humanizeDuration
|
||||||
|
})
|
||||||
|
} else if (typeof module !== 'undefined' && module.exports) {
|
||||||
|
module.exports = humanizeDuration
|
||||||
|
} else {
|
||||||
|
this.humanizeDuration = humanizeDuration
|
||||||
|
}
|
||||||
|
})(); // eslint-disable-line semi
|
File diff suppressed because one or more lines are too long
@ -25,11 +25,6 @@
|
|||||||
<meta content="#cc0000" name="msapplication-TileColor">
|
<meta content="#cc0000" name="msapplication-TileColor">
|
||||||
<meta content="https://www.rug.nl/mstile-144x144.png" name="msapplication-TileImage">
|
<meta content="https://www.rug.nl/mstile-144x144.png" name="msapplication-TileImage">
|
||||||
<meta content="user-scalable=1, initial-scale=1.0" name="viewport">
|
<meta content="user-scalable=1, initial-scale=1.0" name="viewport">
|
||||||
{% comment %}
|
|
||||||
<script type="text/javascript">
|
|
||||||
var alertsHref = "";
|
|
||||||
</script>
|
|
||||||
{% endcomment %}
|
|
||||||
|
|
||||||
<script src="https://www.rug.nl/_definition/shared/js/jquery.js?version=2019-12-12" type="text/javascript"></script>
|
<script src="https://www.rug.nl/_definition/shared/js/jquery.js?version=2019-12-12" type="text/javascript"></script>
|
||||||
<script type="text/javascript">jQuery.noConflict();</script>
|
<script type="text/javascript">jQuery.noConflict();</script>
|
||||||
@ -51,6 +46,9 @@
|
|||||||
<script type="text/javascript" src="https://www.rug.nl/_definition/shared/js/cross-frame.js?version=2019-12-12"></script>
|
<script type="text/javascript" src="https://www.rug.nl/_definition/shared/js/cross-frame.js?version=2019-12-12"></script>
|
||||||
|
|
||||||
<link href="{% static 'RUG_template/css/base.css' %}" rel="stylesheet"/>
|
<link href="{% static 'RUG_template/css/base.css' %}" rel="stylesheet"/>
|
||||||
|
<script type="text/javascript" src="{% static 'RUG_template/javascript/moment-with-locales.min.js' %}"></script>
|
||||||
|
<script type="text/javascript" src="{% static 'RUG_template/javascript/humanize-duration.js' %}"></script>
|
||||||
|
<script type="text/javascript" src="{% static 'RUG_template/javascript/formdata.min.js' %}"></script>
|
||||||
|
|
||||||
</head>
|
</head>
|
||||||
<body itemtype="http://schema.org/WebPage" itemscope="itemscope" id="top" class="page--topicpage"><!--googleoff: all-->
|
<body itemtype="http://schema.org/WebPage" itemscope="itemscope" id="top" class="page--topicpage"><!--googleoff: all-->
|
||||||
@ -90,6 +88,10 @@
|
|||||||
{% get_current_language as LANGUAGE_CODE %}
|
{% get_current_language as LANGUAGE_CODE %}
|
||||||
{% get_available_languages as LANGUAGES %}
|
{% get_available_languages as LANGUAGES %}
|
||||||
{% get_language_info_list for LANGUAGES as languages %}
|
{% get_language_info_list for LANGUAGES as languages %}
|
||||||
|
{% comment %} Here we set the MomentJS locale for all date and time actions {% endcomment %}
|
||||||
|
<script type="text/javascript">
|
||||||
|
moment.locale('{{LANGUAGE_CODE}}');
|
||||||
|
</script>
|
||||||
<input name="next" type="hidden" value="{% if redirect_to %}{{ redirect_to }}{% endif %}">
|
<input name="next" type="hidden" value="{% if redirect_to %}{{ redirect_to }}{% endif %}">
|
||||||
<input type="hidden" name="language" id="language" value="{{LANGUAGE_CODE}}">
|
<input type="hidden" name="language" id="language" value="{{LANGUAGE_CODE}}">
|
||||||
{% for language in languages %}
|
{% for language in languages %}
|
||||||
|
@ -5,7 +5,7 @@ Please go to the following page and choose a new password:
|
|||||||
|
|
||||||
{{ protocol}}://{{ domain }}{{ reset_url }}
|
{{ protocol}}://{{ domain }}{{ reset_url }}
|
||||||
|
|
||||||
Your username, in case you’ve forgotten: {{ user }}
|
Your username, in case you've forgotten: {{ user }}
|
||||||
|
|
||||||
Thanks for using our site!
|
Thanks for using our site!
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
|
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
|
||||||
from django.contrib.auth.models import User
|
from django.contrib.auth.models import User
|
||||||
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
from .models import Employee
|
from .models import Employee
|
||||||
|
|
||||||
@ -9,7 +10,7 @@ from .models import Employee
|
|||||||
class EmployeeInline(admin.StackedInline):
|
class EmployeeInline(admin.StackedInline):
|
||||||
model = Employee
|
model = Employee
|
||||||
can_delete = False
|
can_delete = False
|
||||||
verbose_name_plural = 'employee'
|
verbose_name_plural = _('employee')
|
||||||
|
|
||||||
# Define a new User admin
|
# Define a new User admin
|
||||||
class UserAdmin(BaseUserAdmin):
|
class UserAdmin(BaseUserAdmin):
|
||||||
|
@ -8,7 +8,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2020-05-18 09:07+0000\n"
|
"POT-Creation-Date: 2020-06-08 13:43+0200\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
@ -18,6 +18,10 @@ msgstr ""
|
|||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||||
|
|
||||||
|
#: apps/employee/admin.py:13 apps/employee/models.py:28
|
||||||
|
msgid "employee"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: apps/employee/apps.py:7
|
#: apps/employee/apps.py:7
|
||||||
msgid "Employee"
|
msgid "Employee"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@ -26,30 +30,26 @@ msgstr ""
|
|||||||
msgid "Employees"
|
msgid "Employees"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: apps/employee/models.py:13
|
#: apps/employee/models.py:29
|
||||||
msgid "employee"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: apps/employee/models.py:14
|
|
||||||
msgid "employees"
|
msgid "employees"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: apps/employee/models.py:16
|
#: apps/employee/models.py:31
|
||||||
msgid "Django user"
|
msgid "Django user"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: apps/employee/models.py:18
|
#: apps/employee/models.py:33
|
||||||
msgid "Select the hospital for this employee"
|
msgid "Select the hospital for this employee"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: apps/employee/models.py:20
|
#: apps/employee/models.py:35
|
||||||
msgid "Select the polyclinic(s) for this employee"
|
msgid "Select the polyclinic(s) for this employee"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: apps/employee/models.py:21
|
#: apps/employee/models.py:36
|
||||||
msgid "Phone number"
|
msgid "Phone number"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: apps/employee/models.py:21
|
#: apps/employee/models.py:36
|
||||||
msgid "The direct phone number of this employee"
|
msgid "The direct phone number of this employee"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
@ -7,7 +7,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: \n"
|
"Project-Id-Version: \n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2020-05-18 09:07+0000\n"
|
"POT-Creation-Date: 2020-06-08 13:43+0200\n"
|
||||||
"PO-Revision-Date: 2020-05-15 12:46+0200\n"
|
"PO-Revision-Date: 2020-05-15 12:46+0200\n"
|
||||||
"Last-Translator: Joshua Rubingh <j.g.rubingh@rug.nl>\n"
|
"Last-Translator: Joshua Rubingh <j.g.rubingh@rug.nl>\n"
|
||||||
"Language-Team: \n"
|
"Language-Team: \n"
|
||||||
@ -18,6 +18,10 @@ msgstr ""
|
|||||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||||
"X-Generator: Poedit 2.0.6\n"
|
"X-Generator: Poedit 2.0.6\n"
|
||||||
|
|
||||||
|
#: apps/employee/admin.py:13 apps/employee/models.py:28
|
||||||
|
msgid "employee"
|
||||||
|
msgstr "medewerker"
|
||||||
|
|
||||||
#: apps/employee/apps.py:7
|
#: apps/employee/apps.py:7
|
||||||
msgid "Employee"
|
msgid "Employee"
|
||||||
msgstr "Medewerker"
|
msgstr "Medewerker"
|
||||||
@ -26,30 +30,26 @@ msgstr "Medewerker"
|
|||||||
msgid "Employees"
|
msgid "Employees"
|
||||||
msgstr "Medewerkers"
|
msgstr "Medewerkers"
|
||||||
|
|
||||||
#: apps/employee/models.py:13
|
#: apps/employee/models.py:29
|
||||||
msgid "employee"
|
|
||||||
msgstr "medewerker"
|
|
||||||
|
|
||||||
#: apps/employee/models.py:14
|
|
||||||
msgid "employees"
|
msgid "employees"
|
||||||
msgstr "medewerkers"
|
msgstr "medewerkers"
|
||||||
|
|
||||||
#: apps/employee/models.py:16
|
#: apps/employee/models.py:31
|
||||||
msgid "Django user"
|
msgid "Django user"
|
||||||
msgstr "Django gebruiker"
|
msgstr "Django gebruiker"
|
||||||
|
|
||||||
#: apps/employee/models.py:18
|
#: apps/employee/models.py:33
|
||||||
msgid "Select the hospital for this employee"
|
msgid "Select the hospital for this employee"
|
||||||
msgstr "Selecteer het ziekenhuis voor deze medewerker"
|
msgstr "Selecteer het ziekenhuis voor deze medewerker"
|
||||||
|
|
||||||
#: apps/employee/models.py:20
|
#: apps/employee/models.py:35
|
||||||
msgid "Select the polyclinic(s) for this employee"
|
msgid "Select the polyclinic(s) for this employee"
|
||||||
msgstr "Selecteer de poliklinieken voor deze medewerker"
|
msgstr "Selecteer de poliklinieken voor deze medewerker"
|
||||||
|
|
||||||
#: apps/employee/models.py:21
|
#: apps/employee/models.py:36
|
||||||
msgid "Phone number"
|
msgid "Phone number"
|
||||||
msgstr "Telefoonummer"
|
msgstr "Telefoonummer"
|
||||||
|
|
||||||
#: apps/employee/models.py:21
|
#: apps/employee/models.py:36
|
||||||
msgid "The direct phone number of this employee"
|
msgid "The direct phone number of this employee"
|
||||||
msgstr "Het directe telefoonnummer van deze werknemer"
|
msgstr "Het directe telefoonnummer van deze werknemer"
|
||||||
|
@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 3.0.6 on 2020-05-18 12:27
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('employee', '0002_auto_20200518_0902'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='employee',
|
||||||
|
name='phone',
|
||||||
|
field=models.CharField(blank=True, help_text='The direct phone number of this employee', max_length=20, verbose_name='Phone number'),
|
||||||
|
),
|
||||||
|
]
|
@ -0,0 +1,26 @@
|
|||||||
|
# Generated by Django 3.0.6 on 2020-05-19 13:51
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('hospital', '0003_auto_20200518_1227'),
|
||||||
|
('polyclinic', '0003_auto_20200518_1227'),
|
||||||
|
('employee', '0003_auto_20200518_1227'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='employee',
|
||||||
|
name='hospital',
|
||||||
|
field=models.ForeignKey(help_text='Select the hospital for this employee', on_delete=django.db.models.deletion.CASCADE, to='hospital.Hospital', verbose_name='hospital'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='employee',
|
||||||
|
name='polyclinic',
|
||||||
|
field=models.ManyToManyField(blank=True, help_text='Select the polyclinic(s) for this employee', to='polyclinic.Polyclinic', verbose_name='polyclinic'),
|
||||||
|
),
|
||||||
|
]
|
@ -8,6 +8,21 @@ from apps.polyclinic.models import Polyclinic
|
|||||||
|
|
||||||
# Create your models here.
|
# Create your models here.
|
||||||
class Employee(MetaDataModel):
|
class Employee(MetaDataModel):
|
||||||
|
"""
|
||||||
|
A model that holds the employee information that is not available in the normal user model. It has a One To One relation with the Djano User model
|
||||||
|
It will inherit the attributes :attr:`~lib.models.base.MetaDataModel.created_at` and :attr:`~lib.models.base.MetaDataModel.updated_at` from the Abstract model :class:`~lib.models.base.MetaDataModel`
|
||||||
|
|
||||||
|
Attributes
|
||||||
|
----------
|
||||||
|
user : :class:`~django.contrib.auth.models.User`
|
||||||
|
The Django User model that is the employee.
|
||||||
|
hospital : Hospital
|
||||||
|
The hospital where this employee is working. You can only choose **one** hospital per employee.
|
||||||
|
polyclinic : Polyclinic
|
||||||
|
The polyclinic where this employee is working within the hospital. It is possible to have / work for multiple polyclinics.
|
||||||
|
phone : str
|
||||||
|
Holds the direct phone number of this employee. Max length is 20 characters.
|
||||||
|
"""
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = _('employee')
|
verbose_name = _('employee')
|
||||||
@ -15,11 +30,11 @@ class Employee(MetaDataModel):
|
|||||||
|
|
||||||
user = models.OneToOneField(User, on_delete=models.CASCADE, help_text=_('Django user'))
|
user = models.OneToOneField(User, on_delete=models.CASCADE, help_text=_('Django user'))
|
||||||
|
|
||||||
hospital = models.ForeignKey(Hospital, on_delete=models.CASCADE, help_text=_('Select the hospital for this employee'))
|
hospital = models.ForeignKey(Hospital, verbose_name=Hospital._meta.verbose_name, on_delete=models.CASCADE, help_text=_('Select the hospital for this employee'))
|
||||||
|
|
||||||
polyclinic = models.ManyToManyField(Polyclinic, blank=True, help_text=_('Select the polyclinic(s) for this employee'))
|
polyclinic = models.ManyToManyField(Polyclinic, verbose_name=Polyclinic._meta.verbose_name, blank=True, help_text=_('Select the polyclinic(s) for this employee'))
|
||||||
phone = models.CharField(_('Phone number'), max_length=15, blank=True, help_text=_('The direct phone number of this employee'))
|
phone = models.CharField(_('Phone number'), max_length=20, blank=True, help_text=_('The direct phone number of this employee'))
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
"""str: Returns a readable name for the hospital. Format is [hospital_name] ([city])."""
|
"""str: Returns a readable name for the employee. Format is [employee_full_name] ([city])."""
|
||||||
return '{} ({})'.format(self.user.get_full_name(), self.hospital)
|
return '{} ({})'.format(self.user.get_full_name(), self.hospital)
|
||||||
|
@ -8,7 +8,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2020-05-18 09:07+0000\n"
|
"POT-Creation-Date: 2020-06-08 13:43+0200\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
@ -26,50 +26,50 @@ msgstr ""
|
|||||||
msgid "Hospitals"
|
msgid "Hospitals"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: apps/hospital/models.py:10
|
#: apps/hospital/models.py:27
|
||||||
msgid "hospital"
|
msgid "hospital"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: apps/hospital/models.py:11
|
#: apps/hospital/models.py:28
|
||||||
msgid "hospitals"
|
msgid "hospitals"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: apps/hospital/models.py:13
|
#: apps/hospital/models.py:30
|
||||||
msgid "Name"
|
msgid "Name"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: apps/hospital/models.py:13
|
#: apps/hospital/models.py:30
|
||||||
msgid "The name of this hospital"
|
msgid "The name of this hospital"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: apps/hospital/models.py:14
|
#: apps/hospital/models.py:31
|
||||||
msgid "Address"
|
msgid "Address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: apps/hospital/models.py:14
|
#: apps/hospital/models.py:31
|
||||||
msgid "The address of this hospital"
|
msgid "The address of this hospital"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: apps/hospital/models.py:15
|
#: apps/hospital/models.py:32
|
||||||
msgid "Postal code"
|
msgid "Postal code"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: apps/hospital/models.py:15
|
#: apps/hospital/models.py:32
|
||||||
msgid "The postal code of this hospital"
|
msgid "The postal code of this hospital"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: apps/hospital/models.py:16
|
#: apps/hospital/models.py:33
|
||||||
msgid "City"
|
msgid "City"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: apps/hospital/models.py:16
|
#: apps/hospital/models.py:33
|
||||||
msgid "The city of this hospital"
|
msgid "The city of this hospital"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: apps/hospital/models.py:17
|
#: apps/hospital/models.py:34
|
||||||
msgid "Phone number"
|
msgid "Phone number"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: apps/hospital/models.py:17
|
#: apps/hospital/models.py:34
|
||||||
msgid "The general phone number of this hospital"
|
msgid "The general phone number of this hospital"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
@ -7,7 +7,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: \n"
|
"Project-Id-Version: \n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2020-05-18 09:07+0000\n"
|
"POT-Creation-Date: 2020-06-08 13:43+0200\n"
|
||||||
"PO-Revision-Date: 2020-05-15 12:43+0200\n"
|
"PO-Revision-Date: 2020-05-15 12:43+0200\n"
|
||||||
"Last-Translator: Joshua Rubingh <j.g.rubingh@rug.nl>\n"
|
"Last-Translator: Joshua Rubingh <j.g.rubingh@rug.nl>\n"
|
||||||
"Language-Team: \n"
|
"Language-Team: \n"
|
||||||
@ -26,50 +26,50 @@ msgstr "Ziekenhuis"
|
|||||||
msgid "Hospitals"
|
msgid "Hospitals"
|
||||||
msgstr "Ziekenhuizen"
|
msgstr "Ziekenhuizen"
|
||||||
|
|
||||||
#: apps/hospital/models.py:10
|
#: apps/hospital/models.py:27
|
||||||
msgid "hospital"
|
msgid "hospital"
|
||||||
msgstr "ziekenhuis"
|
msgstr "ziekenhuis"
|
||||||
|
|
||||||
#: apps/hospital/models.py:11
|
#: apps/hospital/models.py:28
|
||||||
msgid "hospitals"
|
msgid "hospitals"
|
||||||
msgstr "ziekenhuizen"
|
msgstr "ziekenhuizen"
|
||||||
|
|
||||||
#: apps/hospital/models.py:13
|
#: apps/hospital/models.py:30
|
||||||
msgid "Name"
|
msgid "Name"
|
||||||
msgstr "Naam"
|
msgstr "Naam"
|
||||||
|
|
||||||
#: apps/hospital/models.py:13
|
#: apps/hospital/models.py:30
|
||||||
msgid "The name of this hospital"
|
msgid "The name of this hospital"
|
||||||
msgstr "De naam van dit ziekenhuis"
|
msgstr "De naam van dit ziekenhuis"
|
||||||
|
|
||||||
#: apps/hospital/models.py:14
|
#: apps/hospital/models.py:31
|
||||||
msgid "Address"
|
msgid "Address"
|
||||||
msgstr "Adres"
|
msgstr "Adres"
|
||||||
|
|
||||||
#: apps/hospital/models.py:14
|
#: apps/hospital/models.py:31
|
||||||
msgid "The address of this hospital"
|
msgid "The address of this hospital"
|
||||||
msgstr "Het adres van dit ziekenhuis"
|
msgstr "Het adres van dit ziekenhuis"
|
||||||
|
|
||||||
#: apps/hospital/models.py:15
|
#: apps/hospital/models.py:32
|
||||||
msgid "Postal code"
|
msgid "Postal code"
|
||||||
msgstr "Postcode"
|
msgstr "Postcode"
|
||||||
|
|
||||||
#: apps/hospital/models.py:15
|
#: apps/hospital/models.py:32
|
||||||
msgid "The postal code of this hospital"
|
msgid "The postal code of this hospital"
|
||||||
msgstr "De postcode van dit ziekenhuis"
|
msgstr "De postcode van dit ziekenhuis"
|
||||||
|
|
||||||
#: apps/hospital/models.py:16
|
#: apps/hospital/models.py:33
|
||||||
msgid "City"
|
msgid "City"
|
||||||
msgstr "Stad"
|
msgstr "Stad"
|
||||||
|
|
||||||
#: apps/hospital/models.py:16
|
#: apps/hospital/models.py:33
|
||||||
msgid "The city of this hospital"
|
msgid "The city of this hospital"
|
||||||
msgstr "De stad waar dit ziekenhuis gelegen is"
|
msgstr "De stad waar dit ziekenhuis gelegen is"
|
||||||
|
|
||||||
#: apps/hospital/models.py:17
|
#: apps/hospital/models.py:34
|
||||||
msgid "Phone number"
|
msgid "Phone number"
|
||||||
msgstr "Telefoonnummer"
|
msgstr "Telefoonnummer"
|
||||||
|
|
||||||
#: apps/hospital/models.py:17
|
#: apps/hospital/models.py:34
|
||||||
msgid "The general phone number of this hospital"
|
msgid "The general phone number of this hospital"
|
||||||
msgstr "Het algemene telefoonummer van dit ziekenhuis"
|
msgstr "Het algemene telefoonummer van dit ziekenhuis"
|
||||||
|
@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 3.0.6 on 2020-05-18 12:27
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('hospital', '0002_auto_20200518_0902'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='hospital',
|
||||||
|
name='phone',
|
||||||
|
field=models.CharField(blank=True, help_text='The general phone number of this hospital', max_length=20, verbose_name='Phone number'),
|
||||||
|
),
|
||||||
|
]
|
@ -5,6 +5,23 @@ from lib.models.base import MetaDataModel
|
|||||||
|
|
||||||
# Create your models here.
|
# Create your models here.
|
||||||
class Hospital(MetaDataModel):
|
class Hospital(MetaDataModel):
|
||||||
|
"""
|
||||||
|
A model that holds the hospital information. This is just basic information just for getting in contact.
|
||||||
|
It will inherit the attributes :attr:`~lib.models.base.MetaDataModel.created_at` and :attr:`~lib.models.base.MetaDataModel.updated_at` from the Abstract model :class:`~lib.models.base.MetaDataModel`
|
||||||
|
|
||||||
|
Attributes
|
||||||
|
----------
|
||||||
|
name : str
|
||||||
|
The name of the hospital. Max length is 200 characters.
|
||||||
|
address : str
|
||||||
|
The address of the hospital. Street and housenumber. Max length is 200 characters.
|
||||||
|
postal_code : str
|
||||||
|
The postcalcode of the hospital. Max length is 10 characters.
|
||||||
|
city : str
|
||||||
|
The city where this hospital is located. Max length is 60 characters.
|
||||||
|
phone : str
|
||||||
|
The general phone number of this hospital. Max length is 20 characters.
|
||||||
|
"""
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = _('hospital')
|
verbose_name = _('hospital')
|
||||||
@ -14,7 +31,7 @@ class Hospital(MetaDataModel):
|
|||||||
address = models.CharField(_('Address'), max_length=200, blank=True, help_text=_('The address of this hospital'))
|
address = models.CharField(_('Address'), max_length=200, blank=True, help_text=_('The address of this hospital'))
|
||||||
postal_code = models.CharField(_('Postal code'), max_length=10, blank=True, help_text=_('The postal code of this hospital'))
|
postal_code = models.CharField(_('Postal code'), max_length=10, blank=True, help_text=_('The postal code of this hospital'))
|
||||||
city = models.CharField(_('City'), max_length=60, blank=True, help_text=_('The city of this hospital'))
|
city = models.CharField(_('City'), max_length=60, blank=True, help_text=_('The city of this hospital'))
|
||||||
phone = models.CharField(_('Phone number'), max_length=18, blank=True, help_text=_('The general phone number of this hospital'))
|
phone = models.CharField(_('Phone number'), max_length=20, blank=True, help_text=_('The general phone number of this hospital'))
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
"""str: Returns a readable name for the hospital. Format is [hospital_name] ([city])."""
|
"""str: Returns a readable name for the hospital. Format is [hospital_name] ([city])."""
|
||||||
|
@ -8,7 +8,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2020-05-18 09:07+0000\n"
|
"POT-Creation-Date: 2020-06-08 13:43+0200\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
@ -26,30 +26,30 @@ msgstr ""
|
|||||||
msgid "Polyclinics"
|
msgid "Polyclinics"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: apps/polyclinic/models.py:11
|
#: apps/polyclinic/models.py:24
|
||||||
msgid "polyclinic"
|
msgid "polyclinic"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: apps/polyclinic/models.py:12
|
#: apps/polyclinic/models.py:25
|
||||||
msgid "polyclinics"
|
msgid "polyclinics"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: apps/polyclinic/models.py:14
|
#: apps/polyclinic/models.py:27
|
||||||
msgid "To which hospital belongs this polyclinic"
|
msgid "To which hospital belongs this polyclinic"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: apps/polyclinic/models.py:15
|
#: apps/polyclinic/models.py:28
|
||||||
msgid "Name"
|
msgid "Name"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: apps/polyclinic/models.py:15
|
#: apps/polyclinic/models.py:28
|
||||||
msgid "The name of this polyclinic"
|
msgid "The name of this polyclinic"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: apps/polyclinic/models.py:16
|
#: apps/polyclinic/models.py:29
|
||||||
msgid "Phone number"
|
msgid "Phone number"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: apps/polyclinic/models.py:16
|
#: apps/polyclinic/models.py:29
|
||||||
msgid "The general/direct phone number of this polyclinic"
|
msgid "The general/direct phone number of this polyclinic"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
@ -7,7 +7,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: \n"
|
"Project-Id-Version: \n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2020-05-18 09:07+0000\n"
|
"POT-Creation-Date: 2020-06-08 13:43+0200\n"
|
||||||
"PO-Revision-Date: 2020-05-15 12:47+0200\n"
|
"PO-Revision-Date: 2020-05-15 12:47+0200\n"
|
||||||
"Last-Translator: Joshua Rubingh <j.g.rubingh@rug.nl>\n"
|
"Last-Translator: Joshua Rubingh <j.g.rubingh@rug.nl>\n"
|
||||||
"Language-Team: \n"
|
"Language-Team: \n"
|
||||||
@ -26,30 +26,30 @@ msgstr "Polikliniek"
|
|||||||
msgid "Polyclinics"
|
msgid "Polyclinics"
|
||||||
msgstr "Poliklinieken"
|
msgstr "Poliklinieken"
|
||||||
|
|
||||||
#: apps/polyclinic/models.py:11
|
#: apps/polyclinic/models.py:24
|
||||||
msgid "polyclinic"
|
msgid "polyclinic"
|
||||||
msgstr "polikliniek"
|
msgstr "polikliniek"
|
||||||
|
|
||||||
#: apps/polyclinic/models.py:12
|
#: apps/polyclinic/models.py:25
|
||||||
msgid "polyclinics"
|
msgid "polyclinics"
|
||||||
msgstr "poliklinieken"
|
msgstr "poliklinieken"
|
||||||
|
|
||||||
#: apps/polyclinic/models.py:14
|
#: apps/polyclinic/models.py:27
|
||||||
msgid "To which hospital belongs this polyclinic"
|
msgid "To which hospital belongs this polyclinic"
|
||||||
msgstr "Bij welke ziekenhuis hoort deze polikliniek"
|
msgstr "Bij welke ziekenhuis hoort deze polikliniek"
|
||||||
|
|
||||||
#: apps/polyclinic/models.py:15
|
#: apps/polyclinic/models.py:28
|
||||||
msgid "Name"
|
msgid "Name"
|
||||||
msgstr "Naam"
|
msgstr "Naam"
|
||||||
|
|
||||||
#: apps/polyclinic/models.py:15
|
#: apps/polyclinic/models.py:28
|
||||||
msgid "The name of this polyclinic"
|
msgid "The name of this polyclinic"
|
||||||
msgstr "De naam van deze polikliniek"
|
msgstr "De naam van deze polikliniek"
|
||||||
|
|
||||||
#: apps/polyclinic/models.py:16
|
#: apps/polyclinic/models.py:29
|
||||||
msgid "Phone number"
|
msgid "Phone number"
|
||||||
msgstr "Telefoonnummer"
|
msgstr "Telefoonnummer"
|
||||||
|
|
||||||
#: apps/polyclinic/models.py:16
|
#: apps/polyclinic/models.py:29
|
||||||
msgid "The general/direct phone number of this polyclinic"
|
msgid "The general/direct phone number of this polyclinic"
|
||||||
msgstr "De algemene/directe telefoonnummer van deze polikliniek"
|
msgstr "De algemene/directe telefoonnummer van deze polikliniek"
|
||||||
|
@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 3.0.6 on 2020-05-18 12:27
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('polyclinic', '0002_auto_20200518_0902'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='polyclinic',
|
||||||
|
name='phone',
|
||||||
|
field=models.CharField(blank=True, help_text='The general/direct phone number of this polyclinic', max_length=20, verbose_name='Phone number'),
|
||||||
|
),
|
||||||
|
]
|
@ -0,0 +1,20 @@
|
|||||||
|
# Generated by Django 3.0.6 on 2020-05-19 13:51
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('hospital', '0003_auto_20200518_1227'),
|
||||||
|
('polyclinic', '0003_auto_20200518_1227'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='polyclinic',
|
||||||
|
name='hospital',
|
||||||
|
field=models.ForeignKey(help_text='To which hospital belongs this polyclinic', on_delete=django.db.models.deletion.CASCADE, to='hospital.Hospital', verbose_name='hospital'),
|
||||||
|
),
|
||||||
|
]
|
@ -6,15 +6,28 @@ from apps.hospital.models import Hospital
|
|||||||
# Create your models here.
|
# Create your models here.
|
||||||
|
|
||||||
class Polyclinic(MetaDataModel):
|
class Polyclinic(MetaDataModel):
|
||||||
|
"""
|
||||||
|
A model that holds the polyclinic information. This is just basic information just for getting in contact.
|
||||||
|
It will inherit the attributes :attr:`~lib.models.base.MetaDataModel.created_at` and :attr:`~lib.models.base.MetaDataModel.updated_at` from the Abstract model :class:`~lib.models.base.MetaDataModel`
|
||||||
|
|
||||||
|
Attributes
|
||||||
|
----------
|
||||||
|
hospital : Hospital
|
||||||
|
The hospital where this polyclinic belongs to.
|
||||||
|
name : str
|
||||||
|
The name of the polyclinic. Max length is 200 characters.
|
||||||
|
phone : str
|
||||||
|
The general/direct phone number of this polyclinic. Max length is 20 characters.
|
||||||
|
"""
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = _('polyclinic')
|
verbose_name = _('polyclinic')
|
||||||
verbose_name_plural = _('polyclinics')
|
verbose_name_plural = _('polyclinics')
|
||||||
|
|
||||||
hospital = models.ForeignKey(Hospital, on_delete=models.CASCADE, help_text=_('To which hospital belongs this polyclinic'))
|
hospital = models.ForeignKey(Hospital, verbose_name=Hospital._meta.verbose_name, on_delete=models.CASCADE, help_text=_('To which hospital belongs this polyclinic'))
|
||||||
name = models.CharField(_('Name'), max_length=200, blank=True, help_text=_('The name of this polyclinic'))
|
name = models.CharField(_('Name'), max_length=200, blank=True, help_text=_('The name of this polyclinic'))
|
||||||
phone = models.CharField(_('Phone number'), max_length=18, blank=True, help_text=_('The general/direct phone number of this polyclinic'))
|
phone = models.CharField(_('Phone number'), max_length=20, blank=True, help_text=_('The general/direct phone number of this polyclinic'))
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
"""str: Returns a readable name for the hospital. Format is [hospital_name] ([city])."""
|
"""str: Returns a readable name for the polyclinic. Format is [polyclinic_name] ([hospital_name])."""
|
||||||
return '{} ({})'.format(self.name, self.hospital)
|
return '{} ({})'.format(self.name, self.hospital)
|
||||||
|
@ -1,15 +1,18 @@
|
|||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
from .models import Schedule
|
from .models import Schedule
|
||||||
|
|
||||||
# Register your models here.
|
# Register your models here.
|
||||||
@admin.register(Schedule)
|
@admin.register(Schedule)
|
||||||
class ScheduleAdmin(admin.ModelAdmin):
|
class ScheduleAdmin(admin.ModelAdmin):
|
||||||
list_display = ('name', 'employee', 'email', 'created_at', 'processed')
|
list_display = ('name', 'employee', 'email', 'created_at', 'status','done')
|
||||||
ordering = ('name', 'created_at')
|
ordering = ('-created_at', 'name',)
|
||||||
search_fields = ('name', 'email')
|
search_fields = ('name', 'email')
|
||||||
|
list_filter = ('status',)
|
||||||
|
|
||||||
def processed(self,obj):
|
def done(self,obj):
|
||||||
return len(obj.output_peregrine) > 0
|
return obj.done
|
||||||
|
|
||||||
processed.boolean = True
|
done.boolean = True
|
||||||
|
done.short_description = _('Done')
|
||||||
|
@ -4,6 +4,7 @@ from django.utils.translation import gettext_lazy as _
|
|||||||
from .models import Schedule
|
from .models import Schedule
|
||||||
|
|
||||||
class ScheduleForm(forms.Form):
|
class ScheduleForm(forms.Form):
|
||||||
name = forms.CharField(label=_('Department name'), help_text=_('Enter a descriptive name for this schedule'), max_length=100)
|
name = forms.CharField(label=_('Department name'), help_text=_('Enter a descriptive name for this schedule'), max_length=100)
|
||||||
email = forms.CharField(label=_('Email address for results'), help_text=_('When the job is done, the results will be sent to this email address'), max_length=100)
|
email = forms.CharField(label=_('Email address for results'), help_text=_('When the job is done, the results will be sent to this email address'), max_length=100)
|
||||||
json = forms.CharField(label=_('Email address for results'), help_text=_('When the job is done, the results will be sent to this email address'), widget=forms.HiddenInput(), strip=True)
|
json = forms.CharField(label=_('JSON form data'), help_text=_('The RAW JSON data of the saved form'), widget=forms.HiddenInput(), strip=True)
|
||||||
|
status = forms.CharField(label=_('Status'), help_text=_('The status of this schedule.'), max_length=10, widget=forms.HiddenInput() )
|
@ -8,7 +8,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2020-05-18 09:07+0000\n"
|
"POT-Creation-Date: 2020-06-08 13:43+0200\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
@ -18,6 +18,10 @@ msgstr ""
|
|||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||||
|
|
||||||
|
#: apps/schedule/admin.py:18 apps/schedule/models.py:75
|
||||||
|
msgid "Done"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: apps/schedule/apps.py:7
|
#: apps/schedule/apps.py:7
|
||||||
msgid "Schedule"
|
msgid "Schedule"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@ -34,97 +38,125 @@ msgstr ""
|
|||||||
msgid "Enter a descriptive name for this schedule"
|
msgid "Enter a descriptive name for this schedule"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: apps/schedule/forms.py:8 apps/schedule/forms.py:9
|
#: apps/schedule/forms.py:8
|
||||||
msgid "Email address for results"
|
msgid "Email address for results"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: apps/schedule/forms.py:8 apps/schedule/forms.py:9
|
#: apps/schedule/forms.py:8
|
||||||
msgid "When the job is done, the results will be sent to this email address"
|
msgid "When the job is done, the results will be sent to this email address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: apps/schedule/models.py:14
|
#: apps/schedule/forms.py:9
|
||||||
|
msgid "JSON form data"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: apps/schedule/forms.py:9
|
||||||
|
msgid "The RAW JSON data of the saved form"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: apps/schedule/forms.py:10 apps/schedule/models.py:84
|
||||||
|
#: apps/schedule/templates/schedule/schedule_list.html:16
|
||||||
|
msgid "Status"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: apps/schedule/forms.py:10 apps/schedule/models.py:84
|
||||||
|
msgid "The status of this schedule."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: apps/schedule/models.py:31
|
||||||
msgid "schedule"
|
msgid "schedule"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: apps/schedule/models.py:15
|
#: apps/schedule/models.py:32
|
||||||
msgid "schedules"
|
msgid "schedules"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: apps/schedule/models.py:18
|
#: apps/schedule/models.py:70
|
||||||
|
msgid "Draft"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: apps/schedule/models.py:71
|
||||||
|
msgid "New"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: apps/schedule/models.py:72
|
||||||
|
msgid "Accepted"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: apps/schedule/models.py:73
|
||||||
|
msgid "Processing"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: apps/schedule/models.py:74
|
||||||
|
msgid "Processed"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: apps/schedule/models.py:76
|
||||||
|
msgid "Invalid"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: apps/schedule/models.py:77
|
||||||
|
msgid "Failure"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: apps/schedule/models.py:79
|
||||||
msgid "Select the employee that is responsible for this schedule request"
|
msgid "Select the employee that is responsible for this schedule request"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: apps/schedule/models.py:20
|
#: apps/schedule/models.py:81
|
||||||
#: apps/schedule/templates/schedule/schedule_list.html:13
|
#: apps/schedule/templates/schedule/schedule_list.html:13
|
||||||
msgid "Name"
|
msgid "Name"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: apps/schedule/models.py:20
|
#: apps/schedule/models.py:81
|
||||||
msgid "Name of the schedule"
|
msgid "Name of the schedule"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: apps/schedule/models.py:21
|
#: apps/schedule/models.py:82
|
||||||
msgid "Email address"
|
msgid "Email address"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: apps/schedule/models.py:21
|
#: apps/schedule/models.py:82
|
||||||
msgid "Email address where the results will be sent to."
|
msgid "Email address where the results will be sent to."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: apps/schedule/models.py:23
|
#: apps/schedule/models.py:86
|
||||||
msgid "Schedule input"
|
msgid "Schedule input"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: apps/schedule/models.py:23
|
#: apps/schedule/models.py:86
|
||||||
msgid "The schedule input in JSON format based on the form data"
|
msgid "The schedule input in JSON format based on the form data"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: apps/schedule/models.py:25
|
#: apps/schedule/models.py:88
|
||||||
msgid "Peregrine input"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: apps/schedule/models.py:25
|
|
||||||
msgid ""
|
|
||||||
"This is the translated content from the source for use with Peregrine cluster"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: apps/schedule/models.py:27
|
|
||||||
msgid "Peregrine accepted"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: apps/schedule/models.py:27
|
|
||||||
msgid "When true, the Peregrine cluster has picked up the job."
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: apps/schedule/models.py:29
|
|
||||||
msgid "Peregrine JSON output"
|
msgid "Peregrine JSON output"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: apps/schedule/models.py:29
|
#: apps/schedule/models.py:88
|
||||||
msgid "The results from the Peregrine job in JSON"
|
msgid "The results from the Peregrine job in JSON"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: apps/schedule/models.py:31
|
#: apps/schedule/models.py:90
|
||||||
msgid "Peregrine binary output"
|
msgid "Peregrine binary output"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: apps/schedule/models.py:31
|
#: apps/schedule/models.py:90
|
||||||
msgid "This is the output in binary format from the Peregrine cluster"
|
msgid "This is the output in binary format from the Peregrine cluster"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: apps/schedule/models.py:33
|
#: apps/schedule/models.py:92
|
||||||
msgid "Report is send to user"
|
msgid "Report is send to user"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: apps/schedule/models.py:33
|
#: apps/schedule/models.py:92
|
||||||
msgid "The date and time when the report has sended to the user."
|
msgid "The date and time when the report has sended to the user."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: apps/schedule/models.py:35
|
#: apps/schedule/models.py:94
|
||||||
msgid "Peregrine logging"
|
msgid "Peregrine logging"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: apps/schedule/models.py:35
|
#: apps/schedule/models.py:94
|
||||||
msgid "Here you can see the logging of the Peregrine job."
|
msgid "Here you can see the logging of the Peregrine job."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -142,19 +174,49 @@ msgstr ""
|
|||||||
msgid "Updated"
|
msgid "Updated"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: apps/schedule/templates/schedule/schedule_list.html:16
|
|
||||||
msgid "Running"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: apps/schedule/templates/schedule/schedule_list.html:17
|
#: apps/schedule/templates/schedule/schedule_list.html:17
|
||||||
msgid "Report"
|
msgid "Report"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: apps/schedule/templates/schedule/schedule_list.html:18
|
||||||
|
msgid "Actions"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: apps/schedule/templates/schedule/schedule_list.html:33
|
#: apps/schedule/templates/schedule/schedule_list.html:33
|
||||||
|
msgid "Resume"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: apps/schedule/templates/schedule/schedule_list.html:35
|
||||||
|
msgid "Clone"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: apps/schedule/templates/schedule/schedule_list.html:41
|
||||||
msgid "No schedules available"
|
msgid "No schedules available"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: apps/schedule/templates/schedule/schedule_new.html:5
|
#: apps/schedule/templates/schedule/schedule_new.html:7
|
||||||
#: apps/schedule/templates/schedule/schedule_new.html:6
|
#: apps/schedule/templates/schedule/schedule_new.html:16
|
||||||
|
msgid "Resume schedule"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: apps/schedule/templates/schedule/schedule_new.html:9
|
||||||
|
#: apps/schedule/templates/schedule/schedule_new.html:18
|
||||||
|
msgid "Clone schedule"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: apps/schedule/templates/schedule/schedule_new.html:11
|
||||||
|
#: apps/schedule/templates/schedule/schedule_new.html:20
|
||||||
msgid "New schedule"
|
msgid "New schedule"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: apps/schedule/templates/schedule/schedule_new.html:432
|
||||||
|
msgid "Save as draft"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: apps/schedule/templates/schedule/schedule_new.html:434
|
||||||
|
msgid "Submit"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: apps/schedule/templates/schedule/schedule_new.html:821
|
||||||
|
msgid "and"
|
||||||
|
msgstr ""
|
||||||
|
@ -7,8 +7,8 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: \n"
|
"Project-Id-Version: \n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2020-05-18 09:07+0000\n"
|
"POT-Creation-Date: 2020-06-08 13:43+0200\n"
|
||||||
"PO-Revision-Date: 2020-05-18 11:08+0200\n"
|
"PO-Revision-Date: 2020-06-08 13:44+0200\n"
|
||||||
"Last-Translator: Joshua Rubingh <j.g.rubingh@rug.nl>\n"
|
"Last-Translator: Joshua Rubingh <j.g.rubingh@rug.nl>\n"
|
||||||
"Language-Team: \n"
|
"Language-Team: \n"
|
||||||
"Language: nl\n"
|
"Language: nl\n"
|
||||||
@ -18,6 +18,10 @@ msgstr ""
|
|||||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||||
"X-Generator: Poedit 2.0.6\n"
|
"X-Generator: Poedit 2.0.6\n"
|
||||||
|
|
||||||
|
#: apps/schedule/admin.py:18 apps/schedule/models.py:75
|
||||||
|
msgid "Done"
|
||||||
|
msgstr "Klaar"
|
||||||
|
|
||||||
#: apps/schedule/apps.py:7
|
#: apps/schedule/apps.py:7
|
||||||
msgid "Schedule"
|
msgid "Schedule"
|
||||||
msgstr "Rooster"
|
msgstr "Rooster"
|
||||||
@ -34,96 +38,125 @@ msgstr "Afdelingsnaam"
|
|||||||
msgid "Enter a descriptive name for this schedule"
|
msgid "Enter a descriptive name for this schedule"
|
||||||
msgstr "Voer een beschrijvende naam in voor dit schema"
|
msgstr "Voer een beschrijvende naam in voor dit schema"
|
||||||
|
|
||||||
#: apps/schedule/forms.py:8 apps/schedule/forms.py:9
|
#: apps/schedule/forms.py:8
|
||||||
msgid "Email address for results"
|
msgid "Email address for results"
|
||||||
msgstr "E-mailadres voor resultaten"
|
msgstr "E-mailadres voor resultaten"
|
||||||
|
|
||||||
#: apps/schedule/forms.py:8 apps/schedule/forms.py:9
|
#: apps/schedule/forms.py:8
|
||||||
msgid "When the job is done, the results will be sent to this email address"
|
msgid "When the job is done, the results will be sent to this email address"
|
||||||
msgstr "Als de klus geklaard is, worden de resultaten naar dit e-mailadres gestuurd"
|
msgstr "Als de klus geklaard is, worden de resultaten naar dit e-mailadres gestuurd"
|
||||||
|
|
||||||
#: apps/schedule/models.py:14
|
#: apps/schedule/forms.py:9
|
||||||
|
msgid "JSON form data"
|
||||||
|
msgstr "JSON formulier data"
|
||||||
|
|
||||||
|
#: apps/schedule/forms.py:9
|
||||||
|
msgid "The RAW JSON data of the saved form"
|
||||||
|
msgstr "De rauwe JSON data van het opgeslagen formulier"
|
||||||
|
|
||||||
|
#: apps/schedule/forms.py:10 apps/schedule/models.py:84
|
||||||
|
#: apps/schedule/templates/schedule/schedule_list.html:16
|
||||||
|
msgid "Status"
|
||||||
|
msgstr "Status"
|
||||||
|
|
||||||
|
#: apps/schedule/forms.py:10 apps/schedule/models.py:84
|
||||||
|
msgid "The status of this schedule."
|
||||||
|
msgstr "De status van dit rooster."
|
||||||
|
|
||||||
|
#: apps/schedule/models.py:31
|
||||||
msgid "schedule"
|
msgid "schedule"
|
||||||
msgstr "rooster"
|
msgstr "rooster"
|
||||||
|
|
||||||
#: apps/schedule/models.py:15
|
#: apps/schedule/models.py:32
|
||||||
msgid "schedules"
|
msgid "schedules"
|
||||||
msgstr "roosters"
|
msgstr "roosters"
|
||||||
|
|
||||||
#: apps/schedule/models.py:18
|
#: apps/schedule/models.py:70
|
||||||
|
msgid "Draft"
|
||||||
|
msgstr "Concept"
|
||||||
|
|
||||||
|
#: apps/schedule/models.py:71
|
||||||
|
msgid "New"
|
||||||
|
msgstr "Nieuw"
|
||||||
|
|
||||||
|
#: apps/schedule/models.py:72
|
||||||
|
msgid "Accepted"
|
||||||
|
msgstr "Geaccepteerd"
|
||||||
|
|
||||||
|
#: apps/schedule/models.py:73
|
||||||
|
msgid "Processing"
|
||||||
|
msgstr "Verwerken"
|
||||||
|
|
||||||
|
#: apps/schedule/models.py:74
|
||||||
|
msgid "Processed"
|
||||||
|
msgstr "Verwerkt"
|
||||||
|
|
||||||
|
#: apps/schedule/models.py:76
|
||||||
|
msgid "Invalid"
|
||||||
|
msgstr "Ongeldig"
|
||||||
|
|
||||||
|
#: apps/schedule/models.py:77
|
||||||
|
msgid "Failure"
|
||||||
|
msgstr "Error"
|
||||||
|
|
||||||
|
#: apps/schedule/models.py:79
|
||||||
msgid "Select the employee that is responsible for this schedule request"
|
msgid "Select the employee that is responsible for this schedule request"
|
||||||
msgstr "Selecteer de medewerker die verantwoordelijk is voor dit roosterverzoek"
|
msgstr "Selecteer de medewerker die verantwoordelijk is voor dit roosterverzoek"
|
||||||
|
|
||||||
#: apps/schedule/models.py:20
|
#: apps/schedule/models.py:81
|
||||||
#: apps/schedule/templates/schedule/schedule_list.html:13
|
#: apps/schedule/templates/schedule/schedule_list.html:13
|
||||||
msgid "Name"
|
msgid "Name"
|
||||||
msgstr "Naam"
|
msgstr "Naam"
|
||||||
|
|
||||||
#: apps/schedule/models.py:20
|
#: apps/schedule/models.py:81
|
||||||
msgid "Name of the schedule"
|
msgid "Name of the schedule"
|
||||||
msgstr "Naam van de rooster"
|
msgstr "Naam van de rooster"
|
||||||
|
|
||||||
#: apps/schedule/models.py:21
|
#: apps/schedule/models.py:82
|
||||||
msgid "Email address"
|
msgid "Email address"
|
||||||
msgstr "E-mailadres"
|
msgstr "E-mailadres"
|
||||||
|
|
||||||
#: apps/schedule/models.py:21
|
#: apps/schedule/models.py:82
|
||||||
msgid "Email address where the results will be sent to."
|
msgid "Email address where the results will be sent to."
|
||||||
msgstr "E-mailadres waar de resultaten naartoe worden gestuurd."
|
msgstr "E-mailadres waar de resultaten naartoe worden gestuurd."
|
||||||
|
|
||||||
#: apps/schedule/models.py:23
|
#: apps/schedule/models.py:86
|
||||||
msgid "Schedule input"
|
msgid "Schedule input"
|
||||||
msgstr "Rooster invoer"
|
msgstr "Rooster invoer"
|
||||||
|
|
||||||
#: apps/schedule/models.py:23
|
#: apps/schedule/models.py:86
|
||||||
msgid "The schedule input in JSON format based on the form data"
|
msgid "The schedule input in JSON format based on the form data"
|
||||||
msgstr "De rooster invoer in JSON-indeling op basis van de formuliergegevens"
|
msgstr "De rooster invoer in JSON-indeling op basis van de formuliergegevens"
|
||||||
|
|
||||||
#: apps/schedule/models.py:25
|
#: apps/schedule/models.py:88
|
||||||
msgid "Peregrine input"
|
|
||||||
msgstr "Peregrine invoer"
|
|
||||||
|
|
||||||
#: apps/schedule/models.py:25
|
|
||||||
msgid "This is the translated content from the source for use with Peregrine cluster"
|
|
||||||
msgstr "Dit is de vertaalde inhoud van de bron voor gebruik met Peregrine-cluster"
|
|
||||||
|
|
||||||
#: apps/schedule/models.py:27
|
|
||||||
msgid "Peregrine accepted"
|
|
||||||
msgstr "Peregrine geaccepteerd"
|
|
||||||
|
|
||||||
#: apps/schedule/models.py:27
|
|
||||||
msgid "When true, the Peregrine cluster has picked up the job."
|
|
||||||
msgstr "Als het waar is, heeft het Peregrine-cluster de taak opgepakt."
|
|
||||||
|
|
||||||
#: apps/schedule/models.py:29
|
|
||||||
msgid "Peregrine JSON output"
|
msgid "Peregrine JSON output"
|
||||||
msgstr "Peregrine JSON uitvoer"
|
msgstr "Peregrine JSON uitvoer"
|
||||||
|
|
||||||
#: apps/schedule/models.py:29
|
#: apps/schedule/models.py:88
|
||||||
msgid "The results from the Peregrine job in JSON"
|
msgid "The results from the Peregrine job in JSON"
|
||||||
msgstr "De resultaten van de Peregrine-taak in JSON"
|
msgstr "De resultaten van de Peregrine-taak in JSON"
|
||||||
|
|
||||||
#: apps/schedule/models.py:31
|
#: apps/schedule/models.py:90
|
||||||
msgid "Peregrine binary output"
|
msgid "Peregrine binary output"
|
||||||
msgstr "Peregrine binaire uitvoer"
|
msgstr "Peregrine binaire uitvoer"
|
||||||
|
|
||||||
#: apps/schedule/models.py:31
|
#: apps/schedule/models.py:90
|
||||||
msgid "This is the output in binary format from the Peregrine cluster"
|
msgid "This is the output in binary format from the Peregrine cluster"
|
||||||
msgstr "Dit is de uitvoer in binair formaat van het Peregrine-cluster"
|
msgstr "Dit is de uitvoer in binair formaat van het Peregrine-cluster"
|
||||||
|
|
||||||
#: apps/schedule/models.py:33
|
#: apps/schedule/models.py:92
|
||||||
msgid "Report is send to user"
|
msgid "Report is send to user"
|
||||||
msgstr "Rapport is naar gebruiker gestuurd"
|
msgstr "Rapport is naar gebruiker gestuurd"
|
||||||
|
|
||||||
#: apps/schedule/models.py:33
|
#: apps/schedule/models.py:92
|
||||||
msgid "The date and time when the report has sended to the user."
|
msgid "The date and time when the report has sended to the user."
|
||||||
msgstr "De datum en tijd waarop het rapport naar de gebruiker is verzonden."
|
msgstr "De datum en tijd waarop het rapport naar de gebruiker is verzonden."
|
||||||
|
|
||||||
#: apps/schedule/models.py:35
|
#: apps/schedule/models.py:94
|
||||||
msgid "Peregrine logging"
|
msgid "Peregrine logging"
|
||||||
msgstr "Peregrine log"
|
msgstr "Peregrine log"
|
||||||
|
|
||||||
#: apps/schedule/models.py:35
|
#: apps/schedule/models.py:94
|
||||||
msgid "Here you can see the logging of the Peregrine job."
|
msgid "Here you can see the logging of the Peregrine job."
|
||||||
msgstr "Hier kunt u de logfile van de Peregrine opdracht zien."
|
msgstr "Hier kunt u de logfile van de Peregrine opdracht zien."
|
||||||
|
|
||||||
@ -141,19 +174,64 @@ msgstr "Aangemaakt"
|
|||||||
msgid "Updated"
|
msgid "Updated"
|
||||||
msgstr "Bijgewerkt"
|
msgstr "Bijgewerkt"
|
||||||
|
|
||||||
#: apps/schedule/templates/schedule/schedule_list.html:16
|
|
||||||
msgid "Running"
|
|
||||||
msgstr "Bezig"
|
|
||||||
|
|
||||||
#: apps/schedule/templates/schedule/schedule_list.html:17
|
#: apps/schedule/templates/schedule/schedule_list.html:17
|
||||||
msgid "Report"
|
msgid "Report"
|
||||||
msgstr "Rapport"
|
msgstr "Rapport"
|
||||||
|
|
||||||
|
#: apps/schedule/templates/schedule/schedule_list.html:18
|
||||||
|
msgid "Actions"
|
||||||
|
msgstr "Acties"
|
||||||
|
|
||||||
#: apps/schedule/templates/schedule/schedule_list.html:33
|
#: apps/schedule/templates/schedule/schedule_list.html:33
|
||||||
|
msgid "Resume"
|
||||||
|
msgstr "Hervat"
|
||||||
|
|
||||||
|
#: apps/schedule/templates/schedule/schedule_list.html:35
|
||||||
|
msgid "Clone"
|
||||||
|
msgstr "Dupliceer"
|
||||||
|
|
||||||
|
#: apps/schedule/templates/schedule/schedule_list.html:41
|
||||||
msgid "No schedules available"
|
msgid "No schedules available"
|
||||||
msgstr "Geen roosters beschikbaar"
|
msgstr "Geen roosters beschikbaar"
|
||||||
|
|
||||||
#: apps/schedule/templates/schedule/schedule_new.html:5
|
#: apps/schedule/templates/schedule/schedule_new.html:7
|
||||||
#: apps/schedule/templates/schedule/schedule_new.html:6
|
#: apps/schedule/templates/schedule/schedule_new.html:16
|
||||||
|
msgid "Resume schedule"
|
||||||
|
msgstr "Hervat rooster"
|
||||||
|
|
||||||
|
#: apps/schedule/templates/schedule/schedule_new.html:9
|
||||||
|
#: apps/schedule/templates/schedule/schedule_new.html:18
|
||||||
|
msgid "Clone schedule"
|
||||||
|
msgstr "Dupliceer rooster"
|
||||||
|
|
||||||
|
#: apps/schedule/templates/schedule/schedule_new.html:11
|
||||||
|
#: apps/schedule/templates/schedule/schedule_new.html:20
|
||||||
msgid "New schedule"
|
msgid "New schedule"
|
||||||
msgstr "Nieuwe rooster"
|
msgstr "Nieuwe rooster"
|
||||||
|
|
||||||
|
#: apps/schedule/templates/schedule/schedule_new.html:432
|
||||||
|
msgid "Save as draft"
|
||||||
|
msgstr "Sla op als concept"
|
||||||
|
|
||||||
|
#: apps/schedule/templates/schedule/schedule_new.html:434
|
||||||
|
msgid "Submit"
|
||||||
|
msgstr "Verstuur"
|
||||||
|
|
||||||
|
#: apps/schedule/templates/schedule/schedule_new.html:821
|
||||||
|
msgid "and"
|
||||||
|
msgstr "en"
|
||||||
|
|
||||||
|
#~ msgid "Running"
|
||||||
|
#~ msgstr "Bezig"
|
||||||
|
|
||||||
|
#~ msgid "Peregrine input"
|
||||||
|
#~ msgstr "Peregrine invoer"
|
||||||
|
|
||||||
|
#~ msgid "This is the translated content from the source for use with Peregrine cluster"
|
||||||
|
#~ msgstr "Dit is de vertaalde inhoud van de bron voor gebruik met Peregrine-cluster"
|
||||||
|
|
||||||
|
#~ msgid "Peregrine accepted"
|
||||||
|
#~ msgstr "Peregrine geaccepteerd"
|
||||||
|
|
||||||
|
#~ msgid "When true, the Peregrine cluster has picked up the job."
|
||||||
|
#~ msgstr "Als het waar is, heeft het Peregrine-cluster de taak opgepakt."
|
||||||
|
@ -0,0 +1,26 @@
|
|||||||
|
# Generated by Django 3.0.6 on 2020-05-18 14:25
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('schedule', '0003_auto_20200518_0902'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='schedule',
|
||||||
|
name='peregrine_accepted',
|
||||||
|
),
|
||||||
|
migrations.RemoveField(
|
||||||
|
model_name='schedule',
|
||||||
|
name='planning_peregrine',
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='schedule',
|
||||||
|
name='status',
|
||||||
|
field=models.CharField(choices=[('new', 'New'), ('accepted', 'Accepted'), ('processing', 'Processing'), ('processed', 'Processed'), ('done', 'Done'), ('invalid', 'Invalid'), ('failure', 'Failure')], db_index=True, default='new', help_text='The status of this schedule.', max_length=10, verbose_name='Status'),
|
||||||
|
),
|
||||||
|
]
|
@ -0,0 +1,30 @@
|
|||||||
|
# Generated by Django 3.0.6 on 2020-05-19 08:21
|
||||||
|
|
||||||
|
import collections
|
||||||
|
from django.db import migrations, models
|
||||||
|
import jsonfield.fields
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('schedule', '0004_auto_20200518_1425'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='schedule',
|
||||||
|
name='output_peregrine',
|
||||||
|
field=models.BinaryField(blank=True, help_text='This is the output in binary format from the Peregrine cluster', null=True, verbose_name='Peregrine binary output'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='schedule',
|
||||||
|
name='peregrine_result',
|
||||||
|
field=jsonfield.fields.JSONField(blank=True, help_text='The results from the Peregrine job in JSON', load_kwargs={'object_pairs_hook': collections.OrderedDict}, null=True, verbose_name='Peregrine JSON output'),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='schedule',
|
||||||
|
name='planning_source',
|
||||||
|
field=jsonfield.fields.JSONField(blank=True, help_text='The schedule input in JSON format based on the form data', load_kwargs={'object_pairs_hook': collections.OrderedDict}, null=True, verbose_name='Schedule input'),
|
||||||
|
),
|
||||||
|
]
|
@ -0,0 +1,20 @@
|
|||||||
|
# Generated by Django 3.0.6 on 2020-05-19 13:51
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('employee', '0004_auto_20200519_1351'),
|
||||||
|
('schedule', '0005_auto_20200519_0821'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='schedule',
|
||||||
|
name='employee',
|
||||||
|
field=models.ForeignKey(help_text='Select the employee that is responsible for this schedule request', on_delete=django.db.models.deletion.CASCADE, to='employee.Employee', verbose_name='employee'),
|
||||||
|
),
|
||||||
|
]
|
@ -0,0 +1,18 @@
|
|||||||
|
# Generated by Django 3.0.6 on 2020-06-08 08:53
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('schedule', '0006_auto_20200519_1351'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='schedule',
|
||||||
|
name='status',
|
||||||
|
field=models.CharField(choices=[('draft', 'Draft'), ('new', 'New'), ('accepted', 'Accepted'), ('processing', 'Processing'), ('processed', 'Processed'), ('done', 'Done'), ('invalid', 'Invalid'), ('failure', 'Failure')], db_index=True, default='new', help_text='The status of this schedule.', max_length=10, verbose_name='Status'),
|
||||||
|
),
|
||||||
|
]
|
@ -9,31 +9,104 @@ import collections
|
|||||||
|
|
||||||
# Create your models here.
|
# Create your models here.
|
||||||
class Schedule(MetaDataModel):
|
class Schedule(MetaDataModel):
|
||||||
|
"""
|
||||||
|
A model that holds the schedule information. Here we store the form data and let the Peregrine cluster make the calculations.
|
||||||
|
It will inherit the attributes :attr:`~lib.models.base.MetaDataModel.created_at` and :attr:`~lib.models.base.MetaDataModel.updated_at` from the Abstract model :class:`~lib.models.base.MetaDataModel`
|
||||||
|
|
||||||
|
Attributes
|
||||||
|
----------
|
||||||
|
employee : Employee
|
||||||
|
The employee that is the owner of this schedule.
|
||||||
|
name : str
|
||||||
|
The name of the schedule. Max length is 100 characters.
|
||||||
|
email : str
|
||||||
|
The email address where the results should be sent to. Max length is 100 characters.
|
||||||
|
status : ScheduleStatus
|
||||||
|
The status of the schedule.
|
||||||
|
planning_source : JSON
|
||||||
|
The complete schedule stored in JSON data object.
|
||||||
|
"""
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
verbose_name = _('schedule')
|
verbose_name = _('schedule')
|
||||||
verbose_name_plural = _('schedules')
|
verbose_name_plural = _('schedules')
|
||||||
|
|
||||||
|
class ScheduleStatus(models.TextChoices):
|
||||||
|
"""This is a sub class of Schedule which holds all the possible schedule statuses
|
||||||
|
|
||||||
employee = models.ForeignKey(Employee, on_delete=models.CASCADE, help_text=_('Select the employee that is responsible for this schedule request'))
|
.. data:: DRAFT
|
||||||
|
|
||||||
|
The schedule is just created but not finished. Schedules in this state can be updated later on.
|
||||||
|
|
||||||
|
.. data:: NEW
|
||||||
|
|
||||||
|
The schedule is just created and waiting to be picked up by the Peregrine scripts.
|
||||||
|
|
||||||
|
.. data:: ACCEPTED
|
||||||
|
|
||||||
|
The Peregrine scripts have accepted the new schedule job. And the input is valid.
|
||||||
|
|
||||||
|
.. data:: PROCESSING
|
||||||
|
|
||||||
|
The Peregrine job is submitted to the job queue and should be starting soon.
|
||||||
|
|
||||||
|
.. data:: PROCESSED
|
||||||
|
|
||||||
|
The Peregrine job is finished, and the results will be futher processed in order to create a new report with the outcome.
|
||||||
|
|
||||||
|
.. data:: DONE
|
||||||
|
|
||||||
|
The schedule rapport is created and uploaded to the database. The Peregrine process is done.
|
||||||
|
|
||||||
|
.. data:: INVALID
|
||||||
|
|
||||||
|
The entered data is invalid. Either directly by the posting of the form. Or when the Peregrine script could not read the input.
|
||||||
|
|
||||||
|
.. data:: FAILURE
|
||||||
|
|
||||||
|
Something when wrong on Peregrine. Look at the logging output of the Peregrine job
|
||||||
|
|
||||||
|
"""
|
||||||
|
DRAFT = 'draft', _('Draft')
|
||||||
|
NEW = 'new', _('New')
|
||||||
|
ACCEPTED = 'accepted', _('Accepted')
|
||||||
|
PROCESSING = 'processing', _('Processing')
|
||||||
|
PROCESSED = 'processed', _('Processed')
|
||||||
|
DONE = 'done', _('Done')
|
||||||
|
INVALID = 'invalid', _('Invalid')
|
||||||
|
FAILURE = 'failure', _('Failure')
|
||||||
|
|
||||||
|
employee = models.ForeignKey(Employee, verbose_name=Employee._meta.verbose_name, on_delete=models.CASCADE, help_text=_('Select the employee that is responsible for this schedule request'))
|
||||||
|
|
||||||
name = models.CharField(_('Name'), max_length=100, help_text=_('Name of the schedule'))
|
name = models.CharField(_('Name'), max_length=100, help_text=_('Name of the schedule'))
|
||||||
email = models.CharField(_('Email address'), max_length=100, help_text=_('Email address where the results will be sent to.'))
|
email = models.CharField(_('Email address'), max_length=100, help_text=_('Email address where the results will be sent to.'))
|
||||||
|
|
||||||
planning_source = JSONField(_('Schedule input'), blank=True, load_kwargs={'object_pairs_hook': collections.OrderedDict}, help_text=_('The schedule input in JSON format based on the form data'))
|
status = models.CharField(_('Status'), max_length=10, choices=ScheduleStatus.choices, default=ScheduleStatus.NEW, help_text=_('The status of this schedule.'), db_index=True, )
|
||||||
|
|
||||||
planning_peregrine = models.TextField(_('Peregrine input'), blank=True, help_text=_('This is the translated content from the source for use with Peregrine cluster'))
|
planning_source = JSONField(_('Schedule input'), blank=True, null=True, load_kwargs={'object_pairs_hook': collections.OrderedDict}, help_text=_('The schedule input in JSON format based on the form data'))
|
||||||
|
|
||||||
peregrine_accepted = models.BooleanField(_('Peregrine accepted'),default=False, help_text=_('When true, the Peregrine cluster has picked up the job.'))
|
peregrine_result = JSONField(_('Peregrine JSON output'), blank=True, null=True, load_kwargs={'object_pairs_hook': collections.OrderedDict}, help_text=_('The results from the Peregrine job in JSON'))
|
||||||
|
|
||||||
peregrine_result = JSONField(_('Peregrine JSON output'), blank=True, load_kwargs={'object_pairs_hook': collections.OrderedDict}, help_text=_('The results from the Peregrine job in JSON'))
|
output_peregrine = models.BinaryField(_('Peregrine binary output'), blank=True, null=True, help_text=_('This is the output in binary format from the Peregrine cluster'))
|
||||||
|
|
||||||
output_peregrine = models.BinaryField(_('Peregrine binary output'), blank=True, help_text=_('This is the output in binary format from the Peregrine cluster'))
|
|
||||||
|
|
||||||
report_sent = models.DateTimeField(_('Report is send to user'), blank=True, null=True, help_text=_('The date and time when the report has sended to the user.'))
|
report_sent = models.DateTimeField(_('Report is send to user'), blank=True, null=True, help_text=_('The date and time when the report has sended to the user.'))
|
||||||
|
|
||||||
peregrine_output_log = models.TextField(_('Peregrine logging'), blank=True, help_text=_('Here you can see the logging of the Peregrine job.'))
|
peregrine_output_log = models.TextField(_('Peregrine logging'), blank=True, help_text=_('Here you can see the logging of the Peregrine job.'))
|
||||||
|
|
||||||
|
@property
|
||||||
|
def done(self):
|
||||||
|
"""
|
||||||
|
Checks if the processing of this schedule is done on the Peregrine cluster. This can be either with the status:
|
||||||
|
|
||||||
|
1. :attr:`~ScheduleStatus.DONE`
|
||||||
|
2. :attr:`~ScheduleStatus.INVALID`
|
||||||
|
3. :attr:`~ScheduleStatus.FAILURE`
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
boolean -- True when status is one of the above value.
|
||||||
|
"""
|
||||||
|
return self.status in [self.ScheduleStatus.DONE,self.ScheduleStatus.INVALID,self.ScheduleStatus.FAILURE]
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
"""str: Returns a readable name for the schedule. Format is [schedule_name] (employee_name)."""
|
"""str: Returns a readable name for the schedule. Format is [schedule_name] (employee_name)."""
|
||||||
return '{} ({})'.format(self.name, self.employee)
|
return '{} ({})'.format(self.name, self.employee)
|
@ -12,8 +12,9 @@
|
|||||||
<th>{% trans "Name" %}</th>
|
<th>{% trans "Name" %}</th>
|
||||||
<th>{% trans "Created" %}</th>
|
<th>{% trans "Created" %}</th>
|
||||||
<th>{% trans "Updated" %}</th>
|
<th>{% trans "Updated" %}</th>
|
||||||
<th>{% trans "Running" %}</th>
|
<th>{% trans "Status" %}</th>
|
||||||
<th>{% trans "Report" %}</th>
|
<th>{% trans "Report" %}</th>
|
||||||
|
<th>{% trans "Actions" %}</th>
|
||||||
</tr>
|
</tr>
|
||||||
{% for schedule in object_list %}
|
{% for schedule in object_list %}
|
||||||
<tr>
|
<tr>
|
||||||
@ -21,8 +22,15 @@
|
|||||||
<td>{% comment %}<a href="{% url 'schedule:detail' pk=schedule.id %}">{% endcomment %}{{ schedule.name }}{% comment %}</a>{% endcomment %}</td>
|
<td>{% comment %}<a href="{% url 'schedule:detail' pk=schedule.id %}">{% endcomment %}{{ schedule.name }}{% comment %}</a>{% endcomment %}</td>
|
||||||
<td>{{ schedule.created_at|date:"SHORT_DATETIME_FORMAT" }}</td>
|
<td>{{ schedule.created_at|date:"SHORT_DATETIME_FORMAT" }}</td>
|
||||||
<td>{{ schedule.updated_at|date:"SHORT_DATETIME_FORMAT" }}</td>
|
<td>{{ schedule.updated_at|date:"SHORT_DATETIME_FORMAT" }}</td>
|
||||||
|
<td>{{ schedule.get_status_display }}</td>
|
||||||
<td>None</td>
|
<td>None</td>
|
||||||
<td>None</td>
|
<td>
|
||||||
|
{% if schedule.status == 'draft' %}
|
||||||
|
<a href="{% url 'schedule:edit' schedule_id=schedule.id %}">{% trans "Resume" %}</a>
|
||||||
|
{% else %}
|
||||||
|
<a href="{% url 'schedule:clone' schedule_id=schedule.id %}">{% trans "Clone" %}</a>
|
||||||
|
{% endif %}
|
||||||
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
{% empty %}
|
{% empty %}
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -2,12 +2,36 @@
|
|||||||
{% load i18n %}
|
{% load i18n %}
|
||||||
{% load static %}
|
{% load static %}
|
||||||
|
|
||||||
{% block title %}{% trans "New schedule" %}{% endblock %}
|
{% block title %}
|
||||||
{% block pagetitle %}{% trans "New schedule" %}{% endblock %}
|
{% if form.status.value == 'draft' %}
|
||||||
|
{% trans "Resume schedule" %}
|
||||||
|
{% elif form.json.value %}
|
||||||
|
{% trans "Clone schedule" %}
|
||||||
|
{% else %}
|
||||||
|
{% trans "New schedule" %}
|
||||||
|
{% endif %}
|
||||||
|
{% endblock %}
|
||||||
|
{% block pagetitle %}
|
||||||
|
{% if form.status.value == 'draft' %}
|
||||||
|
{% trans "Resume schedule" %}
|
||||||
|
{% elif form.json.value %}
|
||||||
|
{% trans "Clone schedule" %}
|
||||||
|
{% else %}
|
||||||
|
{% trans "New schedule" %}
|
||||||
|
{% endif %}
|
||||||
|
{% endblock %}
|
||||||
{% block content %}
|
{% block content %}
|
||||||
<form method="POST" action="{% url 'schedule:new' %}" id="new_schedule_form">
|
|
||||||
|
{% if form.status.value == 'draft' %}
|
||||||
|
<form method="POST" action="" id="new_schedule_form">
|
||||||
|
{% else %}
|
||||||
|
<form method="POST" action="{% url 'schedule:new' %}" id="new_schedule_form">
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
|
||||||
{% csrf_token %}
|
{% csrf_token %}
|
||||||
{{ form.json }}
|
{{ form.json }}
|
||||||
|
{{ form.status }}
|
||||||
<h1>Algemene informatie</h1>
|
<h1>Algemene informatie</h1>
|
||||||
<p>Als een afdeling meerdere wachtkamers heeft, vul dan dit formulier meerdere keren in; een keer voor elke groep van behandelkamers die een wachtkamer delen.</p>
|
<p>Als een afdeling meerdere wachtkamers heeft, vul dan dit formulier meerdere keren in; een keer voor elke groep van behandelkamers die een wachtkamer delen.</p>
|
||||||
<table>
|
<table>
|
||||||
@ -23,7 +47,6 @@
|
|||||||
<small id="afdelingnaamHelp" class="form-text text-muted">Geef de naam op van de afdeling</small>
|
<small id="afdelingnaamHelp" class="form-text text-muted">Geef de naam op van de afdeling</small>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<th>
|
<th>
|
||||||
<label for="id_email">Emailadres voor de resultaten</label>
|
<label for="id_email">Emailadres voor de resultaten</label>
|
||||||
@ -35,7 +58,6 @@
|
|||||||
<small id="emailadresHelp" class="form-text text-muted">Geef het emailadres op om de uitkomsten te ontvangen</small>
|
<small id="emailadresHelp" class="form-text text-muted">Geef het emailadres op om de uitkomsten te ontvangen</small>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<th>
|
<th>
|
||||||
<label for="patienten">Aantal patiënten dat kan wachten in wachtkamer</label>
|
<label for="patienten">Aantal patiënten dat kan wachten in wachtkamer</label>
|
||||||
@ -49,16 +71,13 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
<hr>
|
<hr>
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
<h1>Specialisaties binnen de afdeling</h1>
|
<h1>Specialisaties binnen de afdeling</h1>
|
||||||
<div class="poliekliniek_specialisatie">
|
<div class="poliekliniek_specialisatie">
|
||||||
<table>
|
<table>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<th>
|
<th>
|
||||||
<label for="specialisatie_0" class="h4">Specialisatie 1</label>
|
<label for="specialisatie_0" class="h4">Specialisatie 1</label>
|
||||||
@ -70,7 +89,6 @@
|
|||||||
<small id="specialisatie_0Help" class="form-text text-muted" style="float:right;display:none"><a href="#">Verwijder</a></small>
|
<small id="specialisatie_0Help" class="form-text text-muted" style="float:right;display:none"><a href="#">Verwijder</a></small>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<th>
|
<th>
|
||||||
<label for="specialisatie_afkorting_0">Specialisatie afkorting</label>
|
<label for="specialisatie_afkorting_0">Specialisatie afkorting</label>
|
||||||
@ -82,19 +100,6 @@
|
|||||||
<small id="specialisatie_0Help" class="form-text text-muted">Geef een afkorting op voor deze specialisatie. Deze gebruiken wij in de figuren van de rapportage.</small>
|
<small id="specialisatie_0Help" class="form-text text-muted">Geef een afkorting op voor deze specialisatie. Deze gebruiken wij in de figuren van de rapportage.</small>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
<tr>
|
|
||||||
<th>
|
|
||||||
<label for="specialisatie_aantal_artsen_0">Aantal artsen</label>
|
|
||||||
</th>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>
|
|
||||||
<input type="number" class="form-control" min="1" max="100" id="specialisatie_aantal_artsen_0" name="specialisatie_aantal_artsen_0" aria-describedby="specialisatie_aantal_artsen_0Help" required>
|
|
||||||
<small id="specialisatie_aantal_artsen_0Help" class="form-text text-muted">Maximaal aantal artsen dat op enig moment tegelijk aan het werk zou kunnen zijn.</small>
|
|
||||||
</td>
|
|
||||||
</tr>
|
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<th>
|
<th>
|
||||||
<label for="specialisatie_aantal_kamers_0">Aantal behandelkamers</label>
|
<label for="specialisatie_aantal_kamers_0">Aantal behandelkamers</label>
|
||||||
@ -106,19 +111,18 @@
|
|||||||
<small id="specialisatie_aantal_kamers_0Help" class="form-text text-muted">Aantal behandelkamers dat beschikbaar is per specialisatie</small>
|
<small id="specialisatie_aantal_kamers_0Help" class="form-text text-muted">Aantal behandelkamers dat beschikbaar is per specialisatie</small>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
<!--
|
|
||||||
<tr>
|
<tr>
|
||||||
<th>
|
<th>
|
||||||
<label for="specialisatie_aantal_behandelingen_0">Aantal verschillende soorten behandelingen</label>
|
<label for="specialisatie_aantal_artsen_0">Aantal artsen</label>
|
||||||
</th>
|
</th>
|
||||||
</tr>
|
</tr>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
<input type="number" class="form-control" min="0" max="100" id="specialisatie_aantal_behandelingen_0" name="specialisatie_aantal_behandelingen_0" aria-describedby="specialisatie_aantal_behandelingen_0Help" required>
|
<input type="number" class="form-control" min="1" max="100" id="specialisatie_aantal_artsen_0" name="specialisatie_aantal_artsen_0" aria-describedby="specialisatie_aantal_artsen_0Help" required>
|
||||||
<small id="specialisatie_aantal_behandelingen_0Help" class="form-text text-muted"></small>
|
<small id="specialisatie_aantal_artsen_0Help" class="form-text text-muted">Maximaal aantal artsen dat op enig moment tegelijk aan het werk kan zijn (dit kan niet meer zijn dan het aantal behandelkamers).<br /><strong>Let op</strong>: dit gaat om fulltime artsen, twee 50% parttime artsen moet worden ingevuld als één arts.</small>
|
||||||
|
<br /><br />
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
-->
|
|
||||||
<tr>
|
<tr>
|
||||||
<th>
|
<th>
|
||||||
<label>Werktijden <small class="text-danger" style="display:none"> Nog niet volledig</small></label>
|
<label>Werktijden <small class="text-danger" style="display:none"> Nog niet volledig</small></label>
|
||||||
@ -192,7 +196,6 @@
|
|||||||
</select>
|
</select>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<th>ochtendpauze</th>
|
<th>ochtendpauze</th>
|
||||||
<td>
|
<td>
|
||||||
@ -227,7 +230,6 @@
|
|||||||
</select>
|
</select>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<th>lunchpauze</th>
|
<th>lunchpauze</th>
|
||||||
<td>
|
<td>
|
||||||
@ -265,7 +267,6 @@
|
|||||||
</select>
|
</select>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<th>middagpauze</th>
|
<th>middagpauze</th>
|
||||||
<td>
|
<td>
|
||||||
@ -278,19 +279,15 @@
|
|||||||
<option value="1515">15:15</option>
|
<option value="1515">15:15</option>
|
||||||
<option value="1530">15:30</option>
|
<option value="1530">15:30</option>
|
||||||
<option value="1545">15:45</option>
|
<option value="1545">15:45</option>
|
||||||
|
|
||||||
<option value="1600">16:00</option>
|
<option value="1600">16:00</option>
|
||||||
<option value="1615">16:15</option>
|
<option value="1615">16:15</option>
|
||||||
<option value="1630">16:30</option>
|
<option value="1630">16:30</option>
|
||||||
<option value="1645">16:45</option>
|
<option value="1645">16:45</option>
|
||||||
|
|
||||||
<option value="1700">17:00</option>
|
<option value="1700">17:00</option>
|
||||||
<option value="1715">17:15</option>
|
<option value="1715">17:15</option>
|
||||||
<option value="1730">17:30</option>
|
<option value="1730">17:30</option>
|
||||||
<option value="1745">17:45</option>
|
<option value="1745">17:45</option>
|
||||||
|
|
||||||
<option value="1800">18:00</option>
|
<option value="1800">18:00</option>
|
||||||
|
|
||||||
</select>
|
</select>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
@ -302,65 +299,52 @@
|
|||||||
<option value="1515">15:15</option>
|
<option value="1515">15:15</option>
|
||||||
<option value="1530">15:30</option>
|
<option value="1530">15:30</option>
|
||||||
<option value="1545">15:45</option>
|
<option value="1545">15:45</option>
|
||||||
|
|
||||||
<option value="1600">16:00</option>
|
<option value="1600">16:00</option>
|
||||||
<option value="1615">16:15</option>
|
<option value="1615">16:15</option>
|
||||||
<option value="1630">16:30</option>
|
<option value="1630">16:30</option>
|
||||||
<option value="1645">16:45</option>
|
<option value="1645">16:45</option>
|
||||||
|
|
||||||
<option value="1700">17:00</option>
|
<option value="1700">17:00</option>
|
||||||
<option value="1715">17:15</option>
|
<option value="1715">17:15</option>
|
||||||
<option value="1730">17:30</option>
|
<option value="1730">17:30</option>
|
||||||
<option value="1745">17:45</option>
|
<option value="1745">17:45</option>
|
||||||
|
|
||||||
<option value="1800">18:00</option>
|
<option value="1800">18:00</option>
|
||||||
<option value="1815">18:15</option>
|
<option value="1815">18:15</option>
|
||||||
<option value="1830">18:30</option>
|
<option value="1830">18:30</option>
|
||||||
<option value="1845">18:45</option>
|
<option value="1845">18:45</option>
|
||||||
|
|
||||||
<option value="1900">19:00</option>
|
<option value="1900">19:00</option>
|
||||||
|
|
||||||
</select>
|
</select>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="text-align: center; width: 100%; margin-top: 15px"><a href="#" class="add_specialisatie">klik hier om een extra specialisatie toe te voegen</a></div>
|
<div style="text-align: center; width: 100%; margin-top: 15px"><a href="#" class="add_specialisatie">klik hier om een extra specialisatie toe te voegen</a></div>
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
<hr>
|
<hr>
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
<h1>Behandelingen</h1>
|
<h1>Behandelingen</h1>
|
||||||
<p>In het model worden slots van 5 minuten gebruikt voor het bepalen van starttijden. etc. Afspraken starten daarmee om bijv. 10.00, 10.05, 10.10.<br />Afspraakduur wordt daarmee ook in veelvouden van 5 minuten gevraagd.</p>
|
<p>In het model worden slots van 5 minuten gebruikt voor het bepalen van starttijden. etc. Afspraken starten daarmee om bijv. 10.00, 10.05, 10.10.<br />Afspraakduur wordt daarmee ook in veelvouden van 5 minuten gevraagd.</p>
|
||||||
<p>Zowel afspraketabel_behandelingenn waar de patiënt fysiek in het ziekenhuis is, als wel telefoongesprekken worden hier gevraagd. Beide type afspraken kunnen in het raster worden gepland.</p>
|
<p>Zowel afspraken waar de patiënt fysiek in het ziekenhuis is, als wel telefoongesprekken worden hier gevraagd. Beide type afspraken kunnen in het raster worden gepland.</p>
|
||||||
<p>Normaal aantal: Geef hier het aantal afspraken op dat van dit type <strong style="text-decoration: underline">per dag</strong> gebruikelijk was, voordat COVID-19 begon.<br />
|
<p>Normaal aantal: Geef hier het aantal afspraken op dat van dit type <strong style="text-decoration: underline">per dag</strong> gebruikelijk was, voordat COVID-19 begon.<br />Gewenst als op 30%: Geef hier het aantal afspraken <strong style="text-decoration: underline">per dag</strong> op dat u zou willen hebben als de afdeling maar op 30% van de normale capaciteit zou kunnen draaien.</p>
|
||||||
Gewenst als op 30%: Geef hier het aantal afspraken <strong style="text-decoration: underline">per dag</strong> op dat u zou willen hebben als de afdeling maar op 30% van de normale capaciteit zou kunnen draaien.</p>
|
|
||||||
|
|
||||||
<table id="tabel_behandelingen">
|
<table id="tabel_behandelingen">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Naam behandeling</th>
|
<th class="pointer">Naam behandeling</th>
|
||||||
<th>Duur (in minuten)</th>
|
<th class="pointer">Duur (in minuten)</th>
|
||||||
<th>Specialisatie</th>
|
<th class="pointer">Specialisatie</th>
|
||||||
<th>Methode</th>
|
<th class="pointer">Methode</th>
|
||||||
<th>Normaal aantal</th>
|
<th class="pointer">Normaal aantal</th>
|
||||||
<th>Gewenst als op 30%</th>
|
<th class="pointer">Gewenst als op 30%</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr class="behandeling">
|
<tr class="behandeling">
|
||||||
<td><input type="text" class="form-control" id="behandeling_0" name="behandeling_0" required></td>
|
<td><input type="text" class="form-control" id="behandeling_0" name="behandeling_0" maxlength="20" required></td>
|
||||||
<td>
|
<td>
|
||||||
<select class="form-control" id="behandeling_duration_0" name="behandeling_duration_0" required>
|
<select class="form-control" id="behandeling_duration_0" name="behandeling_duration_0" required>
|
||||||
<option value="5">5</option>
|
<option value="5">5</option>
|
||||||
@ -381,6 +365,11 @@
|
|||||||
<option value="80">80</option>
|
<option value="80">80</option>
|
||||||
<option value="85">85</option>
|
<option value="85">85</option>
|
||||||
<option value="90">90</option>
|
<option value="90">90</option>
|
||||||
|
<option value="120">120</option>
|
||||||
|
<option value="150">150</option>
|
||||||
|
<option value="180">180</option>
|
||||||
|
<option value="210">210</option>
|
||||||
|
<option value="240">240</option>
|
||||||
</select>
|
</select>
|
||||||
</td>
|
</td>
|
||||||
<td>
|
<td>
|
||||||
@ -392,11 +381,9 @@
|
|||||||
<option value="phone">telefonisch</option>
|
<option value="phone">telefonisch</option>
|
||||||
</select>
|
</select>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td>
|
<td>
|
||||||
<input type="number" class="form-control behandeling_calc" id="behandeling_100p_0" name="behandeling_100p_0" min="0" max="100" required>
|
<input type="number" class="form-control behandeling_calc" id="behandeling_100p_0" name="behandeling_100p_0" min="0" max="100" required>
|
||||||
</td>
|
</td>
|
||||||
|
|
||||||
<td>
|
<td>
|
||||||
<input type="number" class="form-control behandeling_calc" id="behandeling_30p_0" name="behandeling_30p_0" min="0" max="100" required>
|
<input type="number" class="form-control behandeling_calc" id="behandeling_30p_0" name="behandeling_30p_0" min="0" max="100" required>
|
||||||
<small style="float:right;"><a href="#">Verwijder</a></small>
|
<small style="float:right;"><a href="#">Verwijder</a></small>
|
||||||
@ -404,9 +391,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<div style="text-align: center; width: 100%; margin-top: 15px"><a href="#" class="add_behandeling">klik hier om een nieuwe behandeling toe te voegen</a></div>
|
<div style="text-align: center; width: 100%; margin-top: 15px"><a href="#" class="add_behandeling">klik hier om een nieuwe behandeling toe te voegen</a></div>
|
||||||
|
|
||||||
<table>
|
<table>
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr class="behandeling_calc_summary">
|
<tr class="behandeling_calc_summary">
|
||||||
@ -414,57 +399,46 @@
|
|||||||
<td style="text-align: center">0</td>
|
<td style="text-align: center">0</td>
|
||||||
<td style="text-align: center">0</td>
|
<td style="text-align: center">0</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="3">
|
<td colspan="3">
|
||||||
<div class="behandeling_calc_remarks"></div>
|
<div class="behandeling_calc_remarks"></div>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<td colspan="3" class="behandeling_calc_time">
|
<td colspan="3" class="behandeling_calc_time"></td>
|
||||||
|
|
||||||
</td>
|
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
|
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
<hr>
|
<hr>
|
||||||
<br />
|
<br />
|
||||||
|
|
||||||
<table>
|
<table>
|
||||||
<tr>
|
<tr>
|
||||||
<td><input type="checkbox" value="1" name="privacy_verklaring" required > </td>
|
<td><input type="checkbox" value="1" name="privacy_verklaring" required > </td>
|
||||||
<td>Met het verzenden van dit formulier gaat u akkoord met de <a href="https://www.rug.nl/about-us/organization/rules-and-regulations/algemeen/20180423-algemeen-privacyverklaring-rug.pdf" target="_blank" title="RUG Privacyverklaring">privacyverklaring</a> van de Rijksuniversiteit Groningen.</td>
|
<td>Met het verzenden van dit formulier gaat u akkoord met de <a href="https://www.rug.nl/about-us/organization/rules-and-regulations/algemeen/20180423-algemeen-privacyverklaring-rug.pdf" target="_blank" title="RUG Privacyverklaring">privacyverklaring</a> van de Rijksuniversiteit Groningen.</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<td><input type="checkbox" value="1" name="rug_vrijwaring" required > </td>
|
<td><input type="checkbox" value="1" name="rug_vrijwaring" required > </td>
|
||||||
<td>De Rijksuniversiteit Groningen (RUG) biedt geen garantie terzake van de juistheid of de bruikbaarheid van het door haar ontwikkelde model en aanverwante documenten. De afnemer/gebruiker vrijwaart de RUG voor aanspraken van derden die jegens RUG mochten worden gedaan naar aanleiding van schades, voortvloeiend uit het gebruik of de toepassing van het model en aanverwante documenten. Alle rechten, waaronder de intellectuele eigendomsrechten, op het model en bijbehorende documenten, blijven te allen tijde voorbehouden aan de RUG.</td>
|
<td>De Rijksuniversiteit Groningen (RUG) biedt geen garantie terzake van de juistheid of de bruikbaarheid van het door haar ontwikkelde model en aanverwante documenten. De afnemer/gebruiker vrijwaart de RUG voor aanspraken van derden die jegens RUG mochten worden gedaan naar aanleiding van schades, voortvloeiend uit het gebruik of de toepassing van het model en aanverwante documenten. Alle rechten, waaronder de intellectuele eigendomsrechten, op het model en bijbehorende documenten, blijven te allen tijde voorbehouden aan de RUG.</td>
|
||||||
</tr>
|
</tr>
|
||||||
|
|
||||||
<tr>
|
<tr>
|
||||||
<td><input type="checkbox" value="1" name="data_verwerking" required > </td>
|
<td><input type="checkbox" value="1" name="data_verwerking" required > </td>
|
||||||
<td>De gebruiker geeft de RUG toestemming om de ingevoerde data te verwerken in het kader van wetenschappelijk onderzoek en in het kader van het verbeteren van haar tools. De RUG zal over het onderzoek mogen publiceren, ook in andere vormen dan genoemde eindrapportage. De data kunnen in geanonimiseerde vorm in de publicaties worden opgenomen.</td>
|
<td>De gebruiker geeft de RUG toestemming om de ingevoerde data te verwerken in het kader van wetenschappelijk onderzoek en in het kader van het verbeteren van haar tools. De RUG zal over het onderzoek mogen publiceren, ook in andere vormen dan genoemde eindrapportage. De data kunnen in geanonimiseerde vorm in de publicaties worden opgenomen.</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
<br />
|
<br />
|
||||||
<hr>
|
<hr>
|
||||||
<br />
|
<br />
|
||||||
|
<button type="submit" id="save_draft" class="btn btn-primary">{% trans "Save as draft" %}</button>
|
||||||
<button type="submit" class="btn btn-primary">Submit</button>
|
-
|
||||||
|
<button type="submit" id="save_new" class="btn btn-primary">{% trans "Submit" %}</button>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
function addSpecialisatie() {
|
function addSpecialisatie() {
|
||||||
var clone = jQuery('div.poliekliniek_specialisatie:first').clone()
|
var clone = jQuery('div.poliekliniek_specialisatie:first').clone()
|
||||||
clone.find('input').val('');
|
clone.find('input').val('');
|
||||||
clone.find('option:disabled').removeAttr('disabled');
|
clone.find('option:disabled').removeAttr('disabled');
|
||||||
clone.find('small').show();
|
clone.find('small.text-muted').show();
|
||||||
clone.insertAfter('div.poliekliniek_specialisatie:last');
|
clone.insertAfter('div.poliekliniek_specialisatie:last');
|
||||||
updateSpecialisaties();
|
updateSpecialisaties();
|
||||||
loadRemoveSpecialisatie();
|
loadRemoveSpecialisatie();
|
||||||
@ -476,6 +450,7 @@
|
|||||||
jQuery(this).parentsUntil('.poliekliniek_specialisatie').parent().remove();
|
jQuery(this).parentsUntil('.poliekliniek_specialisatie').parent().remove();
|
||||||
updateSpecialisaties();
|
updateSpecialisaties();
|
||||||
updateSpecialisatieValues();
|
updateSpecialisatieValues();
|
||||||
|
calculateBehandelingen();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -485,13 +460,18 @@
|
|||||||
element = jQuery(element);
|
element = jQuery(element);
|
||||||
var nr = counter; // We are starting with 0 so the amount is the new number
|
var nr = counter; // We are starting with 0 so the amount is the new number
|
||||||
element.find('label').first().text('Specialisatie ' + (nr + 1));
|
element.find('label').first().text('Specialisatie ' + (nr + 1));
|
||||||
element.find('select,input').each(function(index,selectitem){
|
element.find('select,input,label').each(function(index,selectitem){
|
||||||
selectitem = jQuery(selectitem);
|
selectitem = jQuery(selectitem);
|
||||||
selectitem.prop('name',selectitem.prop('name').replace(/_\d+$/,'_' + nr));
|
if (selectitem.is('label')) {
|
||||||
selectitem.prop('id',selectitem.prop('id').replace(/_\d+$/,'_' + nr));
|
selectitem.prop('for',selectitem.prop('for').replace(/_\d+$/,'_' + nr));
|
||||||
|
} else {
|
||||||
|
//console.log(selectitem,selectitem.prop('name'),selectitem.prop('id') );
|
||||||
|
selectitem.prop('name',selectitem.prop('name').replace(/_\d+$/,'_' + nr));
|
||||||
|
selectitem.prop('id',selectitem.prop('id').replace(/_\d+$/,'_' + nr));
|
||||||
|
|
||||||
if (selectitem.attr('aria-describedby')) {
|
if (selectitem.attr('aria-describedby')) {
|
||||||
selectitem.attr('aria-describedby',selectitem.attr('aria-describedby').replace(/_\d+Help$/,'_' + nr + 'Help'));
|
selectitem.attr('aria-describedby',selectitem.attr('aria-describedby').replace(/_\d+Help$/,'_' + nr + 'Help'));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -501,8 +481,18 @@
|
|||||||
updateSpecialisatieValues();
|
updateSpecialisatieValues();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
jQuery('input[name^="specialisatie_aantal_artsen_"]').off('change keyup').on('change keyup',function(){
|
||||||
|
calculateBehandelingen();
|
||||||
|
validate_doctors_vs_rooms();
|
||||||
|
});
|
||||||
|
|
||||||
|
jQuery('input[name^="specialisatie_aantal_kamers_"]').off('change keyup').on('change keyup',function(){
|
||||||
|
validate_doctors_vs_rooms();
|
||||||
|
});
|
||||||
|
|
||||||
jQuery('div.werktijden select').off('change').on('change',function(event){
|
jQuery('div.werktijden select').off('change').on('change',function(event){
|
||||||
check_working_hours(this);
|
check_working_hours(jQuery(this).parentsUntil('.werktijden').parent());
|
||||||
|
calculateBehandelingen();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -536,11 +526,7 @@
|
|||||||
|
|
||||||
clone.insertAfter('tr.behandeling:last');
|
clone.insertAfter('tr.behandeling:last');
|
||||||
|
|
||||||
jQuery('tr.behandeling input.behandeling_calc').off('change keyup').on('change keyup',function(){
|
jQuery('tr.behandeling :input').off('change keyup').on('change keyup',function(){
|
||||||
calculateBehandelingen();
|
|
||||||
});
|
|
||||||
|
|
||||||
jQuery('tr.behandeling select').off('change').on('change',function(){
|
|
||||||
calculateBehandelingen();
|
calculateBehandelingen();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -554,6 +540,7 @@
|
|||||||
jQuery(this).parentsUntil('.behandeling').parent().remove();
|
jQuery(this).parentsUntil('.behandeling').parent().remove();
|
||||||
|
|
||||||
updateBehandelingen();
|
updateBehandelingen();
|
||||||
|
calculateBehandelingen();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -571,12 +558,21 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function calculateBehandelingen() {
|
function calculateBehandelingen() {
|
||||||
|
const max_limit = 0.4; // Max 40% van het maximum
|
||||||
let total = 0, percentage = 0;
|
let total = 0, percentage = 0;
|
||||||
let error = false;
|
let error = false;
|
||||||
|
let show_message = false;
|
||||||
|
|
||||||
jQuery('tr.behandeling').each(function(counter,row){
|
jQuery('tr.behandeling').each(function(counter,row){
|
||||||
row = jQuery(row);
|
row = jQuery(row);
|
||||||
if (row.find('select[name^="behandeling_method_"]').val() == 'live') {
|
if (row.find('select[name^="behandeling_method_"]').val() == 'live') {
|
||||||
|
if (!show_message) {
|
||||||
|
show_message = ( row.find('input[name^="behandeling_"]').val() !== ''
|
||||||
|
&& row.find('select[name^="behandeling_specialisme_"]').val() !== ''
|
||||||
|
&& row.find('input[name^="behandeling_100p_"]').val() !== ''
|
||||||
|
&& row.find('input[name^="behandeling_30p_"]').val() !== '' )
|
||||||
|
}
|
||||||
|
|
||||||
total += (row.find('input[name*="_100p_"]').val() != '' ? row.find('input[name*="_100p_"]').val() * 1 : 0);
|
total += (row.find('input[name*="_100p_"]').val() != '' ? row.find('input[name*="_100p_"]').val() * 1 : 0);
|
||||||
percentage += (row.find('input[name*="_30p_"]').val() != '' ? row.find('input[name*="_30p_"]').val() * 1 : 0);
|
percentage += (row.find('input[name*="_30p_"]').val() != '' ? row.find('input[name*="_30p_"]').val() * 1 : 0);
|
||||||
}
|
}
|
||||||
@ -588,18 +584,22 @@
|
|||||||
let calc_message = '';
|
let calc_message = '';
|
||||||
let class_message = '';
|
let class_message = '';
|
||||||
|
|
||||||
if (percentage > (total * 0.3)) {
|
if (percentage > (total * max_limit)) {
|
||||||
calc_message = 'U heeft ' + Math.ceil(percentage - (total * 0.3)) + ' teveel afspraken geselecteerd voor het 30% scenario';
|
calc_message = 'U heeft ' + Math.ceil(percentage - (total * max_limit)) + ' afspraken teveel geselecteerd voor het 30% scenario';
|
||||||
class_message = 'alert-danger';
|
class_message = 'alert-danger';
|
||||||
error = true;
|
error = true;
|
||||||
} else if ((total * 0.3) - percentage >= 1) {
|
} else if ((total * max_limit) - percentage >= 1) {
|
||||||
calc_message = 'U kunt nog '+ Math.floor((total * 0.3) - percentage) +' afspraken toevoegen voor het 30% scenario';
|
//calc_message = 'U kunt nog '+ Math.floor((total * max_limit - percentage) +' afspraken toevoegen voor het 30% scenario';
|
||||||
class_message = 'alert-warning';
|
//class_message = 'alert-warning';
|
||||||
} else {
|
} else {
|
||||||
calc_message = 'Dit klopt precies';
|
calc_message = 'Dit klopt precies';
|
||||||
class_message = 'alert-success';
|
class_message = 'alert-success';
|
||||||
}
|
}
|
||||||
jQuery('div.behandeling_calc_remarks').removeClass('alert-danger alert-warning alert-success').addClass(class_message).text(calc_message);
|
|
||||||
|
jQuery('div.behandeling_calc_remarks').removeClass('alert-danger alert-warning alert-success').html('');
|
||||||
|
if (show_message) {
|
||||||
|
jQuery('div.behandeling_calc_remarks').addClass(class_message).text(calc_message);
|
||||||
|
}
|
||||||
|
|
||||||
validate_behandeling_hours();
|
validate_behandeling_hours();
|
||||||
|
|
||||||
@ -614,6 +614,13 @@
|
|||||||
dir = "asc";
|
dir = "asc";
|
||||||
/* Make a loop that will continue until
|
/* Make a loop that will continue until
|
||||||
no switching has been done: */
|
no switching has been done: */
|
||||||
|
|
||||||
|
// Normal sorting is done on text based.
|
||||||
|
mode = 'text';
|
||||||
|
if ([1,4,5].indexOf(n) !== -1) {
|
||||||
|
// but for some colums, we want to use number soring.
|
||||||
|
mode = 'number';
|
||||||
|
}
|
||||||
while (switching) {
|
while (switching) {
|
||||||
// Start by saying: no switching is done:
|
// Start by saying: no switching is done:
|
||||||
switching = false;
|
switching = false;
|
||||||
@ -631,14 +638,21 @@
|
|||||||
based on the direction, asc or desc: */
|
based on the direction, asc or desc: */
|
||||||
var value_x = jQuery(x).find('select').length > 0 ? jQuery(x).find('select') : jQuery(x).find('input');
|
var value_x = jQuery(x).find('select').length > 0 ? jQuery(x).find('select') : jQuery(x).find('input');
|
||||||
var value_y = jQuery(y).find('select').length > 0 ? jQuery(y).find('select') : jQuery(y).find('input');
|
var value_y = jQuery(y).find('select').length > 0 ? jQuery(y).find('select') : jQuery(y).find('input');
|
||||||
|
|
||||||
if (dir == "asc") {
|
if (dir == "asc") {
|
||||||
if (value_x.val().toLowerCase() > value_y.val().toLowerCase()) {
|
if (
|
||||||
|
('text' == mode && value_x.val().toLowerCase() > value_y.val().toLowerCase()) ||
|
||||||
|
('number' == mode && (value_x.val() * 1) > (value_y.val() * 1))
|
||||||
|
) {
|
||||||
// If so, mark as a switch and break the loop:
|
// If so, mark as a switch and break the loop:
|
||||||
shouldSwitch = true;
|
shouldSwitch = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else if (dir == "desc") {
|
} else if (dir == "desc") {
|
||||||
if (value_x.val().toLowerCase() < value_y.val().toLowerCase()) {
|
if (
|
||||||
|
('text' == mode && value_x.val().toLowerCase() < value_y.val().toLowerCase()) ||
|
||||||
|
('number' == mode && (value_x.val() * 1) < (value_y.val() * 1))
|
||||||
|
) {
|
||||||
// If so, mark as a switch and break the loop:
|
// If so, mark as a switch and break the loop:
|
||||||
shouldSwitch = true;
|
shouldSwitch = true;
|
||||||
break;
|
break;
|
||||||
@ -664,6 +678,19 @@
|
|||||||
updateBehandelingen();
|
updateBehandelingen();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function validate_doctors_vs_rooms() {
|
||||||
|
//let behandelingen = {};
|
||||||
|
jQuery('div.poliekliniek_specialisatie').each(function(index,element){
|
||||||
|
element = jQuery(element);
|
||||||
|
|
||||||
|
let amount_of_doctors = element.find('input[name^="specialisatie_aantal_artsen_"]').val() * 1;
|
||||||
|
let amount_of_rooms = element.find('input[name^="specialisatie_aantal_kamers_"]').val() * 1;
|
||||||
|
|
||||||
|
// Use HTML5 validators from the browser and chage the max value based on the amount of rooms available
|
||||||
|
element.find('input[name^="specialisatie_aantal_artsen_"]').prop('max',amount_of_rooms);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function validate_behandeling_hours() {
|
function validate_behandeling_hours() {
|
||||||
let behandelingen = {};
|
let behandelingen = {};
|
||||||
jQuery('div.poliekliniek_specialisatie').each(function(index,element){
|
jQuery('div.poliekliniek_specialisatie').each(function(index,element){
|
||||||
@ -672,12 +699,13 @@
|
|||||||
let specialisme = element.find('input[name^="specialisatie_"]').val();
|
let specialisme = element.find('input[name^="specialisatie_"]').val();
|
||||||
|
|
||||||
behandelingen[specialisme] = {
|
behandelingen[specialisme] = {
|
||||||
name : element.find('input[name^="specialisatie_"]').val(),
|
name : element.find('input[name^="specialisatie_"]').val(),
|
||||||
artsen : element.find('input[name^="specialisatie_aantal_artsen_"]').val(),
|
artsen : element.find('input[name^="specialisatie_aantal_artsen_"]').val() * 1,
|
||||||
max_time : 0,
|
max_time : 0,
|
||||||
used_time : 0
|
used_time : 0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Hole working day, first time row
|
||||||
let time_start_value = element.find('select[name^="werkdag_start_afdeling_"]').val() * 1;
|
let time_start_value = element.find('select[name^="werkdag_start_afdeling_"]').val() * 1;
|
||||||
let time_end_value = element.find('select[name^="werkdag_end_afdeling_"]').val() * 1;
|
let time_end_value = element.find('select[name^="werkdag_end_afdeling_"]').val() * 1;
|
||||||
|
|
||||||
@ -695,11 +723,10 @@
|
|||||||
time_end.setSeconds(0);
|
time_end.setSeconds(0);
|
||||||
time_end.setMilliseconds(0);
|
time_end.setMilliseconds(0);
|
||||||
|
|
||||||
//console.log(time_start,time_end);
|
|
||||||
|
|
||||||
behandelingen[specialisme]['max_time'] = ((time_end - time_start) / (1000 * 60));
|
behandelingen[specialisme]['max_time'] = ((time_end - time_start) / (1000 * 60));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Morning break. Second row
|
||||||
time_start_value = element.find('select[name^="ochtend_pauze_start_afdeling_"]').val() * 1;
|
time_start_value = element.find('select[name^="ochtend_pauze_start_afdeling_"]').val() * 1;
|
||||||
time_end_value = element.find('select[name^="ochtend_pauze_end_afdeling_"]').val() * 1;
|
time_end_value = element.find('select[name^="ochtend_pauze_end_afdeling_"]').val() * 1;
|
||||||
|
|
||||||
@ -717,8 +744,6 @@
|
|||||||
time_end.setSeconds(0);
|
time_end.setSeconds(0);
|
||||||
time_end.setMilliseconds(0);
|
time_end.setMilliseconds(0);
|
||||||
|
|
||||||
//console.log(time_start,time_end);
|
|
||||||
|
|
||||||
behandelingen[specialisme]['max_time'] -= ((time_end - time_start) / (1000 * 60));
|
behandelingen[specialisme]['max_time'] -= ((time_end - time_start) / (1000 * 60));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -787,13 +812,19 @@
|
|||||||
message.html('')
|
message.html('')
|
||||||
|
|
||||||
jQuery.each(behandelingen,function(specialisme,obj){
|
jQuery.each(behandelingen,function(specialisme,obj){
|
||||||
if (obj.max_time - obj.used_time < 0) {
|
if ('' == specialisme) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ((obj.artsen * obj.max_time) - obj.used_time < 0) {
|
||||||
error = true;
|
error = true;
|
||||||
message.append(jQuery('<div>').addClass('alert-danger').html('<strong>' + specialisme + ' </strong>: Te veel behandelingen voor het aantal arsten en werktijd. ' + (obj.used_time - obj.max_time) + ' Minuten teveel.'));
|
duration_to_much = (obj.used_time - (obj.artsen * obj.max_time)) * 60 * 1000;
|
||||||
} else if (obj.max_time - obj.used_time == 0) {
|
duration_to_much = humanizeDuration(duration_to_much, {language: moment.locale(), delimiter: ' {% trans "and" %} ', units: ['h','m']});
|
||||||
|
message.append(jQuery('<div>').addClass('alert-danger').html('<strong>' + specialisme + ' </strong>: Te veel behandelingen voor het aantal artsen en werktijd. ' + duration_to_much + ' te veel.'));
|
||||||
|
} else if ((obj.artsen * obj.max_time) - obj.used_time == 0) {
|
||||||
message.append(jQuery('<div>').addClass('alert-success').html('<strong>' + specialisme + ' </strong>: Perfect! Alle tijd is ingedeeld.'));
|
message.append(jQuery('<div>').addClass('alert-success').html('<strong>' + specialisme + ' </strong>: Perfect! Alle tijd is ingedeeld.'));
|
||||||
} else {
|
} else {
|
||||||
message.append(jQuery('<div>').addClass('alert-warning').html('<strong>' + specialisme + ' </strong>: Uw heeft nog ' + (obj.max_time - obj.used_time) + ' minuten tijd over voor meer afspraken.'));
|
// do not show this message here, as it is hard to predict the maximum available time
|
||||||
|
// message.append(jQuery('<div>').addClass('alert-warning').html('<strong>' + specialisme + ' </strong>: Uw heeft nog ' + moment.duration((obj.artsen * obj.max_time) - obj.used_time,'minutes').humanize() + ' tijd over voor meer afspraken.'));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -811,8 +842,11 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function check_working_hours(html, showerror) {
|
function check_working_hours(html, showerror) {
|
||||||
html = jQuery(html).parentsUntil('.werktijden').parent();
|
if (Array.isArray(html)) {
|
||||||
html = jQuery(html[0]);
|
html = html[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
html = jQuery(html);
|
||||||
|
|
||||||
let day_start = html.find('select[name^="werkdag_start_afdeling_"]');
|
let day_start = html.find('select[name^="werkdag_start_afdeling_"]');
|
||||||
let day_end = html.find('select[name^="werkdag_end_afdeling_"]');
|
let day_end = html.find('select[name^="werkdag_end_afdeling_"]');
|
||||||
@ -839,18 +873,35 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
morning_break_end.find('option').each(function(index,element){
|
morning_break_end.find('option').each(function(index,element){
|
||||||
if ('' !== element.value && element.value > 0) {
|
if ('' !== element.value && element.value >= 0) {
|
||||||
// Only allow options that are between the day start and day end.
|
// Only allow options that are between the day start and day end.
|
||||||
// Or when morning_break_start is selected and valid, add period time for end time selections
|
// Or when morning_break_start is selected and valid, add period time for end time selections
|
||||||
|
// When start time is selected, the option 'no break' is not valid (value 0)
|
||||||
let time = ('' != morning_break_start.val() ? morning_break_start.val() : day_start.val());
|
let time = ('' != morning_break_start.val() ? morning_break_start.val() : day_start.val());
|
||||||
let disable = (time && element.value <= time) || (day_end.val() && element.value > day_end.val());
|
let disable = false;
|
||||||
if (element.selected && disable) {
|
|
||||||
|
// Selected no-break at morning starting time and select no-break here
|
||||||
|
if (time == 0 && element.value == 0) {
|
||||||
|
disable = false;
|
||||||
|
} else if (time == 0) {
|
||||||
|
disable = element.value != 0;
|
||||||
|
} else if (element.value == 0) {
|
||||||
|
disable = '' != morning_break_start.val();
|
||||||
|
} else {
|
||||||
|
disable = (time && element.value <= time) || (day_end.val() && element.value > day_end.val());
|
||||||
|
}
|
||||||
|
|
||||||
|
if(element.selected && disable) {
|
||||||
morning_break_end.val('');
|
morning_break_end.val('');
|
||||||
}
|
}
|
||||||
element.disabled = disable;
|
element.disabled = disable;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (morning_break_start.val() == '0') {
|
||||||
|
morning_break_end.val('0');
|
||||||
|
}
|
||||||
|
|
||||||
lunch_start.find('option').each(function(index,element){
|
lunch_start.find('option').each(function(index,element){
|
||||||
if ('' !== element.value && element.value > 0) {
|
if ('' !== element.value && element.value > 0) {
|
||||||
// Only allow options that are between the day start and day end.
|
// Only allow options that are between the day start and day end.
|
||||||
@ -865,11 +916,23 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
lunch_end.find('option').each(function(index,element){
|
lunch_end.find('option').each(function(index,element){
|
||||||
if ('' !== element.value && element.value > 0) {
|
if ('' !== element.value && element.value >= 0) {
|
||||||
// Only allow options that are between the day start and day end.
|
// Only allow options that are between the day start and day end.
|
||||||
// Or when lunch_start is selected and valid, add period time for end time selections
|
// Or when lunch_start is selected and valid, add period time for end time selections
|
||||||
|
// When start time is selected, the option 'no break' is not valid (value 0)
|
||||||
let time = ('' != lunch_start.val() ? lunch_start.val() : day_start.val()) * 1;
|
let time = ('' != lunch_start.val() ? lunch_start.val() : day_start.val()) * 1;
|
||||||
let disable = (time && element.value <= time) || (day_end.val() && element.value > day_end.val());
|
let disable = false;
|
||||||
|
|
||||||
|
if (time == 0 && element.value == 0) {
|
||||||
|
disable = false;
|
||||||
|
} else if (time == 0) {
|
||||||
|
disable = element.value != 0;
|
||||||
|
} else if (element.value == 0) {
|
||||||
|
disable = '' != lunch_start.val();
|
||||||
|
} else {
|
||||||
|
disable = (time && element.value <= time) || (day_end.val() && element.value > day_end.val());
|
||||||
|
}
|
||||||
|
|
||||||
if (element.selected && disable) {
|
if (element.selected && disable) {
|
||||||
lunch_end.val('');
|
lunch_end.val('');
|
||||||
}
|
}
|
||||||
@ -877,6 +940,10 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (lunch_start.val() == '0') {
|
||||||
|
lunch_end.val('0');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
afternoon_break_start.find('option').each(function(index,element){
|
afternoon_break_start.find('option').each(function(index,element){
|
||||||
if ('' !== element.value && element.value > 0) {
|
if ('' !== element.value && element.value > 0) {
|
||||||
@ -892,11 +959,23 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
afternoon_break_end.find('option').each(function(index,element){
|
afternoon_break_end.find('option').each(function(index,element){
|
||||||
if ('' !== element.value && element.value > 0) {
|
if ('' !== element.value && element.value >= 0) {
|
||||||
// Only allow options that are between the day start and day end.
|
// Only allow options that are between the day start and day end.
|
||||||
// Or when morning_break_start is selected and valid, add period time for end time selections
|
// Or when morning_break_start is selected and valid, add period time for end time selections
|
||||||
|
// When start time is selected, the option 'no break' is not valid (value 0)
|
||||||
let time = ('' != afternoon_break_start.val() ? afternoon_break_start.val() : day_start.val());
|
let time = ('' != afternoon_break_start.val() ? afternoon_break_start.val() : day_start.val());
|
||||||
let disable = (time && element.value <= time) || (day_end.val() && element.value > day_end.val());
|
let disable = false;
|
||||||
|
|
||||||
|
if (time == 0 && element.value == 0) {
|
||||||
|
disable = false;
|
||||||
|
} else if (time == 0) {
|
||||||
|
disable = element.value != 0;
|
||||||
|
} else if (element.value == 0) {
|
||||||
|
disable = '' != afternoon_break_start.val();
|
||||||
|
} else {
|
||||||
|
disable = (time && element.value <= time) || (day_end.val() && element.value > day_end.val());
|
||||||
|
}
|
||||||
|
|
||||||
if (element.selected && disable) {
|
if (element.selected && disable) {
|
||||||
afternoon_break_end.val('');
|
afternoon_break_end.val('');
|
||||||
}
|
}
|
||||||
@ -904,6 +983,10 @@
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (afternoon_break_start.val() == '0') {
|
||||||
|
afternoon_break_end.val('0');
|
||||||
|
}
|
||||||
|
|
||||||
if (showerror) {
|
if (showerror) {
|
||||||
html.find('small.text-danger').toggle(day_start.val() == '' || day_start.val() == null ||
|
html.find('small.text-danger').toggle(day_start.val() == '' || day_start.val() == null ||
|
||||||
day_end.val() == '' || day_end.val() == null ||
|
day_end.val() == '' || day_end.val() == null ||
|
||||||
@ -917,6 +1000,35 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function load_clone_data() {
|
||||||
|
if (jQuery('input#id_json').val() != '') {
|
||||||
|
let form = jQuery('form#new_schedule_form');
|
||||||
|
|
||||||
|
let json_data = JSON.parse(form.find('input#id_json').val());
|
||||||
|
|
||||||
|
jQuery.each(json_data,function(key,value){
|
||||||
|
let input = form.find(':input[name="' + key + '"]');
|
||||||
|
|
||||||
|
if (input.length == 0) {
|
||||||
|
// check for second or more specilism or treatment
|
||||||
|
if (key.indexOf('behandeling') >= 0) {
|
||||||
|
addBehandeling();
|
||||||
|
} else {
|
||||||
|
addSpecialisatie();
|
||||||
|
}
|
||||||
|
|
||||||
|
input = form.find(':input[name="' + key + '"]');
|
||||||
|
}
|
||||||
|
input.val(value);
|
||||||
|
updateSpecialisatieValues();
|
||||||
|
});
|
||||||
|
|
||||||
|
validate_working_hours();
|
||||||
|
calculateBehandelingen();
|
||||||
|
validate_behandeling_hours();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
jQuery(function() {
|
jQuery(function() {
|
||||||
jQuery('a.add_specialisatie').on('click',function(event){
|
jQuery('a.add_specialisatie').on('click',function(event){
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
@ -926,12 +1038,6 @@
|
|||||||
jQuery('div.poliekliniek_specialisatie input').off('change').on('change',function(){
|
jQuery('div.poliekliniek_specialisatie input').off('change').on('change',function(){
|
||||||
updateSpecialisatieValues();
|
updateSpecialisatieValues();
|
||||||
});
|
});
|
||||||
{% comment %}
|
|
||||||
jQuery('a.add_behandelkamer').on('click',function(event){
|
|
||||||
event.preventDefault();
|
|
||||||
addBehandelkamer();
|
|
||||||
});
|
|
||||||
{% endcomment %}
|
|
||||||
|
|
||||||
jQuery('a.add_behandeling').on('click',function(event){
|
jQuery('a.add_behandeling').on('click',function(event){
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
@ -939,7 +1045,7 @@
|
|||||||
});
|
});
|
||||||
|
|
||||||
jQuery('div.werktijden select').off('change').on('change',function(event){
|
jQuery('div.werktijden select').off('change').on('change',function(event){
|
||||||
check_working_hours(this);
|
check_working_hours(jQuery(this).parentsUntil('.werktijden').parent());
|
||||||
calculateBehandelingen();
|
calculateBehandelingen();
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -949,10 +1055,27 @@
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
jQuery('input.behandeling_calc').off('change keyup').on('change keyup',function(event){
|
jQuery('input[name^="specialisatie_aantal_artsen_"]').off('change keyup').on('change keyup',function(){
|
||||||
|
calculateBehandelingen();
|
||||||
|
validate_doctors_vs_rooms();
|
||||||
|
});
|
||||||
|
|
||||||
|
jQuery('input[name^="specialisatie_aantal_kamers_"]').off('change keyup').on('change keyup',function(){
|
||||||
|
validate_doctors_vs_rooms();
|
||||||
|
});
|
||||||
|
|
||||||
|
jQuery('tr.behandeling :input').off('change keyup').on('change keyup',function(event){
|
||||||
calculateBehandelingen();
|
calculateBehandelingen();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
jQuery('#save_draft').on('click',function(event){
|
||||||
|
jQuery('input#id_status').val('draft');
|
||||||
|
});
|
||||||
|
|
||||||
|
jQuery('#save_new').on('click',function(event){
|
||||||
|
jQuery('input#id_status').val('new');
|
||||||
|
});
|
||||||
|
|
||||||
jQuery('form#new_schedule_form').on('submit',function(event){
|
jQuery('form#new_schedule_form').on('submit',function(event){
|
||||||
if (validate_working_hours() &&
|
if (validate_working_hours() &&
|
||||||
calculateBehandelingen() &&
|
calculateBehandelingen() &&
|
||||||
@ -961,15 +1084,27 @@
|
|||||||
let formdata = new FormData(this);
|
let formdata = new FormData(this);
|
||||||
formdata.delete('csrfmiddlewaretoken');
|
formdata.delete('csrfmiddlewaretoken');
|
||||||
formdata.delete('json');
|
formdata.delete('json');
|
||||||
|
formdata.delete('status');
|
||||||
|
|
||||||
jQuery('input#id_json').val(JSON.stringify(Object.fromEntries(formdata)));
|
// Display the key/value pairs. This is needed to support stupid IE. Mici$oft is still having hardtime playing nice :(
|
||||||
|
let json_data = {};
|
||||||
|
var formDataEntries = formdata.entries(), formDataEntry = formDataEntries.next(), pair;
|
||||||
|
while (!formDataEntry.done) {
|
||||||
|
pair = formDataEntry.value;
|
||||||
|
json_data[pair[0]] = pair[1];
|
||||||
|
formDataEntry = formDataEntries.next();
|
||||||
|
}
|
||||||
|
|
||||||
|
jQuery('input#id_json').val(JSON.stringify(json_data));
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
alert('Er zijn wat problemen met het formulier. Controleer de invoer velden');
|
alert('Er zijn wat problemen met het formulier. Controleer de invoer velden');
|
||||||
|
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
updateBehandelingen();
|
||||||
|
load_clone_data();
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
{% endblock %}
|
{% endblock %}
|
@ -5,5 +5,7 @@ from . import views
|
|||||||
app_name = 'schedule'
|
app_name = 'schedule'
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('', views.ScheduleListView.as_view(), name='list'),
|
path('', views.ScheduleListView.as_view(), name='list'),
|
||||||
path('new', views.new_or_update_study, name='new'),
|
path('new', views.new_or_update_schedule, name='new'),
|
||||||
|
path('<int:schedule_id>/clone', views.new_or_update_schedule, name='clone'),
|
||||||
|
path('<int:schedule_id>/edit', views.new_or_update_schedule, name='edit'),
|
||||||
]
|
]
|
@ -3,6 +3,7 @@ from django.shortcuts import render, redirect
|
|||||||
from django.views.generic.list import ListView
|
from django.views.generic.list import ListView
|
||||||
from django.contrib.auth.mixins import LoginRequiredMixin
|
from django.contrib.auth.mixins import LoginRequiredMixin
|
||||||
from django.contrib.auth.decorators import login_required
|
from django.contrib.auth.decorators import login_required
|
||||||
|
from django.forms.models import model_to_dict
|
||||||
|
|
||||||
from .models import Schedule
|
from .models import Schedule
|
||||||
from .forms import ScheduleForm
|
from .forms import ScheduleForm
|
||||||
@ -11,6 +12,13 @@ import json
|
|||||||
|
|
||||||
# Create your views here.
|
# Create your views here.
|
||||||
class ScheduleListView(LoginRequiredMixin,ListView):
|
class ScheduleListView(LoginRequiredMixin,ListView):
|
||||||
|
"""
|
||||||
|
This view will give a list of all entered schedules. The list is filtered on the logged in employee.
|
||||||
|
|
||||||
|
Only the schedules owned by the logged in user are shown.
|
||||||
|
|
||||||
|
The results are shown with 10 items per page. A pager will be shown when there are more then 10 schedules
|
||||||
|
"""
|
||||||
|
|
||||||
model = Schedule
|
model = Schedule
|
||||||
paginate_by = 10
|
paginate_by = 10
|
||||||
@ -19,32 +27,82 @@ class ScheduleListView(LoginRequiredMixin,ListView):
|
|||||||
return Schedule.objects.filter(employee=self.request.user.employee).order_by('-created_at')
|
return Schedule.objects.filter(employee=self.request.user.employee).order_by('-created_at')
|
||||||
|
|
||||||
@login_required
|
@login_required
|
||||||
def new_or_update_study(request, schedule = None):
|
def new_or_update_schedule(request, schedule_id = None):
|
||||||
|
"""
|
||||||
|
This view will create or update an existing schedule. At the moment there is not a real update, but a clone functionality.
|
||||||
|
So every schedule that is updated will be stored as a new schedule.
|
||||||
|
|
||||||
|
Only schedules owned by the logged in user can be loaded here and can be cloned.
|
||||||
|
|
||||||
|
The data of the form is stored as a JSON object in a single database field for more flexibility.
|
||||||
|
|
||||||
|
Arguments:
|
||||||
|
request HttpRequest -- This is the HTTP request from the Django framework. This will hold the current logged in user info.
|
||||||
|
|
||||||
|
Keyword Arguments:
|
||||||
|
schedule_id Schedule -- This is the schedule to be edited. When none, a new schedule will be created (default: {None})
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
A view with an empty form to create a new schedule or a prefilled form for cloning.
|
||||||
|
"""
|
||||||
template_name = 'schedule/schedule_new.html'
|
template_name = 'schedule/schedule_new.html'
|
||||||
|
|
||||||
|
schedule = None
|
||||||
|
if schedule_id is not None:
|
||||||
|
try:
|
||||||
|
# Try loading an existing schedule. Make sure you only load a schedule that is owned by the logged in user!
|
||||||
|
schedule = Schedule.objects.get(pk = schedule_id, employee = request.user.employee)
|
||||||
|
except Schedule.DoesNotExist:
|
||||||
|
# Schedule does not exist, or you do not own the schedule you try to load. Stop playing around on the url bar ;)
|
||||||
|
pass
|
||||||
|
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
|
# Load the form data
|
||||||
schedule_form = ScheduleForm(request.POST)
|
schedule_form = ScheduleForm(request.POST)
|
||||||
|
|
||||||
|
# Check if minimal input fields are correct
|
||||||
if schedule_form.is_valid():
|
if schedule_form.is_valid():
|
||||||
new_schedule = Schedule()
|
# First time saving. Create a new, empty schedule
|
||||||
|
# Or when the existing schedule has NOT 'draft' status, which means we are cloning an existing schedule
|
||||||
|
if schedule is None or schedule.status != Schedule.ScheduleStatus.DRAFT:
|
||||||
|
schedule = Schedule()
|
||||||
|
|
||||||
|
# Set the schedule status based on the form pressed button. Either new or draft status
|
||||||
|
schedule.status = Schedule.ScheduleStatus.DRAFT if schedule_form.cleaned_data['status'] == 'draft' else Schedule.ScheduleStatus.NEW
|
||||||
|
|
||||||
try:
|
try:
|
||||||
new_schedule.planning_source = json.loads(schedule_form.cleaned_data['json'])
|
# Try loading the JSON data from the form
|
||||||
|
schedule.planning_source = json.loads(schedule_form.cleaned_data['json'])
|
||||||
except json.JSONDecodeError as ex:
|
except json.JSONDecodeError as ex:
|
||||||
# For now, sorry, ignore
|
# Something when wrong. The error is saved instead, and can be read out in the admin area
|
||||||
pass
|
schedule.planning_source = json.loads(json.dumps({'error': str(ex)}))
|
||||||
|
schedule.status = Schedule.ScheduleStatus.INVALID
|
||||||
|
|
||||||
new_schedule.employee = request.user.employee
|
# Make sure that the logged in user that is creating the schedule does become the owner
|
||||||
new_schedule.name = schedule_form.cleaned_data['name']
|
schedule.employee = request.user.employee
|
||||||
new_schedule.email = schedule_form.cleaned_data['email']
|
# Store name of the schedule
|
||||||
|
schedule.name = schedule_form.cleaned_data['name']
|
||||||
new_schedule.save()
|
# Store email address for the results
|
||||||
|
schedule.email = schedule_form.cleaned_data['email']
|
||||||
|
# Save the schedule to the database
|
||||||
|
schedule.save()
|
||||||
|
|
||||||
|
# Return to overview
|
||||||
return redirect('schedule:list')
|
return redirect('schedule:list')
|
||||||
|
|
||||||
else:
|
else:
|
||||||
schedule_form = ScheduleForm()
|
# We start with a new form. Either new of clone/edit
|
||||||
|
status = 'new'
|
||||||
|
json_form = ''
|
||||||
|
if schedule is not None:
|
||||||
|
# The schedule is an existing one. So we are in clone/edit mode. So load the current status and JSON data
|
||||||
|
status = schedule.status
|
||||||
|
json_form = json.dumps(schedule.planning_source)
|
||||||
|
|
||||||
|
# Create the from logic
|
||||||
|
schedule_form = ScheduleForm(initial={'json' : json_form, 'status' : status})
|
||||||
|
|
||||||
|
# Show the form in the browser
|
||||||
return render(request, template_name, {
|
return render(request, template_name, {
|
||||||
'form' : schedule_form,
|
'form' : schedule_form,
|
||||||
})
|
})
|
@ -8,7 +8,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2020-05-18 09:07+0000\n"
|
"POT-Creation-Date: 2020-06-08 13:43+0200\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
|
@ -7,8 +7,8 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: \n"
|
"Project-Id-Version: \n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2020-05-18 09:07+0000\n"
|
"POT-Creation-Date: 2020-06-08 13:43+0200\n"
|
||||||
"PO-Revision-Date: 2020-05-18 11:10+0200\n"
|
"PO-Revision-Date: 2020-06-08 11:57+0200\n"
|
||||||
"Last-Translator: Joshua Rubingh <j.g.rubingh@rug.nl>\n"
|
"Last-Translator: Joshua Rubingh <j.g.rubingh@rug.nl>\n"
|
||||||
"Language-Team: \n"
|
"Language-Team: \n"
|
||||||
"Language: nl\n"
|
"Language: nl\n"
|
||||||
@ -36,7 +36,7 @@ msgstr "De datum en tijd waarop dit model is bijgewerkt"
|
|||||||
|
|
||||||
#: templates/menu.html:4
|
#: templates/menu.html:4
|
||||||
msgid "Het 1,5 meter ziekenhuis"
|
msgid "Het 1,5 meter ziekenhuis"
|
||||||
msgstr ""
|
msgstr "Het 1,5 meter ziekenhuis"
|
||||||
|
|
||||||
#: templates/menu.html:8 templates/registration/login.html:4
|
#: templates/menu.html:8 templates/registration/login.html:4
|
||||||
#: templates/registration/login.html:5 templates/registration/login.html:8
|
#: templates/registration/login.html:5 templates/registration/login.html:8
|
||||||
@ -62,9 +62,9 @@ msgid ""
|
|||||||
"please go to the <a href=\"https://www.rug.nl/cope/projecten/het-anderhalve-"
|
"please go to the <a href=\"https://www.rug.nl/cope/projecten/het-anderhalve-"
|
||||||
"meter-ziekenhuis/aanmelden\">Signup page</a> "
|
"meter-ziekenhuis/aanmelden\">Signup page</a> "
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Hier kunt u inloggen om nieuwe roosters te maken. Als u geen login heeft, "
|
"Hier kunt u inloggen om nieuwe roosters te maken. Als u geen login heeft, ga "
|
||||||
"ga dan naar de <a href=\"https://www.rug.nl/cope/projecten/het-anderhalve-"
|
"dan naar de <a href=\"https://www.rug.nl/cope/projecten/het-anderhalve-meter-"
|
||||||
"meter-ziekenhuis/aanmelden\">aanmeld page</a> "
|
"ziekenhuis/aanmelden\">aanmeld page</a> "
|
||||||
|
|
||||||
#: templates/registration/login.html:24
|
#: templates/registration/login.html:24
|
||||||
msgid "Lost password?"
|
msgid "Lost password?"
|
||||||
|
@ -11,10 +11,13 @@ ALLOWED_HOSTS=127.0.0.1,localhost
|
|||||||
INTERNAL_IPS=127.0.0.1
|
INTERNAL_IPS=127.0.0.1
|
||||||
|
|
||||||
# Enter the database url connection: https://github.com/jacobian/dj-database-url
|
# Enter the database url connection: https://github.com/jacobian/dj-database-url
|
||||||
DATABASE_URL=sqlite:////opt/deploy/VRE/VirtualResearchEnvironment/db.sqlite3
|
DATABASE_URL=sqlite:////opt/poli_planning/polyclinic_scheduling/db.sqlite3
|
||||||
|
|
||||||
# The location on disk where the static files will be placed during deployment. Setting is required
|
# The location on disk where the static files will be placed during deployment. Setting is required
|
||||||
STATIC_ROOT =
|
STATIC_ROOT=
|
||||||
|
|
||||||
|
# Enter the default timezone for the visitors when it is not known.
|
||||||
|
TIME_ZONE=Europe/Amsterdam
|
||||||
|
|
||||||
# Email settings
|
# Email settings
|
||||||
|
|
||||||
|
@ -8,7 +8,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2020-05-18 09:07+0000\n"
|
"POT-Creation-Date: 2020-06-08 13:43+0200\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
@ -18,12 +18,8 @@ msgstr ""
|
|||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||||
|
|
||||||
#: polyclinic_scheduling/settings.py:129
|
|
||||||
msgid "Dutch"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: polyclinic_scheduling/settings.py:130
|
#: polyclinic_scheduling/settings.py:130
|
||||||
msgid "English"
|
msgid "Dutch"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: polyclinic_scheduling/urls.py:22 polyclinic_scheduling/urls.py:23
|
#: polyclinic_scheduling/urls.py:22 polyclinic_scheduling/urls.py:23
|
||||||
|
@ -7,7 +7,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: \n"
|
"Project-Id-Version: \n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2020-05-18 09:07+0000\n"
|
"POT-Creation-Date: 2020-06-08 13:43+0200\n"
|
||||||
"PO-Revision-Date: 2020-05-15 12:49+0200\n"
|
"PO-Revision-Date: 2020-05-15 12:49+0200\n"
|
||||||
"Last-Translator: Joshua Rubingh <j.g.rubingh@rug.nl>\n"
|
"Last-Translator: Joshua Rubingh <j.g.rubingh@rug.nl>\n"
|
||||||
"Language-Team: \n"
|
"Language-Team: \n"
|
||||||
@ -18,14 +18,10 @@ msgstr ""
|
|||||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||||
"X-Generator: Poedit 2.0.6\n"
|
"X-Generator: Poedit 2.0.6\n"
|
||||||
|
|
||||||
#: polyclinic_scheduling/settings.py:129
|
#: polyclinic_scheduling/settings.py:130
|
||||||
msgid "Dutch"
|
msgid "Dutch"
|
||||||
msgstr "Nederlands"
|
msgstr "Nederlands"
|
||||||
|
|
||||||
#: polyclinic_scheduling/settings.py:130
|
|
||||||
msgid "English"
|
|
||||||
msgstr "Engels"
|
|
||||||
|
|
||||||
#: polyclinic_scheduling/urls.py:22 polyclinic_scheduling/urls.py:23
|
#: polyclinic_scheduling/urls.py:22 polyclinic_scheduling/urls.py:23
|
||||||
msgid "University of Groningen Polyclinic planning tool"
|
msgid "University of Groningen Polyclinic planning tool"
|
||||||
msgstr "RUG Poliklinieken planning tool"
|
msgstr "RUG Poliklinieken planning tool"
|
||||||
@ -33,3 +29,6 @@ msgstr "RUG Poliklinieken planning tool"
|
|||||||
#: polyclinic_scheduling/urls.py:24
|
#: polyclinic_scheduling/urls.py:24
|
||||||
msgid "Polyclinic planning tool"
|
msgid "Polyclinic planning tool"
|
||||||
msgstr "Poliklinieken planning tool"
|
msgstr "Poliklinieken planning tool"
|
||||||
|
|
||||||
|
#~ msgid "English"
|
||||||
|
#~ msgstr "Engels"
|
||||||
|
@ -61,6 +61,7 @@ MIDDLEWARE = [
|
|||||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||||
'django.contrib.messages.middleware.MessageMiddleware',
|
'django.contrib.messages.middleware.MessageMiddleware',
|
||||||
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||||
|
'apps.RUG_template.middleware.TimezoneMiddleware',
|
||||||
'django.middleware.locale.LocaleMiddleware',
|
'django.middleware.locale.LocaleMiddleware',
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -123,14 +124,14 @@ LOGOUT_REDIRECT_URL = '/'
|
|||||||
# Internationalization
|
# Internationalization
|
||||||
# https://docs.djangoproject.com/en/3.0/topics/i18n/
|
# https://docs.djangoproject.com/en/3.0/topics/i18n/
|
||||||
|
|
||||||
LANGUAGE_CODE = 'en-us'
|
LANGUAGE_CODE = 'nl'
|
||||||
|
|
||||||
LANGUAGES = [
|
LANGUAGES = [
|
||||||
('nl', _('Dutch')),
|
('nl', _('Dutch')),
|
||||||
('en', _('English')),
|
# ('en', _('English')),
|
||||||
]
|
]
|
||||||
|
|
||||||
TIME_ZONE = 'UTC'
|
TIME_ZONE = config('TIME_ZONE', default='UTC')
|
||||||
|
|
||||||
USE_I18N = True
|
USE_I18N = True
|
||||||
|
|
||||||
|
1
polyclinic_scheduling/static/.gitignore
vendored
1
polyclinic_scheduling/static/.gitignore
vendored
@ -1 +0,0 @@
|
|||||||
|
|
||||||
|
@ -2,4 +2,6 @@ Django==3.0.6
|
|||||||
jsonfield==3.1.0
|
jsonfield==3.1.0
|
||||||
python-decouple==3.3
|
python-decouple==3.3
|
||||||
dj-database-url==0.5.0
|
dj-database-url==0.5.0
|
||||||
mysqlclient==1.4.6
|
mysqlclient==1.4.6
|
||||||
|
django-ipware==2.1.0
|
||||||
|
requests==2.23.0
|
Reference in New Issue
Block a user