Others
CanViewMixin
¶
Bases: GenericContentPermissionMixinBuilder
Ensure the user has permission to view this view's object.
Raises:
| Type | Description |
|---|---|
PermissionDenied
|
if the user cannot edit this view's object. |
CloseCustomerAccountForm
¶
Bases: Form
CounterEditForm(*args, user, instance, **kwargs)
¶
Bases: ModelForm
Source code in counter/forms.py
ProductForm(*args, prefix=None, instance=None, **kwargs)
¶
Bases: ModelForm
Source code in counter/forms.py
ProductFormulaForm
¶
Bases: ModelForm
ReturnableProductForm
¶
Bases: ModelForm
Counter
¶
Bases: Model
barmen_list()
¶
update_activity()
¶
can_refill()
¶
Show if the counter authorize the refilling with physic money.
Refills are authorized if a user having the required permission is currently logged in.
Source code in counter/models.py
get_top_barmen()
¶
Return a QuerySet querying the office hours stats of all the barmen of all time of this counter, ordered by descending number of hours.
Source code in counter/models.py
get_top_customers(since=None)
¶
Return a QuerySet querying the money spent by customers of this counter since the specified date, ordered by descending amount of money spent.
Each element of the QuerySet corresponds to a customer and has the following data :
- the full name (first name + last name) of the customer
- the nickname of the customer
- the amount of money spent by the customer
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
since
|
datetime | date | None
|
timestamp from which to perform the calculation |
None
|
Source code in counter/models.py
get_total_sales(since=None)
¶
Compute and return the total turnover of this counter since the given date.
By default, the date is the start of the current semester.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
since
|
datetime | date | None
|
timestamp from which to perform the calculation |
None
|
Returns:
| Type | Description |
|---|---|
CurrencyField
|
Total revenue earned at this counter. |
Source code in counter/models.py
customer_is_barman(customer)
¶
Check if this counter is a bar and if the customer is currently logged in.
This is useful to compute special prices.
Source code in counter/models.py
Product
¶
Bases: Model
A product, with all its related information.
is_owned_by(user)
¶
Method to see if that object can be edited by the given user.
Source code in counter/models.py
ProductFormula
¶
Bases: Model
ProductType
¶
Bases: OrderedModel
A product type.
Useful only for categorizing.
is_owned_by(user)
¶
Method to see if that object can be edited by the given user.
Refilling
¶
Bases: Model
Handle the refilling.
ReturnableProduct
¶
Bases: Model
A returnable relation between two products (consigne/déconsigne).
update_balances()
¶
Update all returnable balances linked to this object.
Call this when a ReturnableProduct is created or updated.
Warning
This function is expensive (around a few seconds), so try not to run it outside a management command or a task.
Source code in counter/models.py
Selling
¶
Bases: Model
Handle the sellings.
save(*args, allow_negative=False, **kwargs)
¶
allow_negative : Allow this selling to use more money than available for this user.
Source code in counter/models.py
960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 | |
CounterAdminTabsMixin
¶
Bases: TabedViewMixin
CounterListView
¶
CounterEditView
¶
Bases: CounterAdminTabsMixin, UserPassesTestMixin, SuccessMessageMixin, UpdateView
Edit a counter's main informations (for the counter's manager).
CounterEditPropView
¶
CounterCreateView
¶
Bases: CounterAdminTabsMixin, PermissionRequiredMixin, CreateView
Create a counter (for the admins).
CounterDeleteView
¶
Bases: CounterAdminTabsMixin, PermissionRequiredMixin, DeleteView
Delete a counter (for the admins).
ProductTypeListView
¶
ProductTypeCreateView
¶
ProductTypeEditView
¶
ProductListView
¶
Bases: CounterAdminTabsMixin, PermissionRequiredMixin, TemplateView
ProductCreateView
¶
ProductEditView
¶
ProductFormulaListView
¶
Bases: CounterAdminTabsMixin, PermissionRequiredMixin, ListView
ProductFormulaCreateView
¶
Bases: CounterAdminTabsMixin, PermissionRequiredMixin, CreateView
ProductFormulaEditView
¶
Bases: CounterAdminTabsMixin, PermissionRequiredMixin, UpdateView
ProductFormulaDeleteView
¶
Bases: CounterAdminTabsMixin, PermissionRequiredMixin, DeleteView
ReturnableProductListView
¶
Bases: CounterAdminTabsMixin, PermissionRequiredMixin, ListView
ReturnableProductCreateView
¶
Bases: CounterAdminTabsMixin, PermissionRequiredMixin, CreateView
ReturnableProductUpdateView
¶
Bases: CounterAdminTabsMixin, PermissionRequiredMixin, UpdateView
ReturnableProductDeleteView
¶
Bases: CounterAdminTabsMixin, PermissionRequiredMixin, DeleteView
CounterTransactionDeletionView
¶
Bases: DeleteView
RefillingDeleteView
¶
SellingDeleteView
¶
CounterStatView
¶
Bases: PermissionRequiredMixin, DetailView
Show the bar stats.
get_context_data(**kwargs)
¶
Add stats to the context.
Source code in counter/views/admin.py
CounterRefillingListView
¶
RefoundAccountView
¶
Bases: UserPassesTestMixin, SuccessMessageMixin, FormView
Create a selling with the same amount as the current user money.
get_semester_code(d=None)
¶
Return the semester code of the given date. If no date is given, return the semester code of the current semester.
The semester code is an upper letter (A for autumn, P for spring), followed by the last two digits of the year. For example, the autumn semester of 2018 is "A18".
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
d
|
date | None
|
the date to use to compute the semester. If None, use today's date. |
None
|
Returns:
| Type | Description |
|---|---|
str
|
the semester code corresponding to the given date |
Source code in core/utils.py
get_start_of_semester(today=None)
¶
Return the date of the start of the semester of the given date. If no date is given, return the start date of the current semester.
The current semester is computed as follows:
- If the date is between 15/08 and 31/12 => Autumn semester.
- If the date is between 01/01 and 15/02 => Autumn semester of the previous year.
- If the date is between 15/02 and 15/08 => Spring semester
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
today
|
date | None
|
the date to use to compute the semester. If None, use today's date. |
None
|
Returns:
| Type | Description |
|---|---|
date
|
the date of the start of the semester |
Source code in core/utils.py
is_logged_in_counter(request, counter=None)
¶
Check if the request is sent from a device logged to a counter.
The request must also be sent within the frame of a counter's activity. Trying to use this function to manage access to non-sas related resources probably won't work.
A request is considered as coming from a logged counter if :
- Its referer comes from the counter app (eg. fetching user pictures from the click UI) or the request path belongs to the counter app (eg. the barman went back to the main by missclick and go back to the counter)
- There are barmen logged in the current session
Source code in counter/utils.py
CashSummaryFormBase
¶
Bases: Form
CashRegisterSummary
¶
Bases: Model
is_owned_by(user)
¶
Method to see if that object can be edited by the given user.
CashRegisterSummaryItem
¶
Bases: Model
Counter
¶
Bases: Model
barmen_list()
¶
update_activity()
¶
can_refill()
¶
Show if the counter authorize the refilling with physic money.
Refills are authorized if a user having the required permission is currently logged in.
Source code in counter/models.py
get_top_barmen()
¶
Return a QuerySet querying the office hours stats of all the barmen of all time of this counter, ordered by descending number of hours.
Source code in counter/models.py
get_top_customers(since=None)
¶
Return a QuerySet querying the money spent by customers of this counter since the specified date, ordered by descending amount of money spent.
Each element of the QuerySet corresponds to a customer and has the following data :
- the full name (first name + last name) of the customer
- the nickname of the customer
- the amount of money spent by the customer
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
since
|
datetime | date | None
|
timestamp from which to perform the calculation |
None
|
Source code in counter/models.py
get_total_sales(since=None)
¶
Compute and return the total turnover of this counter since the given date.
By default, the date is the start of the current semester.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
since
|
datetime | date | None
|
timestamp from which to perform the calculation |
None
|
Returns:
| Type | Description |
|---|---|
CurrencyField
|
Total revenue earned at this counter. |
Source code in counter/models.py
customer_is_barman(customer)
¶
Check if this counter is a bar and if the customer is currently logged in.
This is useful to compute special prices.
Source code in counter/models.py
Refilling
¶
Bases: Model
Handle the refilling.
CounterAdminTabsMixin
¶
Bases: TabedViewMixin
CounterTabsMixin
¶
Bases: TabedViewMixin
User
¶
Bases: AbstractUser
Defines the base user class, useable in every app.
This is almost the same as the auth module AbstractUser since it inherits from it, but some fields are required, and the username is generated automatically with the name of the user (see generate_username()).
Added field: nick_name, date_of_birth Required fields: email, first_name, last_name, date_of_birth
is_in_group(*, pk=None, name=None)
¶
Check if this user is in the given group. Either a group id or a group name must be provided. If both are passed, only the id will be considered.
The group will be fetched using the given parameter. If no group is found, return False. If a group is found, check if this user is in the latter.
Returns:
| Type | Description |
|---|---|
bool
|
True if the user is the group, else False |
Source code in core/models.py
all_groups()
¶
Get the list of groups this user is in.
Source code in core/models.py
age()
¶
Return the age this user has the day the method is called. If the user has not filled his age, return 0.
Source code in core/models.py
get_short_name()
¶
get_display_name()
¶
Returns the display name of the user.
A nickname if possible, otherwise, the full name.
get_family(godfathers_depth=4, godchildren_depth=4)
¶
Get the family of the user, with the given depth.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
godfathers_depth
|
NonNegativeInt
|
The number of generations of godfathers to fetch |
4
|
godchildren_depth
|
NonNegativeInt
|
The number of generations of godchildren to fetch |
4
|
Returns:
| Type | Description |
|---|---|
set[through]
|
A list of family relationships in this user's family |
Source code in core/models.py
email_user(subject, message, from_email=None, **kwargs)
¶
Sends an email to this User.
generate_username()
¶
Generates a unique username based on the first and last names.
For example: Guy Carlier gives gcarlier, and gcarlier1 if the first one exists.
Returns:
| Type | Description |
|---|---|
str
|
The generated username. |
Source code in core/models.py
is_owner(obj)
¶
Determine if the object is owned by the user.
Source code in core/models.py
can_edit(obj)
¶
Determine if the object can be edited by the user.
Source code in core/models.py
can_view(obj)
¶
Determine if the object can be viewed by the user.
Source code in core/models.py
can_be_viewed_by(user)
¶
Check if the given user can be viewed by this user.
Given users A and B. A can be viewed by B if :
- A and B are the same user
- or B has the permission to view hidden users
- or B can view users in general and A didn't hide its profile
- or B is in A's whitelist.
Source code in core/models.py
clubs_with_rights()
¶
The list of clubs where the user has rights
CashRegisterSummaryForm(*args, **kwargs)
¶
Bases: Form
Provide the cash summary form.
Source code in counter/views/cash.py
CounterCashSummaryView
¶
Bases: CounterTabsMixin, PermissionRequiredMixin, BaseFormView, DetailView
Provide the cash summary form.
CashSummaryEditView
¶
CashSummaryListView
¶
Bases: CounterAdminTabsMixin, PermissionRequiredMixin, ListView
Display a list of cash summaries.
get_context_data(**kwargs)
¶
Add sums to the context.
Source code in counter/views/cash.py
CanViewMixin
¶
Bases: GenericContentPermissionMixinBuilder
Ensure the user has permission to view this view's object.
Raises:
| Type | Description |
|---|---|
PermissionDenied
|
if the user cannot edit this view's object. |
EticketForm
¶
Bases: ModelForm
Eticket
¶
Bases: Model
Eticket can be linked to a product an allows PDF generation.
is_owned_by(user)
¶
Method to see if that object can be edited by the given user.
Selling
¶
Bases: Model
Handle the sellings.
save(*args, allow_negative=False, **kwargs)
¶
allow_negative : Allow this selling to use more money than available for this user.
Source code in counter/models.py
960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 | |
CounterAdminTabsMixin
¶
Bases: TabedViewMixin
EticketListView
¶
EticketCreateView
¶
EticketEditView
¶
EticketPDFView
¶
InvoiceCallForm(*args, month, **kwargs)
¶
Bases: Form
Source code in counter/forms.py
Refilling
¶
Bases: Model
Handle the refilling.
Selling
¶
Bases: Model
Handle the sellings.
save(*args, allow_negative=False, **kwargs)
¶
allow_negative : Allow this selling to use more money than available for this user.
Source code in counter/models.py
960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 | |
CounterAdminTabsMixin
¶
Bases: TabedViewMixin
InvoiceCallView
¶
Bases: CounterAdminTabsMixin, PermissionRequiredMixin, SuccessMessageMixin, FormView
get_context_data(**kwargs)
¶
Add sums to the context.
Source code in counter/views/invoice.py
FragmentMixin
¶
Bases: TemplateResponseMixin, AllowFragment, ContextMixin
Make a view buildable as a fragment that can be embedded in a template.
Most fragments are used in two different ways : - in the request/response cycle, like any regular view - in templates, where the rendering is done in another view
This mixin aims to simplify the initial fragment rendering. The rendered fragment will then be able to re-render itself through the request/response cycle if it uses HTMX.
Example
class MyFragment(FragmentMixin, FormView):
template_name = "app/fragment.jinja"
form_class = MyForm
success_url = reverse_lazy("foo:bar")
# in another view :
def some_view(request):
fragment = MyFragment.as_fragment()
return render(
request,
"app/template.jinja",
context={"fragment": fragment(request)}
)
# in urls.py
urlpatterns = [
path("foo/view", some_view),
path("foo/fragment", MyFragment.as_view()),
]
reload_on_redirect = False
class-attribute
instance-attribute
¶
If True, this fragment will trigger a full page reload on redirect.
StudentCardForm
¶
Bases: ModelForm
Form for adding student cards
Customer
¶
Bases: Model
Customer data of a User.
It adds some basic customers' information, such as the account ID, and is used by other accounting classes as reference to the customer, rather than using User.
save(*args, allow_negative=False, **kwargs)
¶
is_selling : tell if the current action is a selling allow_negative : ignored if not a selling. Allow a selling to put the account in negative Those two parameters avoid blocking the save method of a customer if his account is negative.
Source code in counter/models.py
update_returnable_balance()
¶
Update all returnable balances of this user to their real amount.
Source code in counter/models.py
can_buy()
¶
Check if whether this customer has the right to purchase any item.
Source code in counter/models.py
get_or_create(user)
classmethod
¶
Work in pretty much the same way as the usual get_or_create method, but with the default field replaced by some under the hood.
If the user has an account, return it as is. Else create a new account with no money on it and a new unique account id
Example : ::
user = User.objects.get(pk=1)
account, created = Customer.get_or_create(user)
if created:
print(f"created a new account with id {account.id}")
else:
print(f"user has already an account, with {account.id} € on it"
Source code in counter/models.py
StudentCard
¶
Bases: Model
Alternative way to connect a customer into a counter.
We are using Mifare DESFire EV1 specs since it's used for izly cards https://www.nxp.com/docs/en/application-note/AN10927.pdf UID is 7 byte long that means 14 hexa characters.
StudentCardDeleteView
¶
Bases: DeleteView
View used to delete a card from a user. This is a fragment view !
StudentCardFormFragment
¶
can_edit(obj, user)
¶
Can the user edit the object.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
obj
|
Any
|
Object to test for permission |
required |
user
|
User
|
core.models.User to test permissions against |
required |
Returns:
| Type | Description |
|---|---|
bool
|
True if user is authorized to edit object else False |
Source code in core/auth/mixins.py
is_logged_in_counter(request, counter=None)
¶
Check if the request is sent from a device logged to a counter.
The request must also be sent within the frame of a counter's activity. Trying to use this function to manage access to non-sas related resources probably won't work.
A request is considered as coming from a logged counter if :
- Its referer comes from the counter app (eg. fetching user pictures from the click UI) or the request path belongs to the counter app (eg. the barman went back to the main by missclick and go back to the counter)
- There are barmen logged in the current session