adamspd / django-appointment Goto Github PK
View Code? Open in Web Editor NEWA Django app for managing appointment scheduling with ease and flexibility.
License: Apache License 2.0
A Django app for managing appointment scheduling with ease and flexibility.
License: Apache License 2.0
There's no view defined to get all the services defined.
There should be a URL defined to add a new staff member. The one that exists only allow staff member update:
path('create-staff-member/int:user_id/', add_or_update_staff_info, name='add_or_update_staff_info'),
On service addition, redirect to service adding page, not to user profile.
The image is not saved when creating the service.
the month is too big
the button is also too big
the calendar is too large
the slots are too big and container too large.
As a user of a specific Django package, I frequently encounter challenges when determining the compatibility of different versions of the package with various versions of Django. It would be valuable to have a dedicated resource, such as a compatibility table or matrix, that clearly outlines which versions of the package are compatible with specific versions of Django.
I envision a centralized resource within the documentation of the package, providing users with a comprehensive table or compatibility matrix.
Currently, users often rely on scattered information from release notes, examples, and GitHub issues to determine compatibility between the package and Django versions.
How important is this feature to you?
Please consider adding some.
Describe the bug
Due to the misuse of date.weekday() which returns the python format (not used by the package) a different day is used so the slots asked are not the ones expected
Faulty code
def get_available_slots_for_staff(date, staff_member):
"""Calculate the available time slots for a given date and a staff member.
:param date: The date for which to calculate the available slots
:param staff_member: The staff member for which to calculate the available slots
:return: A list of available time slots as strings in the format '%I:%M %p' like ['10:00 AM', '10:30 AM']
"""
# Check if the provided date is a day off for the staff member
days_off_exist = check_day_off_for_staff(staff_member=staff_member, date=date)
if days_off_exist:
return []
# Check if the staff member works on the provided date
day_of_week = date.weekday() # Python's weekday starts from Monday (0) to Sunday (6)
working_hours_dict = get_working_hours_for_staff_and_day(staff_member, day_of_week)
if not working_hours_dict:
return []
slot_duration = datetime.timedelta(minutes=staff_member.get_slot_duration())
slots = calculate_staff_slots(date, staff_member)
slots = exclude_pending_reschedules(slots, staff_member, date)
appointments = get_appointments_for_date_and_time(date, working_hours_dict['start_time'],
working_hours_dict['end_time'], staff_member)
slots = exclude_booked_slots(appointments, slots, slot_duration)
return [slot.strftime('%I:%M %p') for slot in slots]
Expected behavior
Slots already taken should not be shown to users.
Describe the bug
When User model is customized and only take email as username to login an error is thrown when finishing scheduling an appointment :
create_user() got an unexpected keyword argument 'username'
Describe the bug
On the appointment page, when no staff user is selected, if I click on a day on the calendar, a request is still sent to get staff member available slots
GET | http://127.0.0.1:8000/en/ajax/available_slots/?selected_date=2024-02-09&staff_id=none
Expected behaviour
if staff_id == none, no Ajax request sent.
Describe the bug
On admin pages, if a name is not provided, use username.
Describe the bug
Not all pages are ready for translation
To Reproduce
See appointments.js' file
As pointed out by the issue #2 regarding the minimum time between two slots, being able to manually enter your slots would be one possible solution, especially for services that might require preparation or rest time between sessions. But it would require more effort to manually add the slots by the time. Another solution would be to add another variable that would be taken into account in calculating the pause time between slots (automatic solution).
When a user takes an appointment, it has a reminder case, if chosen, we have to send an email reminder (phone reminder maybe later) to tell him/her that he has an appointment with the details of the appointment. Not yet implemented.
Describe the bug
For admin to be able to see/edit an appointment, he has to be a staff member and offer at least one service.
An admin may want to change some information without being a staff member or even offering a service if a staff member.
Currently, when logged in as an admin, the modification available are the ones also available for the staff member. Add a new field to be able to change an appointment's staff member.
plugin of django-appointment to integrate with django cms, it would be perfect,
I have seen many ideas of appointment plugin with wordpress/ php frameworks, but for django not yet.
this app seems contain all features for scheduling appointment.
Describe the bug
Can't update django-phonenumber-field to latest version due to incompatibility issue
Describe the bug
Password is neither set nor email sent to staff member user when a profile is created for him/her by admin. Thus, he/she will never be able to log in and complete his/her profile.
Expected behavior
Email staff member user with information about how they can reset their password.
Additional context
I added a TODO label in the code since when I saw it, I was in main branch.
To do as quick as possible.
Describe the bug
Environment:
Request Method: POST
Request URL: https://django-appt.adamspierredavid.com/appointment/client-info/1/17156424663544787568680320b4c4db4ba6968fe20a52242/
Django Version: 5.0.6
Python Version: 3.11.9
Installed Applications:
['django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'main_app',
'appointment']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.middleware.locale.LocaleMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'main_app.middlewares.RestrictAdminAccessMiddleware']
Traceback (most recent call last):
File "/home/ubuntu/web/django_appt_web/env/lib/python3.11/site-packages/django/core/handlers/exception.py", line 55, in inner
response = get_response(request)
^^^^^^^^^^^^^^^^^^^^^
File "/home/ubuntu/web/django_appt_web/env/lib/python3.11/site-packages/django/core/handlers/base.py", line 197, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/ubuntu/web/django_appt_web/env/lib/python3.11/site-packages/appointment/views.py", line 350, in appointment_client_information
user = create_new_user(client_data)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/ubuntu/web/django_appt_web/env/lib/python3.11/site-packages/appointment/utils/db_helpers.py", line 274, in create_new_user
client_data['first_name'], client_data['last_name'] = parse_name(client_data['name'])
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Exception Type: ValueError at /appointment/client-info/1/17156424663544787568680320b4c4db4ba6968fe20a52242/
Exception Value: not enough values to unpack (expected 2, got 1)
To Reproduce
Steps to reproduce the behavior:
Expected behavior
Handle that better when only firstname is entered (to work).
Describe the bug
Don't allow user to re-submit appointment information after the appointment has been successfully created.
To Reproduce
Steps to reproduce the behavior:
Created an appointment request on the page to select date and stuff, then send user info on the next page to create appointment. Aftewards, instead of creating a new appointment request, I used the arrow back button to come back to the page and then resend user information thus the same appointment request for the new appointment.
Expected behavior
Prevent the users from going back and resubmitting the same information for an appointment after it's been successfully created.
Additional context
Environment:
Request Method: POST
Request URL: http://127.0.0.1:8000/en/verification-code/92/170765011615498819679753da1ee4e2db40b6bcac897ee20/
Django Version: 4.2.8
Python Version: 3.11.0
Installed Applications:
['django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'appointment.apps.AppointmentConfig',
'django_q']
Installed Middleware:
['django.middleware.security.SecurityMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
'django.middleware.locale.LocaleMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware']
Traceback (most recent call last):
File "/Users/adamspierredavid/developer/PycharmProjects/django-appointment/venv/lib/python3.11/site-packages/django/db/backends/utils.py", line 89, in _execute
return self.cursor.execute(sql, params)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/adamspierredavid/developer/PycharmProjects/django-appointment/venv/lib/python3.11/site-packages/django/db/backends/sqlite3/base.py", line 328, in execute
return super().execute(query, params)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The above exception (UNIQUE constraint failed: appointment_appointment.appointment_request_id) was the direct cause of the following exception:
File "/Users/adamspierredavid/developer/PycharmProjects/django-appointment/venv/lib/python3.11/site-packages/django/core/handlers/exception.py", line 55, in inner
response = get_response(request)
^^^^^^^^^^^^^^^^^^^^^
File "/Users/adamspierredavid/developer/PycharmProjects/django-appointment/venv/lib/python3.11/site-packages/django/core/handlers/base.py", line 197, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/adamspierredavid/developer/PycharmProjects/django-appointment/appointment/views.py", line 400, in enter_verification_code
response = create_appointment(request=request, appointment_request_obj=appointment_request_object,
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/adamspierredavid/developer/PycharmProjects/django-appointment/appointment/views.py", line 278, in create_appointment
appointment = create_and_save_appointment(appointment_request_obj, client_data, appointment_data)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/adamspierredavid/developer/PycharmProjects/django-appointment/appointment/utils/db_helpers.py", line 100, in create_and_save_appointment
appointment = Appointment.objects.create(
Exception Type: IntegrityError at /en/verification-code/92/170765011615498819679753da1ee4e2db40b6bcac897ee20/
Exception Value: UNIQUE constraint failed: appointment_appointment.appointment_request_id
Use Session to Store Submission State: After the form is successfully submitted and the appointment is created, store a flag in the user's session to indicate that the submission has already occurred.
Check Session on Form Page Load: On the page where the user fills out the form, check the session flag at the beginning of the request. If the flag indicates a submission has already occurred, redirect the user to a page that explains they cannot resubmit the form.
Clear Session on Start of a New Appointment Process: Ensure that the flag in the session is cleared or reset when the user starts the process of creating a new appointment. This could be when they first load the form page under a new session or click a button to start a new appointment.
Describe the bug
If the service is free, it redirects to a pay page.
Expected behaviour
If service is free, redirect to thank you page even if pay link is set
Hello. I ran into django-appointment recently and I have started to play with it, it's very nice.
I would like to book a physical resource, not a human (it won't be a StaffMember
, then)
I have no idea. Ideally it would be a different object than StaffMember
but I have the feeling it might be hard or even undoable
How important is this feature to you?
I don't think I will be able to achieve what I want with the current system :)
Can't delete appointment.
Provide an endpoint that will allow to delete an appointment.
How important is this feature to you?
Describe the bug
If a staff (Django-related role) is authenticated and tries to retrieved this endpoint : /appointment/app-admin/user-event/
he'll get the following error if debug = true
Traceback (most recent call last):
File "/Users/adamspierredavid/developer/PycharmProjects/crueltouch/venv/lib/python3.11/site-packages/django/core/handlers/exception.py", line 55, in inner
response = get_response(request)
^^^^^^^^^^^^^^^^^^^^^
File "/Users/adamspierredavid/developer/PycharmProjects/crueltouch/venv/lib/python3.11/site-packages/django/core/handlers/base.py", line 197, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/adamspierredavid/developer/PycharmProjects/crueltouch/venv/lib/python3.11/site-packages/appointment/decorators.py", line 26, in wrapper
return func(request, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/adamspierredavid/developer/PycharmProjects/crueltouch/venv/lib/python3.11/site-packages/appointment/decorators.py", line 39, in wrapper
return func(request, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/adamspierredavid/developer/PycharmProjects/crueltouch/venv/lib/python3.11/site-packages/appointment/views_admin.py", line 39, in get_user_appointments
appointments = fetch_user_appointments(request.user)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/adamspierredavid/developer/PycharmProjects/crueltouch/venv/lib/python3.11/site-packages/appointment/services.py", line 44, in fetch_user_appointments
staff_member_instance = user.staffmember
^^^^^^^^^^^^^^^^
File "/Users/adamspierredavid/developer/PycharmProjects/crueltouch/venv/lib/python3.11/site-packages/django/utils/functional.py", line 268, in inner
return func(_wrapped, *args)
^^^^^^^^^^^^^^^^^^^^^
File "/Users/adamspierredavid/developer/PycharmProjects/crueltouch/venv/lib/python3.11/site-packages/django/db/models/fields/related_descriptors.py", line 492, in __get__
raise self.RelatedObjectDoesNotExist(
client.models.UserClient.staffmember.RelatedObjectDoesNotExist: UserClient has no staffmember.
[01/Dec/2023 23:29:58] "GET /appointment/app-admin/user-event/ HTTP/1.1" 500 110721
2023-12-01 23:29:58,433 - django.request - ERROR - Internal Server Error: /appointment/app-admin/user-event/
Traceback (most recent call last):
File "/Users/adamspierredavid/developer/PycharmProjects/crueltouch/venv/lib/python3.11/site-packages/django/core/handlers/exception.py", line 55, in inner
response = get_response(request)
^^^^^^^^^^^^^^^^^^^^^
File "/Users/adamspierredavid/developer/PycharmProjects/crueltouch/venv/lib/python3.11/site-packages/django/core/handlers/base.py", line 197, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/adamspierredavid/developer/PycharmProjects/crueltouch/venv/lib/python3.11/site-packages/appointment/decorators.py", line 26, in wrapper
return func(request, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/adamspierredavid/developer/PycharmProjects/crueltouch/venv/lib/python3.11/site-packages/appointment/decorators.py", line 39, in wrapper
return func(request, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/adamspierredavid/developer/PycharmProjects/crueltouch/venv/lib/python3.11/site-packages/appointment/views_admin.py", line 39, in get_user_appointments
appointments = fetch_user_appointments(request.user)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/Users/adamspierredavid/developer/PycharmProjects/crueltouch/venv/lib/python3.11/site-packages/appointment/services.py", line 44, in fetch_user_appointments
staff_member_instance = user.staffmember
^^^^^^^^^^^^^^^^
File "/Users/adamspierredavid/developer/PycharmProjects/crueltouch/venv/lib/python3.11/site-packages/django/utils/functional.py", line 268, in inner
return func(_wrapped, *args)
^^^^^^^^^^^^^^^^^^^^^
File "/Users/adamspierredavid/developer/PycharmProjects/crueltouch/venv/lib/python3.11/site-packages/django/db/models/fields/related_descriptors.py", line 492, in __get__
raise self.RelatedObjectDoesNotExist(
client.models.UserClient.staffmember.RelatedObjectDoesNotExist: UserClient has no staffmember.
To Reproduce
Steps to reproduce the behavior:
Expected behavior
Not an error but a redirection or anything more concise than just an error or a 5xx code return.
Describe the bug
I have a problem when installing and running the app
To Reproduce
Steps to reproduce the behavior:
Expected behavior
To create the migrations successfully
Logs
path('appointment/', include('appointment.urls')),
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/site-packages/django/urls/conf.py", line 38, in include
urlconf_module = import_module(urlconf_module)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/local/lib/python3.12/importlib/__init__.py", line 90, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "<frozen importlib._bootstrap>", line 1387, in _gcd_import
File "<frozen importlib._bootstrap>", line 1360, in _find_and_load
File "<frozen importlib._bootstrap>", line 1331, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 935, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 995, in exec_module
File "<frozen importlib._bootstrap>", line 488, in _call_with_frames_removed
File "/usr/local/lib/python3.12/site-packages/appointment/urls.py", line 11, in <module>
from appointment.views import (
File "/usr/local/lib/python3.12/site-packages/appointment/views.py", line 24, in <module>
from appointment.forms import AppointmentForm, AppointmentRequestForm, SlotForm, ClientDataForm
File "/usr/local/lib/python3.12/site-packages/appointment/forms.py", line 42, in <module>
class AppointmentForm(forms.ModelForm):
File "/usr/local/lib/python3.12/site-packages/appointment/forms.py", line 43, in AppointmentForm
phone = PhoneNumberField(widget=PhoneNumberPrefixWidget(initial='US'))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
TypeError: MultiWidget.__init__() got an unexpected keyword argument 'initial'
Additional context
I run this in docker compose, although I don't think that might be relevant
Describe the bug
Django Q2 is a fork of Django Q. Big thanks to Ilan Steemers for starting this project. Unfortunately, development has stalled since June 2021. Django Q2 is the new updated version of Django Q, with dependencies updates, docs updates and several bug fixes. Original repository: https://github.com/Koed00/django-q
For example, because of this stalling, incompatibility with django 5.0.2 is found (usage of baseconv, which was deprecated).
Utilize Django-Q to schedule tasks for cleaning up unnecessary objects, such as Appointment Requests that are not associated with any appointments and are older than a specified period.
UNIQUE constraint failed: auth_user.username
Request Method: | POST |
---|---|
http://127.0.0.1:8000/client-info/10/169117242435964223441c78207164a9a991ea4b418a9f1a8/ | |
4.2.3 | |
IntegrityError | |
UNIQUE constraint failed: auth_user.username | |
/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages/django/db/backends/sqlite3/base.py, line 328, in execute | |
appointment.views.appointment_client_information | |
/usr/local/bin/python3.11 | |
3.11.0 | |
['/Users/adamspierredavid/developer/PycharmProjects/appointments', '/Users/adamspierredavid/developer/PycharmProjects/appointments', '/Users/adamspierredavid/Library/Application ' 'Support/JetBrains/Toolbox/apps/PyCharm-P/ch-0/231.8770.66/PyCharm.app/Contents/plugins/python/helpers/pycharm_display', '/Library/Frameworks/Python.framework/Versions/3.11/lib/python311.zip', '/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11', '/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/lib-dynload', '/Users/adamspierredavid/Library/Python/3.11/lib/python/site-packages', '/Library/Frameworks/Python.framework/Versions/3.11/lib/python3.11/site-packages', '/Users/adamspierredavid/Library/Application ' 'Support/JetBrains/Toolbox/apps/PyCharm-P/ch-0/231.8770.66/PyCharm.app/Contents/plugins/python/helpers/pycharm_matplotlib_backend'] | |
Fri, 04 Aug 2023 14:07:19 -0400 |
Currently, the system sends only reminder emails using Django-Q task functionality.
It is proposed to introduce a new variable in the settings to determine if the user prefers all emails to be sent using Django-Q task functionality. This approach is expected to optimize the load time of pages that wait for an email to be dispatched before completing the loading process. The default behaviour will still be kept in case user don't want Django-Q.
Describe the bug
By fixing the duplicate slot bug in #142, a new bug was introduced where even on selecting staff member, no slots were fetch
Describe the bug
Followed installation steps as specified in the docs quick start guide. Upon running server, seems to be an issue with loading the appointment URL. Despite exactly matching url, opens django debug page:
Request Method: | GET
http://127.0.0.1:8000/appointment/
Django tried these URL patterns, in this order:
appointment/ request/<int:service_id>/ [name='appointment_request']
appointment/ request-submit/ [name='appointment_request_submit']
appointment/ appointment/<str:id_request>/reschedule/ [name='prepare_reschedule_appointment']
appointment/ appointment-reschedule-submit/ [name='reschedule_appointment_submit']
appointment/ confirm-reschedule/<str:id_request>/ [name='confirm_reschedule']
appointment/ client-info/<int:appointment_request_id>/<str:id_request>/ [name='appointment_client_information']
appointment/ verification-code/<int:appointment_request_id>/<str:id_request>/ [name='enter_verification_code']
appointment/ verification-code/ [name='email_change_verification_code']
appointment/ thank-you/<int:appointment_id>/ [name='default_thank_you']
appointment/ verify/<uidb64>/<str:token>/ [name='set_passwd']
appointment/ ajax/
appointment/ app-admin/
The current path, appointment/, didnโt match any of these.
Desktop (please complete the following information):
Smartphone (please complete the following information):
I am tired and there is absolutely the issue that I'm making a stupid error. Sorry if that's the case lmao.
class AppointmentForm(forms.ModelForm):
File "/usr/local/lib/python3.10/site-packages/appointment/forms.py", line 43, in AppointmentForm
phone = PhoneNumberField(widget=PhoneNumberPrefixWidget(initial='US'))
TypeError: MultiWidget.init() got an unexpected keyword argument 'initial'
Version 3.6.0
Just change line 43 in forms.py FROM:
phone = PhoneNumberField(widget=PhoneNumberPrefixWidget(initial='US'))
TO:
phone = PhoneNumberField(widget=PhoneNumberPrefixWidget({'initial':'US'}))
Describe the bug
The username used is generated even if one is provided by the client
Faulty code
def create_user_with_username(client_data: dict):
CLIENT_MODEL = get_user_model()
username = generate_unique_username_from_email(client_data['email'])
user_data = {
'username': username,
'email': client_data['email'],
'first_name': client_data.get('first_name', ''),
'last_name': client_data.get('last_name', '')
}
user = CLIENT_MODEL.objects.create_user(**user_data)
return user
Solution
username = generate_unique_username_from_email(client_data['email']) if 'username' not in client_data else
client_data['username']
Currently, an administrator can add a staff member by entering the individual's name and email address, after which an account is created for them. Subsequently, an email is dispatched to the new staff member, prompting them to set a new password.
What happens if the staff member already possesses a user account? To address this potential overlap, it might be beneficial to introduce an option that allows the addition of a staff member by selecting from existing user accounts.
Hello,
Let's configure the settings like those:
APPOINTMENT_SLOT_DURATION = 120 # minutes
APPOINTMENT_LEAD_TIME = (11, 0) # (hour, minute) 24-hour format
APPOINTMENT_FINISH_TIME = (14, 0) # (hour, minute) 24-hour format
A service with a duration of 2 hours.
When you want to book a slot you see well the two slots : 11am and 1pm
If I book the slot at 1pm, I can also book the slot of 11am
But if I first book the slot of 11am, then when I come back to book again the slot of 1pm, it just says No availability.
Checking the appointment, I have only one for the specified date
Hi,
first of all thanks for creating this amazing plugin.
I did not used it yet but as I read the docs I think this has much potential.
I want to do a very similar thing accept that I need support for a staff feature. I am thinking about availability of staff members on some days, holidays, services only some staffys will do etc.
Is this something you will implement as well?
greetings,
Nico
Describe the bug
apt = Appointment.objects.get(id=id)
apt.get_client_name() returns only first name on cases where last name exist also
In Appointment model, no get_client_email method is defined.
Expected behavior
Full name returned
If you have two services defined, if you make a reservation for one service, in this case the first one, no time slot are available for the second one. It seems to only take into account the first service or first reservation that it found. The information showed of the service is well the right one.
Describe the bug
I run into a 404 error when running the server for the first time.
To Reproduce
Steps to reproduce the behavior:
python manage.py runserver
Expected behavior
Base url brings us to a landing page for making appointments.
Screenshots
If applicable, add screenshots to help explain your problem.
Desktop (please complete the following information):
Additional context
Add any other context about the problem here.
"""
Django settings for appointments project.
Generated by 'django-admin startproject' using Django 4.1.6.
For more information on this file, see
https://docs.djangoproject.com/en/4.1/topics/settings/
For the full list of settings and their values, see
https://docs.djangoproject.com/en/4.1/ref/settings/
"""
import os
from pathlib import Path
from django.conf import locale
from django.utils.translation import gettext_lazy as _
from dotenv import load_dotenv
load_dotenv()
# Build paths inside the project like this: BASE_DIR / 'subdir'.
BASE_DIR = Path(__file__).resolve().parent.parent
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/4.1/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = "django-insecure-(%st!9pc%2d%*b3xt8@0o7*4rkxq-$6j3y-(b*ftz^m2^r4l$z"
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
ALLOWED_HOSTS = ["*"]
# Application definition
INSTALLED_APPS = [
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
'appointment.apps.AppointmentConfig',
'django_q',
]
MIDDLEWARE = [
"django.middleware.security.SecurityMiddleware",
"django.contrib.sessions.middleware.SessionMiddleware",
'django.middleware.locale.LocaleMiddleware',
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
]
ROOT_URLCONF = "appointments.urls"
TEMPLATES = [
{
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [BASE_DIR / 'appointment/templates']
,
"APP_DIRS": True,
"OPTIONS": {
"context_processors": [
"django.template.context_processors.debug",
"django.template.context_processors.request",
"django.contrib.auth.context_processors.auth",
"django.contrib.messages.context_processors.messages",
],
},
},
]
WSGI_APPLICATION = "appointments.wsgi.application"
# Database
# https://docs.djangoproject.com/en/4.1/ref/settings/#databases
DATABASES = {
"default": {
"ENGINE": "django.db.backends.sqlite3",
"NAME": BASE_DIR / "db.sqlite3",
}
}
# Password validation
# https://docs.djangoproject.com/en/4.1/ref/settings/#auth-password-validators
AUTH_PASSWORD_VALIDATORS = [
{
"NAME": "django.contrib.auth.password_validation.UserAttributeSimilarityValidator",
},
{
"NAME": "django.contrib.auth.password_validation.MinimumLengthValidator",
},
{
"NAME": "django.contrib.auth.password_validation.CommonPasswordValidator",
},
{
"NAME": "django.contrib.auth.password_validation.NumericPasswordValidator",
},
]
# Internationalization
# https://docs.djangoproject.com/en/4.1/topics/i18n/
LANGUAGE_CODE = "en"
TIME_ZONE = 'Asia/Singapore'
USE_I18N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/4.1/howto/static-files/
STATIC_URL = "/static/"
STATICFILES_DIRS = [os.path.join(BASE_DIR, "appointment/static")]
# Default primary key field type
# https://docs.djangoproject.com/en/4.1/ref/settings/#default-auto-field
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
APPOINTMENT_BUFFER_TIME = 0
LOCALE_PATHS = [os.path.join(BASE_DIR, "locale")]
LANGUAGES = (
('en', _('English')),
('es', _('Spanish')),
('fr', _('French')),
)
# Email settings
EMAIL_BACKEND = 'django.core.mail.backends.smtp.EmailBackend'
EMAIL_HOST = 'smtp.gmail.com'
EMAIL_PORT = 587
EMAIL_HOST_USER = os.getenv('EMAIL_HOST_USER', default="")
EMAIL_HOST_PASSWORD = os.getenv('EMAIL_HOST_PASSWORD', default="")
EMAIL_USE_TLS = True
EMAIL_SUBJECT_PREFIX = ""
EMAIL_USE_LOCALTIME = True
SERVER_EMAIL = EMAIL_HOST_USER
ADMINS = [
('Adams', "[email protected]"),
]
Q_CLUSTER = {
'name': 'DjangORM',
'workers': 4,
'timeout': 90,
'retry': 120,
'queue_limit': 50,
'bulk': 10,
'orm': 'default',
}
"""appointments URL Configuration
The `urlpatterns` list routes URLs to views. For more information please see:
https://docs.djangoproject.com/en/4.1/topics/http/urls/
Examples:
Function views
1. Add an import: from my_app import views
2. Add a URL to urlpatterns: path('', views.home, name='home')
Class-based views
1. Add an import: from other_app.views import Home
2. Add a URL to urlpatterns: path('', Home.as_view(), name='home')
Including another URLconf
1. Import the include() function: from django.urls import include, path
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
"""
from django.conf.urls.i18n import i18n_patterns
from django.contrib import admin
from django.urls import include, path
urlpatterns = i18n_patterns(
path("admin/", admin.site.urls),
path('i18n/', include('django.conf.urls.i18n')),
path("appointment/", include("appointment.urls")),
)
Thanks for this nice app.
This is more a request for an enhancement.
Would it be possible to define the lead-time, finish-time and slot-duration per service.
It would be also nice to a have a minimum time between two slot.
So if we define a service with a slot duration of 2h, a lead-time at 9 o'clock and an interval time of 30 minutes, the first slot would be 9h, the next one 11h30, then 14h, and so on.
Describe the bug
When attempting to add the application to the project, the corresponding models are not being created.
To Reproduce
I follow this instructions.
Expected behavior
After adding the 'appointment' application and running migrations, the corresponding models should be created successfully.
Screenshots
I follow all the steps and my project doesn't run migrations of 'appointment' application:
And It's installed correctly
Desktop (please complete the following information):
Additional context
The 'appointment' application is installed correctly, but the models are not being created.
appointment/templates/administration/display_appointment.html:27
msgid "Start time"
appointment/templates/administration/manage_working_hours.html:39
appointment/templates/administration/user_profile.html:164
msgid "Start Time"
appointment/templates/administration/display_appointment.html:31
msgid "End time"
appointment/templates/administration/manage_working_hours.html:53
appointment/templates/administration/user_profile.html:165
msgid "End Time"
Add Plural
appointment/templates/administration/user_profile.html:163
msgid "Day"
Remove spaces
site-packages/appointment/utils/date_time.py:62
msgid " and "
Describe the bug
Email Verification: Automatically creating a user and setting their password might pose a security risk, especially if the user is unaware that an account has been created for them.
Password Handling: Setting a predictable password (like combining website name and current year) is not secure.
The faulty code
def create_new_user(client_data: dict):
CLIENT_MODEL = get_user_model()
# Check if client_data has first_name and last_name
if 'first_name' not in client_data or 'last_name' not in client_data:
# Assuming 'name' contains a single space between first and last name.
client_data['first_name'], client_data['last_name'] = parse_name(client_data['name'])
try:
# Check if the 'username' field exists in the User model
CLIENT_MODEL._meta.get_field('username')
user = create_user_with_username(client_data)
except FieldDoesNotExist:
user = create_user_with_email(client_data)
password = f"{get_website_name()}{get_current_year()}"
user.set_password(password) # Use set_password to ensure the password is hashed
user.save()
return user
Expected behavior
Possible Solution
See above
On the main branch:
./manage.py test appointment.tests.utils.test_db_helpers --shuffle
Using shuffle seed: 4356288042 (generated)
Found 87 test(s).
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
...........................................E.......2024-03-27 02:06:11,934 - appointment.logger_config - INFO - Scheduling email reminder for appointment 1 at 2024-03-26 09:00:00+01:00
.................F....F...2024-03-27 02:06:25,464 - appointment.logger_config - INFO - Rescheduling is allowed for service Test Service -> Reschedule count: 0, Reschedule limit: 0
.2024-03-27 02:06:26,213 - appointment.logger_config - INFO - Rescheduling is allowed but no specific limit set for service Test Service -> Reschedule count: 0, Reschedule limit: 3
.2024-03-27 02:06:26,947 - appointment.logger_config - INFO - Rescheduling is allowed for service Test Service -> Reschedule count: 4, Reschedule limit: 3
.2024-03-27 02:06:27,704 - appointment.logger_config - INFO - Rescheduling is allowed but no specific limit set for service Test Service -> Reschedule count: 2, Reschedule limit: 3
2024-03-27 02:06:27,705 - appointment.logger_config - INFO - Rescheduling is allowed but no specific limit set for service Test Service -> Reschedule count: 3, Reschedule limit: 3
.2024-03-27 02:06:28,384 - appointment.logger_config - INFO - New appointment created: {'id': 1, 'client_name': 'Tester2', 'client_email': '[email protected]', 'start_time': '1900-01-01 09:00', 'end_time': '1900-01-01 10:00', 'service_name': 'Test Service', 'address': '123 Main St', 'want_reminder': True, 'additional_info': 'Additional Test Info', 'paid': False, 'amount_to_pay': 100, 'id_request': '171150158838388516e2e264025104d8c93e8144a07168c8c'}
Missing conf: []
2024-03-27 02:06:28,384 - appointment.logger_config - INFO - Scheduling email reminder for appointment 1 at 2024-03-26 09:00:00+01:00
......
======================================================================
ERROR: test_calculate_slots_on_working_day_without_appointments (appointment.tests.utils.test_db_helpers.TestCalculateStaffSlots)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/mathieu/dev/django-appointment/appointment/tests/utils/test_db_helpers.py", line 109, in test_calculate_slots_on_working_day_without_appointments
slots = calculate_staff_slots(self.working_date, self.staff_member1)
File "/Users/mathieu/dev/django-appointment/appointment/utils/db_helpers.py", line 75, in calculate_staff_slots
buffer_duration_minutes = get_staff_member_buffer_time(staff_member, date)
File "/Users/mathieu/dev/django-appointment/appointment/utils/db_helpers.py", line 538, in get_staff_member_buffer_time
_, _, _, buff_time = get_times_from_config(date)
File "/Users/mathieu/dev/django-appointment/appointment/utils/db_helpers.py", line 593, in get_times_from_config
start_time = datetime.datetime.combine(date, datetime.time(hour=config.lead_time.hour,
AttributeError: 'NoneType' object has no attribute 'hour'
======================================================================
FAIL: test_staff_member_buffer_time_with_global_setting (appointment.tests.utils.test_db_helpers.TestStaffMemberTimeFunctions)
Test buffer time when staff member-specific setting is None.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/mathieu/.pyenv/versions/3.10.13/lib/python3.10/unittest/mock.py", line 1379, in patched
return func(*newargs, **newkeywargs)
File "/Users/mathieu/dev/django-appointment/appointment/tests/utils/test_db_helpers.py", line 814, in test_staff_member_buffer_time_with_global_setting
self.assertEqual(buffer_time, 60) # Global setting
AssertionError: 90.0 != 60
======================================================================
FAIL: test_staff_member_slot_duration_with_global_setting (appointment.tests.utils.test_db_helpers.TestStaffMemberTimeFunctions)
Test slot duration when staff member-specific setting is None.
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/mathieu/.pyenv/versions/3.10.13/lib/python3.10/unittest/mock.py", line 1379, in patched
return func(*newargs, **newkeywargs)
File "/Users/mathieu/dev/django-appointment/appointment/tests/utils/test_db_helpers.py", line 826, in test_staff_member_slot_duration_with_global_setting
self.assertEqual(slot_duration, 30) # Global setting
AssertionError: 45.0 != 30
----------------------------------------------------------------------
Ran 87 tests in 47.532s
FAILED (failures=2, errors=1)
Used shuffle seed: 4356288042 (generated)
Destroying test database for alias 'default'...
You can reproduce these failures by re-running the test suite shuffled with the same seed:
./manage.py test appointment.tests.utils.test_db_helpers --shuffle 4356288042
.
I notice that objects created in setUp
sometime are mutated elsewhere, that might be a cause.
Wow your package is really fantastic but it didn't support jalali or shamci calender and in our country miladi calender to book appointments not useful
you can add jalali calender in your project and if you needed my help you can have it bro
I suggest you to use this I found some useful resources:
https://pypi.org/project/django-jalali-date/
https://stackoverflow.com/questions/42182989/jalali-calendar-in-fullcalendar
https://github.com/mzangeneh/fullcalendar-shamsi
Add any other context or screenshots about the feature request here.
How important is this feature to you?
User (superuser/staff member) will be able to create an appointment on right click.
Describe the bug
Even in the example page, it shows Sunday-Thursday days avaiable to work.
To Reproduce
Make monday day avaiable to work, shows only tuesday as day avaiable, and says no one avaible to work on tuesday.
Expected behavior
Should show monday
When booking an appointment, the client is required to enter their email and confirm with an auth code. In some use cases this is unnecessary.
An option so the email verification code step can be skipped, and the client goes straight to the thank-you/payment page. Maybe even an option that does not require the client to enter their email at all.
How important is this feature to you?
Allow clients to reschedule their appointment by themselves
Description
The Django-Appointment project provides a robust solution for appointment scheduling, offering flexibility, efficient task scheduling, and easy integration. However, as of now, the project lacks Docker support, which could streamline setup and deployment processes for developers and users alike. Incorporating Docker and Docker Compose would not only facilitate a smoother development and deployment workflow but also ensure consistency across different environments, enhancing the project's accessibility and ease of use.
Feature Request Details
Proposed Implementation
Dockerfile: Create a Dockerfile to build a Docker image for the Django-Appointment application. This should include:
requirements.txt
.Docker Compose: Introduce a docker-compose.yml
file to define services, networks, and volumes for the application and any auxiliary services it requires (e.g., database, cache, task scheduler).
Expected Outcome
Integrating Docker and Docker Compose into the Django-Appointment project will make it significantly easier for developers to start working on the project, contribute, and deploy it across various environments. This enhancement is expected to attract more contributors and users by lowering the barrier to entry and ensuring a uniform development experience.
Additional Notes
README.md
or the documentation on how to use Docker and Docker Compose with the project.Request for Comments
I invite the maintainers and community to discuss this feature request. Feedback on the proposed implementation, suggestions for improvements, and any concerns are highly welcomed. Let's make Django-Appointment even more accessible and easier to deploy for everyone.
Thank you for considering this feature request.
vic + gpt4 (draft)
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.