mirror of
https://github.com/ae-utbm/sith.git
synced 2024-12-22 15:51:19 +00:00
Merge pull request #842 from ae-utbm/3dsv2-again
Add the new 3DSv2 fields
This commit is contained in:
commit
8ec3074488
@ -306,6 +306,12 @@ a:not(.button) {
|
||||
align-items: center;
|
||||
text-align: justify;
|
||||
|
||||
&.alert-yellow {
|
||||
background-color: rgb(255, 255, 240);
|
||||
color: rgb(99, 87, 6);
|
||||
border: rgb(192, 180, 16) 1px solid;
|
||||
}
|
||||
|
||||
&.alert-green {
|
||||
background-color: rgb(245, 255, 245);
|
||||
color: rgb(3, 84, 63);
|
||||
|
@ -46,6 +46,7 @@ class CustomerAdmin(SearchModelAdmin):
|
||||
@admin.register(BillingInfo)
|
||||
class BillingInfoAdmin(admin.ModelAdmin):
|
||||
list_display = ("first_name", "last_name", "address_1", "city", "country")
|
||||
autocomplete_fields = ("customer",)
|
||||
|
||||
|
||||
@admin.register(Counter)
|
||||
|
@ -2,6 +2,7 @@ from ajax_select import make_ajax_field
|
||||
from ajax_select.fields import AutoCompleteSelectField, AutoCompleteSelectMultipleField
|
||||
from django import forms
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from phonenumber_field.widgets import RegionalPhoneNumberWidget
|
||||
|
||||
from core.views.forms import NFCTextInput, SelectDate, SelectDateTime
|
||||
from counter.models import (
|
||||
@ -26,7 +27,11 @@ class BillingInfoForm(forms.ModelForm):
|
||||
"zip_code",
|
||||
"city",
|
||||
"country",
|
||||
"phone_number",
|
||||
]
|
||||
widgets = {
|
||||
"phone_number": RegionalPhoneNumberWidget,
|
||||
}
|
||||
|
||||
|
||||
class StudentCardForm(forms.ModelForm):
|
||||
|
20
counter/migrations/0023_billinginfo_phone_number.py
Normal file
20
counter/migrations/0023_billinginfo_phone_number.py
Normal file
@ -0,0 +1,20 @@
|
||||
# Generated by Django 4.2.16 on 2024-09-26 10:28
|
||||
|
||||
import phonenumber_field.modelfields
|
||||
from django.db import migrations
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
dependencies = [
|
||||
("counter", "0022_alter_product_icon"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="billinginfo",
|
||||
name="phone_number",
|
||||
field=phonenumber_field.modelfields.PhoneNumberField(
|
||||
max_length=128, null=True, region=None, verbose_name="Phone number"
|
||||
),
|
||||
),
|
||||
]
|
@ -34,6 +34,7 @@ from django.utils import timezone
|
||||
from django.utils.functional import cached_property
|
||||
from django.utils.translation import gettext_lazy as _
|
||||
from django_countries.fields import CountryField
|
||||
from phonenumber_field.modelfields import PhoneNumberField
|
||||
|
||||
from accounting.models import CurrencyField
|
||||
from club.models import Club
|
||||
@ -176,6 +177,14 @@ class BillingInfo(models.Model):
|
||||
city = models.CharField(_("City"), max_length=50)
|
||||
country = CountryField(blank_label=_("Country"))
|
||||
|
||||
# This table was created during the A22 semester.
|
||||
# However, later on, CA asked for the phone number to be added to the billing info.
|
||||
# As the table was already created, this new field had to be nullable,
|
||||
# even tough it is required by the bank and shouldn't be null.
|
||||
# If one day there is no null phone number remaining,
|
||||
# please make the field non-nullable.
|
||||
phone_number = PhoneNumberField(_("Phone number"), null=True, blank=False)
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.first_name} {self.last_name}"
|
||||
|
||||
@ -192,6 +201,8 @@ class BillingInfo(models.Model):
|
||||
"ZipCode": self.zip_code,
|
||||
"City": self.city,
|
||||
"CountryCode": self.country.numeric, # ISO-3166-1 numeric code
|
||||
"MobilePhone": self.phone_number.as_national.replace(" ", ""),
|
||||
"CountryCodeMobilePhone": f"+{self.phone_number.country_code}",
|
||||
}
|
||||
}
|
||||
if self.address_2:
|
||||
|
@ -315,6 +315,7 @@ class TestBillingInfo:
|
||||
"zip_code": "34301",
|
||||
"city": "Sète",
|
||||
"country": "FR",
|
||||
"phone_number": "0612345678",
|
||||
}
|
||||
|
||||
def test_edit_infos(self, client: Client, payload: dict):
|
||||
@ -356,7 +357,7 @@ class TestBillingInfo:
|
||||
for key, val in payload.items():
|
||||
assert getattr(infos, key) == val
|
||||
|
||||
def test_invalid_data(self, client: Client, payload):
|
||||
def test_invalid_data(self, client: Client, payload: dict[str, str]):
|
||||
user = subscriber_user.make()
|
||||
client.force_login(user)
|
||||
# address_1, zip_code and country are missing
|
||||
@ -391,6 +392,60 @@ class TestBillingInfo:
|
||||
)
|
||||
assert response.status_code == expected_code
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"phone_number",
|
||||
["+33612345678", "0612345678", "06 12 34 56 78", "06-12-34-56-78"],
|
||||
)
|
||||
def test_phone_number_format(
|
||||
self, client: Client, payload: dict, phone_number: str
|
||||
):
|
||||
"""Test that various formats of phone numbers are accepted."""
|
||||
user = subscriber_user.make()
|
||||
client.force_login(user)
|
||||
payload["phone_number"] = phone_number
|
||||
response = client.put(
|
||||
reverse("api:put_billing_info", args=[user.id]),
|
||||
json.dumps(payload),
|
||||
content_type="application/json",
|
||||
)
|
||||
assert response.status_code == 200
|
||||
infos = BillingInfo.objects.get(customer__user=user)
|
||||
assert infos.phone_number == "0612345678"
|
||||
assert infos.phone_number.country_code == 33
|
||||
|
||||
def test_foreign_phone_number(self, client: Client, payload: dict):
|
||||
"""Test that a foreign phone number is accepted."""
|
||||
user = subscriber_user.make()
|
||||
client.force_login(user)
|
||||
payload["phone_number"] = "+49612345678"
|
||||
response = client.put(
|
||||
reverse("api:put_billing_info", args=[user.id]),
|
||||
json.dumps(payload),
|
||||
content_type="application/json",
|
||||
)
|
||||
assert response.status_code == 200
|
||||
infos = BillingInfo.objects.get(customer__user=user)
|
||||
assert infos.phone_number.as_national == "06123 45678"
|
||||
assert infos.phone_number.country_code == 49
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"phone_number", ["061234567a", "06 12 34 56", "061234567879", "azertyuiop"]
|
||||
)
|
||||
def test_invalid_phone_number(
|
||||
self, client: Client, payload: dict, phone_number: str
|
||||
):
|
||||
"""Test that invalid phone numbers are rejected."""
|
||||
user = subscriber_user.make()
|
||||
client.force_login(user)
|
||||
payload["phone_number"] = phone_number
|
||||
response = client.put(
|
||||
reverse("api:put_billing_info", args=[user.id]),
|
||||
json.dumps(payload),
|
||||
content_type="application/json",
|
||||
)
|
||||
assert response.status_code == 422
|
||||
assert not BillingInfo.objects.filter(customer__user=user).exists()
|
||||
|
||||
|
||||
class TestBarmanConnection(TestCase):
|
||||
@classmethod
|
||||
|
@ -1,6 +1,11 @@
|
||||
from typing import Annotated
|
||||
|
||||
from ninja import ModelSchema, Schema
|
||||
from pydantic import Field, NonNegativeInt, PositiveInt, TypeAdapter
|
||||
|
||||
# from phonenumber_field.phonenumber import PhoneNumber
|
||||
from pydantic_extra_types.phone_numbers import PhoneNumber, PhoneNumberValidator
|
||||
|
||||
from counter.models import BillingInfo
|
||||
|
||||
|
||||
@ -31,3 +36,8 @@ class BillingInfoSchema(ModelSchema):
|
||||
"country",
|
||||
]
|
||||
fields_optional = ["customer"]
|
||||
|
||||
# for reasons described in the model, BillingInfo.phone_number
|
||||
# in nullable, but null values shouldn't be actually allowed,
|
||||
# so we force the field to be required
|
||||
phone_number: Annotated[PhoneNumber, PhoneNumberValidator(default_region="FR")]
|
||||
|
@ -42,7 +42,16 @@ document.addEventListener("alpine:init", () => {
|
||||
this.req_state = res.ok
|
||||
? BillingInfoReqState.SUCCESS
|
||||
: BillingInfoReqState.FAILURE;
|
||||
if (res.ok) {
|
||||
if (res.status === 422) {
|
||||
const errors = (await res.json())["detail"].map((err) => err["loc"]).flat();
|
||||
Array.from(form.querySelectorAll("input"))
|
||||
.filter((elem) => errors.includes(elem.name))
|
||||
.forEach((elem) => {
|
||||
elem.setCustomValidity(gettext("Incorrect value"));
|
||||
elem.reportValidity();
|
||||
elem.oninput = () => elem.setCustomValidity("");
|
||||
});
|
||||
} else if (res.ok) {
|
||||
Alpine.store("billing_inputs").fill();
|
||||
}
|
||||
},
|
||||
|
@ -98,13 +98,20 @@
|
||||
</form>
|
||||
</div>
|
||||
<br>
|
||||
{% if must_fill_billing_infos %}
|
||||
<p>
|
||||
<i>
|
||||
{% trans %}You must fill your billing infos if you want to pay with your credit
|
||||
card{% endtrans %}
|
||||
</i>
|
||||
</p>
|
||||
{% if billing_infos_state == BillingInfoState.EMPTY %}
|
||||
<div class="alert alert-yellow">
|
||||
{% trans %}You must fill your billing infos if you want to pay with your credit
|
||||
card{% endtrans %}
|
||||
</div>
|
||||
{% elif billing_infos_state == BillingInfoState.MISSING_PHONE_NUMBER %}
|
||||
<div class="alert alert-yellow">
|
||||
{% trans %}
|
||||
The Crédit Agricole changed its policy related to the billing
|
||||
information that must be provided in order to pay with a credit card.
|
||||
If you want to pay with your credit card, you must add a phone number
|
||||
to the data you already provided.
|
||||
{% endtrans %}
|
||||
</div>
|
||||
{% endif %}
|
||||
<form method="post" action="{{ settings.SITH_EBOUTIC_ET_URL }}" name="bank-pay-form">
|
||||
<template x-data x-for="[key, value] in Object.entries($store.billing_inputs.data)">
|
||||
@ -113,7 +120,7 @@
|
||||
<input
|
||||
type="submit"
|
||||
id="bank-submit-button"
|
||||
{% if must_fill_billing_infos %}disabled="disabled"{% endif %}
|
||||
{% if billing_infos_state != BillingInfoState.VALID %}disabled="disabled"{% endif %}
|
||||
value="{% trans %}Pay with credit card{% endtrans %}"
|
||||
/>
|
||||
</form>
|
||||
|
@ -16,6 +16,7 @@
|
||||
import base64
|
||||
import json
|
||||
from datetime import datetime
|
||||
from enum import Enum
|
||||
|
||||
import sentry_sdk
|
||||
from cryptography.exceptions import InvalidSignature
|
||||
@ -82,6 +83,12 @@ def payment_result(request, result: str) -> HttpResponse:
|
||||
return render(request, "eboutic/eboutic_payment_result.jinja", context)
|
||||
|
||||
|
||||
class BillingInfoState(Enum):
|
||||
VALID = 1
|
||||
EMPTY = 2
|
||||
MISSING_PHONE_NUMBER = 3
|
||||
|
||||
|
||||
class EbouticCommand(LoginRequiredMixin, TemplateView):
|
||||
template_name = "eboutic/eboutic_makecommand.jinja"
|
||||
basket: Basket
|
||||
@ -130,9 +137,16 @@ class EbouticCommand(LoginRequiredMixin, TemplateView):
|
||||
default_billing_info = customer.billing_infos
|
||||
else:
|
||||
kwargs["customer_amount"] = None
|
||||
kwargs["must_fill_billing_infos"] = default_billing_info is None
|
||||
if not kwargs["must_fill_billing_infos"]:
|
||||
# the user has already filled its billing_infos, thus we can
|
||||
# make the enum available in the template
|
||||
kwargs["BillingInfoState"] = BillingInfoState
|
||||
if default_billing_info is None:
|
||||
kwargs["billing_infos_state"] = BillingInfoState.EMPTY
|
||||
elif default_billing_info.phone_number is None:
|
||||
kwargs["billing_infos_state"] = BillingInfoState.MISSING_PHONE_NUMBER
|
||||
else:
|
||||
kwargs["billing_infos_state"] = BillingInfoState.VALID
|
||||
if kwargs["billing_infos_state"] == BillingInfoState.VALID:
|
||||
# the user has already filled all of its billing_infos, thus we can
|
||||
# get it without expecting an error
|
||||
kwargs["billing_infos"] = dict(self.basket.get_e_transaction_data())
|
||||
kwargs["basket"] = self.basket
|
||||
|
@ -6,7 +6,7 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-09-17 12:21+0200\n"
|
||||
"POT-Creation-Date: 2024-09-26 17:51+0200\n"
|
||||
"PO-Revision-Date: 2016-07-18\n"
|
||||
"Last-Translator: Skia <skia@libskia.so>\n"
|
||||
"Language-Team: AE info <ae.info@utbm.fr>\n"
|
||||
@ -18,8 +18,8 @@ msgstr ""
|
||||
|
||||
#: accounting/models.py:62 accounting/models.py:103 accounting/models.py:136
|
||||
#: accounting/models.py:203 club/models.py:54 com/models.py:274
|
||||
#: com/models.py:293 counter/models.py:209 counter/models.py:242
|
||||
#: counter/models.py:377 forum/models.py:59 launderette/models.py:29
|
||||
#: com/models.py:293 counter/models.py:213 counter/models.py:246
|
||||
#: counter/models.py:381 forum/models.py:59 launderette/models.py:29
|
||||
#: launderette/models.py:84 launderette/models.py:122 stock/models.py:36
|
||||
#: stock/models.py:57 stock/models.py:97 stock/models.py:125
|
||||
msgid "name"
|
||||
@ -66,8 +66,8 @@ msgid "account number"
|
||||
msgstr "numéro de compte"
|
||||
|
||||
#: accounting/models.py:109 accounting/models.py:140 club/models.py:344
|
||||
#: com/models.py:74 com/models.py:259 com/models.py:299 counter/models.py:265
|
||||
#: counter/models.py:379 trombi/models.py:210
|
||||
#: com/models.py:74 com/models.py:259 com/models.py:299 counter/models.py:269
|
||||
#: counter/models.py:383 trombi/models.py:210
|
||||
msgid "club"
|
||||
msgstr "club"
|
||||
|
||||
@ -88,12 +88,12 @@ msgstr "Compte club"
|
||||
msgid "%(club_account)s on %(bank_account)s"
|
||||
msgstr "%(club_account)s sur %(bank_account)s"
|
||||
|
||||
#: accounting/models.py:201 club/models.py:350 counter/models.py:860
|
||||
#: accounting/models.py:201 club/models.py:350 counter/models.py:864
|
||||
#: election/models.py:16 launderette/models.py:179
|
||||
msgid "start date"
|
||||
msgstr "date de début"
|
||||
|
||||
#: accounting/models.py:202 club/models.py:351 counter/models.py:861
|
||||
#: accounting/models.py:202 club/models.py:351 counter/models.py:865
|
||||
#: election/models.py:17
|
||||
msgid "end date"
|
||||
msgstr "date de fin"
|
||||
@ -106,8 +106,8 @@ msgstr "est fermé"
|
||||
msgid "club account"
|
||||
msgstr "compte club"
|
||||
|
||||
#: accounting/models.py:212 accounting/models.py:272 counter/models.py:56
|
||||
#: counter/models.py:583
|
||||
#: accounting/models.py:212 accounting/models.py:272 counter/models.py:57
|
||||
#: counter/models.py:587
|
||||
msgid "amount"
|
||||
msgstr "montant"
|
||||
|
||||
@ -127,20 +127,20 @@ msgstr "numéro"
|
||||
msgid "journal"
|
||||
msgstr "classeur"
|
||||
|
||||
#: accounting/models.py:273 core/models.py:940 core/models.py:1442
|
||||
#: core/models.py:1487 core/models.py:1516 core/models.py:1540
|
||||
#: counter/models.py:593 counter/models.py:686 counter/models.py:896
|
||||
#: accounting/models.py:273 core/models.py:940 core/models.py:1460
|
||||
#: core/models.py:1505 core/models.py:1534 core/models.py:1558
|
||||
#: counter/models.py:597 counter/models.py:690 counter/models.py:900
|
||||
#: eboutic/models.py:57 eboutic/models.py:173 forum/models.py:311
|
||||
#: forum/models.py:412 stock/models.py:96
|
||||
msgid "date"
|
||||
msgstr "date"
|
||||
|
||||
#: accounting/models.py:274 counter/models.py:211 counter/models.py:897
|
||||
#: accounting/models.py:274 counter/models.py:215 counter/models.py:901
|
||||
#: pedagogy/models.py:207 stock/models.py:99
|
||||
msgid "comment"
|
||||
msgstr "commentaire"
|
||||
|
||||
#: accounting/models.py:276 counter/models.py:595 counter/models.py:688
|
||||
#: accounting/models.py:276 counter/models.py:599 counter/models.py:692
|
||||
#: subscription/models.py:56
|
||||
msgid "payment method"
|
||||
msgstr "méthode de paiement"
|
||||
@ -166,8 +166,8 @@ msgid "accounting type"
|
||||
msgstr "type comptable"
|
||||
|
||||
#: accounting/models.py:311 accounting/models.py:450 accounting/models.py:483
|
||||
#: accounting/models.py:515 core/models.py:1515 core/models.py:1541
|
||||
#: counter/models.py:652
|
||||
#: accounting/models.py:515 core/models.py:1533 core/models.py:1559
|
||||
#: counter/models.py:656
|
||||
msgid "label"
|
||||
msgstr "étiquette"
|
||||
|
||||
@ -266,7 +266,7 @@ msgstr ""
|
||||
"Vous devez fournir soit un type comptable simplifié ou un type comptable "
|
||||
"standard"
|
||||
|
||||
#: accounting/models.py:442 counter/models.py:252 pedagogy/models.py:41
|
||||
#: accounting/models.py:442 counter/models.py:256 pedagogy/models.py:41
|
||||
msgid "code"
|
||||
msgstr "code"
|
||||
|
||||
@ -370,7 +370,7 @@ msgstr "Compte en banque : "
|
||||
#: core/templates/core/user_account_detail.jinja:66
|
||||
#: core/templates/core/user_clubs.jinja:34
|
||||
#: core/templates/core/user_clubs.jinja:63
|
||||
#: core/templates/core/user_edit.jinja:57
|
||||
#: core/templates/core/user_edit.jinja:62
|
||||
#: core/templates/core/user_preferences.jinja:48
|
||||
#: counter/templates/counter/last_ops.jinja:35
|
||||
#: counter/templates/counter/last_ops.jinja:65
|
||||
@ -968,11 +968,11 @@ msgstr "Une action est requise"
|
||||
msgid "You must specify at least an user or an email address"
|
||||
msgstr "vous devez spécifier au moins un utilisateur ou une adresse email"
|
||||
|
||||
#: club/forms.py:153 counter/forms.py:186
|
||||
#: club/forms.py:153 counter/forms.py:187
|
||||
msgid "Begin date"
|
||||
msgstr "Date de début"
|
||||
|
||||
#: club/forms.py:156 com/views.py:82 com/views.py:201 counter/forms.py:189
|
||||
#: club/forms.py:156 com/views.py:82 com/views.py:201 counter/forms.py:190
|
||||
#: election/views.py:167 subscription/views.py:38
|
||||
msgid "End date"
|
||||
msgstr "Date de fin"
|
||||
@ -1058,7 +1058,7 @@ msgstr "Vous ne pouvez pas faire de boucles dans les clubs"
|
||||
msgid "A club with that unix_name already exists"
|
||||
msgstr "Un club avec ce nom UNIX existe déjà."
|
||||
|
||||
#: club/models.py:336 counter/models.py:851 counter/models.py:887
|
||||
#: club/models.py:336 counter/models.py:855 counter/models.py:891
|
||||
#: eboutic/models.py:53 eboutic/models.py:169 election/models.py:183
|
||||
#: launderette/models.py:136 launderette/models.py:198 sas/models.py:270
|
||||
#: trombi/models.py:206
|
||||
@ -1070,8 +1070,8 @@ msgstr "nom d'utilisateur"
|
||||
msgid "role"
|
||||
msgstr "rôle"
|
||||
|
||||
#: club/models.py:358 core/models.py:89 counter/models.py:210
|
||||
#: counter/models.py:243 election/models.py:13 election/models.py:115
|
||||
#: club/models.py:358 core/models.py:89 counter/models.py:214
|
||||
#: counter/models.py:247 election/models.py:13 election/models.py:115
|
||||
#: election/models.py:188 forum/models.py:60 forum/models.py:244
|
||||
msgid "description"
|
||||
msgstr "description"
|
||||
@ -1440,7 +1440,7 @@ msgstr "résumé"
|
||||
msgid "content"
|
||||
msgstr "contenu"
|
||||
|
||||
#: com/models.py:71 core/models.py:1485 launderette/models.py:92
|
||||
#: com/models.py:71 core/models.py:1503 launderette/models.py:92
|
||||
#: launderette/models.py:130 launderette/models.py:181 stock/models.py:74
|
||||
#: stock/models.py:129
|
||||
msgid "type"
|
||||
@ -2217,7 +2217,7 @@ msgstr "Un utilisateur de ce nom d'utilisateur existe déjà"
|
||||
#: core/templates/core/user_detail.jinja:110
|
||||
#: core/templates/core/user_detail.jinja:112
|
||||
#: core/templates/core/user_detail.jinja:113
|
||||
#: core/templates/core/user_edit.jinja:16
|
||||
#: core/templates/core/user_edit.jinja:21
|
||||
#: election/templates/election/election_detail.jinja:132
|
||||
#: election/templates/election/election_detail.jinja:134
|
||||
#: forum/templates/forum/macros.jinja:104
|
||||
@ -2250,7 +2250,7 @@ msgstr "avoir une notification pour chaque rechargement"
|
||||
msgid "file name"
|
||||
msgstr "nom du fichier"
|
||||
|
||||
#: core/models.py:899 core/models.py:1234
|
||||
#: core/models.py:899 core/models.py:1252
|
||||
msgid "parent"
|
||||
msgstr "parent"
|
||||
|
||||
@ -2266,11 +2266,11 @@ msgstr "miniature"
|
||||
msgid "owner"
|
||||
msgstr "propriétaire"
|
||||
|
||||
#: core/models.py:932 core/models.py:1251 core/views/files.py:223
|
||||
#: core/models.py:932 core/models.py:1269 core/views/files.py:223
|
||||
msgid "edit group"
|
||||
msgstr "groupe d'édition"
|
||||
|
||||
#: core/models.py:935 core/models.py:1254 core/views/files.py:226
|
||||
#: core/models.py:935 core/models.py:1272 core/views/files.py:226
|
||||
msgid "view group"
|
||||
msgstr "groupe de vue"
|
||||
|
||||
@ -2316,11 +2316,11 @@ msgstr "Un fichier de ce nom existe déjà"
|
||||
msgid "You must provide a file"
|
||||
msgstr "Vous devez fournir un fichier"
|
||||
|
||||
#: core/models.py:1217
|
||||
#: core/models.py:1235
|
||||
msgid "page unix name"
|
||||
msgstr "nom unix de la page"
|
||||
|
||||
#: core/models.py:1223
|
||||
#: core/models.py:1241
|
||||
msgid ""
|
||||
"Enter a valid page name. This value may contain only unaccented letters, "
|
||||
"numbers and ./+/-/_ characters."
|
||||
@ -2328,55 +2328,55 @@ msgstr ""
|
||||
"Entrez un nom de page correct. Uniquement des lettres non accentuées, "
|
||||
"numéros, et ./+/-/_"
|
||||
|
||||
#: core/models.py:1241
|
||||
#: core/models.py:1259
|
||||
msgid "page name"
|
||||
msgstr "nom de la page"
|
||||
|
||||
#: core/models.py:1246
|
||||
#: core/models.py:1264
|
||||
msgid "owner group"
|
||||
msgstr "groupe propriétaire"
|
||||
|
||||
#: core/models.py:1259
|
||||
#: core/models.py:1277
|
||||
msgid "lock user"
|
||||
msgstr "utilisateur bloquant"
|
||||
|
||||
#: core/models.py:1266
|
||||
#: core/models.py:1284
|
||||
msgid "lock_timeout"
|
||||
msgstr "décompte du déblocage"
|
||||
|
||||
#: core/models.py:1316
|
||||
#: core/models.py:1334
|
||||
msgid "Duplicate page"
|
||||
msgstr "Une page de ce nom existe déjà"
|
||||
|
||||
#: core/models.py:1319
|
||||
#: core/models.py:1337
|
||||
msgid "Loop in page tree"
|
||||
msgstr "Boucle dans l'arborescence des pages"
|
||||
|
||||
#: core/models.py:1439
|
||||
#: core/models.py:1457
|
||||
msgid "revision"
|
||||
msgstr "révision"
|
||||
|
||||
#: core/models.py:1440
|
||||
#: core/models.py:1458
|
||||
msgid "page title"
|
||||
msgstr "titre de la page"
|
||||
|
||||
#: core/models.py:1441
|
||||
#: core/models.py:1459
|
||||
msgid "page content"
|
||||
msgstr "contenu de la page"
|
||||
|
||||
#: core/models.py:1482
|
||||
#: core/models.py:1500
|
||||
msgid "url"
|
||||
msgstr "url"
|
||||
|
||||
#: core/models.py:1483
|
||||
#: core/models.py:1501
|
||||
msgid "param"
|
||||
msgstr "param"
|
||||
|
||||
#: core/models.py:1488
|
||||
#: core/models.py:1506
|
||||
msgid "viewed"
|
||||
msgstr "vue"
|
||||
|
||||
#: core/models.py:1546
|
||||
#: core/models.py:1564
|
||||
msgid "operation type"
|
||||
msgstr "type d'opération"
|
||||
|
||||
@ -2474,7 +2474,7 @@ msgstr "Forum"
|
||||
msgid "Gallery"
|
||||
msgstr "Photos"
|
||||
|
||||
#: core/templates/core/base.jinja:225 counter/models.py:387
|
||||
#: core/templates/core/base.jinja:225 counter/models.py:391
|
||||
#: counter/templates/counter/counter_list.jinja:11
|
||||
#: eboutic/templates/eboutic/eboutic_main.jinja:4
|
||||
#: eboutic/templates/eboutic/eboutic_main.jinja:22
|
||||
@ -2693,7 +2693,7 @@ msgid "Edit group"
|
||||
msgstr "Éditer le groupe"
|
||||
|
||||
#: core/templates/core/group_edit.jinja:9
|
||||
#: core/templates/core/user_edit.jinja:268
|
||||
#: core/templates/core/user_edit.jinja:170
|
||||
#: core/templates/core/user_group.jinja:13
|
||||
#: pedagogy/templates/pedagogy/uv_edit.jinja:36
|
||||
msgid "Update"
|
||||
@ -3184,39 +3184,35 @@ msgstr "Aucun cadeau donné pour l'instant"
|
||||
msgid "Edit user"
|
||||
msgstr "Éditer l'utilisateur"
|
||||
|
||||
#: core/templates/core/user_edit.jinja:36
|
||||
#: core/templates/core/user_edit.jinja:41
|
||||
msgid "Enable camera"
|
||||
msgstr "Activer la caméra"
|
||||
|
||||
#: core/templates/core/user_edit.jinja:44
|
||||
#: core/templates/core/user_edit.jinja:49
|
||||
msgid "Take a picture"
|
||||
msgstr "Prendre une photo"
|
||||
|
||||
#: core/templates/core/user_edit.jinja:64
|
||||
#: core/templates/core/user_edit.jinja:69
|
||||
msgid "To edit your profile picture, ask a member of the AE"
|
||||
msgstr "Pour changer votre photo de profil, demandez à un membre de l'AE"
|
||||
|
||||
#: core/templates/core/user_edit.jinja:173
|
||||
msgid "captured"
|
||||
msgstr "capturé"
|
||||
|
||||
#: core/templates/core/user_edit.jinja:196
|
||||
#: core/templates/core/user_edit.jinja:98
|
||||
msgid "Edit user profile"
|
||||
msgstr "Éditer le profil de l'utilisateur"
|
||||
|
||||
#: core/templates/core/user_edit.jinja:258
|
||||
#: core/templates/core/user_edit.jinja:160
|
||||
msgid "Change my password"
|
||||
msgstr "Changer mon mot de passe"
|
||||
|
||||
#: core/templates/core/user_edit.jinja:263
|
||||
#: core/templates/core/user_edit.jinja:165
|
||||
msgid "Change user password"
|
||||
msgstr "Changer le mot de passe"
|
||||
|
||||
#: core/templates/core/user_edit.jinja:273
|
||||
#: core/templates/core/user_edit.jinja:175
|
||||
msgid "Username:"
|
||||
msgstr "Nom d'utilisateur : "
|
||||
|
||||
#: core/templates/core/user_edit.jinja:276
|
||||
#: core/templates/core/user_edit.jinja:178
|
||||
msgid "Account number:"
|
||||
msgstr "Numéro de compte : "
|
||||
|
||||
@ -3350,7 +3346,7 @@ msgstr "Achats"
|
||||
msgid "Product top 10"
|
||||
msgstr "Top 10 produits"
|
||||
|
||||
#: core/templates/core/user_stats.jinja:43 counter/forms.py:200
|
||||
#: core/templates/core/user_stats.jinja:43 counter/forms.py:201
|
||||
msgid "Product"
|
||||
msgstr "Produit"
|
||||
|
||||
@ -3395,7 +3391,7 @@ msgstr "Cotisations"
|
||||
msgid "Subscription stats"
|
||||
msgstr "Statistiques de cotisation"
|
||||
|
||||
#: core/templates/core/user_tools.jinja:48 counter/forms.py:159
|
||||
#: core/templates/core/user_tools.jinja:48 counter/forms.py:160
|
||||
#: counter/views.py:728
|
||||
msgid "Counters"
|
||||
msgstr "Comptoirs"
|
||||
@ -3654,7 +3650,7 @@ msgstr "Parrain / Marraine"
|
||||
msgid "Godchild"
|
||||
msgstr "Fillot / Fillote"
|
||||
|
||||
#: core/views/forms.py:338 counter/forms.py:67 trombi/views.py:149
|
||||
#: core/views/forms.py:338 counter/forms.py:68 trombi/views.py:149
|
||||
msgid "Select user"
|
||||
msgstr "Choisir un utilisateur"
|
||||
|
||||
@ -3713,24 +3709,24 @@ msgstr "Photos"
|
||||
msgid "Galaxy"
|
||||
msgstr "Galaxie"
|
||||
|
||||
#: counter/apps.py:30 counter/models.py:403 counter/models.py:857
|
||||
#: counter/models.py:893 launderette/models.py:32 stock/models.py:39
|
||||
#: counter/apps.py:30 counter/models.py:407 counter/models.py:861
|
||||
#: counter/models.py:897 launderette/models.py:32 stock/models.py:39
|
||||
msgid "counter"
|
||||
msgstr "comptoir"
|
||||
|
||||
#: counter/forms.py:48
|
||||
#: counter/forms.py:49
|
||||
msgid "This UID is invalid"
|
||||
msgstr "Cet UID est invalide"
|
||||
|
||||
#: counter/forms.py:89
|
||||
#: counter/forms.py:90
|
||||
msgid "User not found"
|
||||
msgstr "Utilisateur non trouvé"
|
||||
|
||||
#: counter/forms.py:145
|
||||
#: counter/forms.py:146
|
||||
msgid "Parent product"
|
||||
msgstr "Produit parent"
|
||||
|
||||
#: counter/forms.py:151
|
||||
#: counter/forms.py:152
|
||||
msgid "Buying groups"
|
||||
msgstr "Groupes d'achat"
|
||||
|
||||
@ -3738,165 +3734,169 @@ msgstr "Groupes d'achat"
|
||||
msgid "Ecocup regularization"
|
||||
msgstr "Régularization des ecocups"
|
||||
|
||||
#: counter/models.py:55
|
||||
#: counter/models.py:56
|
||||
msgid "account id"
|
||||
msgstr "numéro de compte"
|
||||
|
||||
#: counter/models.py:57
|
||||
#: counter/models.py:58
|
||||
msgid "recorded product"
|
||||
msgstr "produits consignés"
|
||||
|
||||
#: counter/models.py:60
|
||||
#: counter/models.py:61
|
||||
msgid "customer"
|
||||
msgstr "client"
|
||||
|
||||
#: counter/models.py:61
|
||||
#: counter/models.py:62
|
||||
msgid "customers"
|
||||
msgstr "clients"
|
||||
|
||||
#: counter/models.py:73 counter/views.py:309
|
||||
#: counter/models.py:74 counter/views.py:309
|
||||
msgid "Not enough money"
|
||||
msgstr "Solde insuffisant"
|
||||
|
||||
#: counter/models.py:171
|
||||
#: counter/models.py:172
|
||||
msgid "First name"
|
||||
msgstr "Prénom"
|
||||
|
||||
#: counter/models.py:172
|
||||
#: counter/models.py:173
|
||||
msgid "Last name"
|
||||
msgstr "Nom de famille"
|
||||
|
||||
#: counter/models.py:173
|
||||
#: counter/models.py:174
|
||||
msgid "Address 1"
|
||||
msgstr "Adresse 1"
|
||||
|
||||
#: counter/models.py:174
|
||||
#: counter/models.py:175
|
||||
msgid "Address 2"
|
||||
msgstr "Adresse 2"
|
||||
|
||||
#: counter/models.py:175
|
||||
#: counter/models.py:176
|
||||
msgid "Zip code"
|
||||
msgstr "Code postal"
|
||||
|
||||
#: counter/models.py:176
|
||||
#: counter/models.py:177
|
||||
msgid "City"
|
||||
msgstr "Ville"
|
||||
|
||||
#: counter/models.py:177
|
||||
#: counter/models.py:178
|
||||
msgid "Country"
|
||||
msgstr "Pays"
|
||||
|
||||
#: counter/models.py:221 counter/models.py:247
|
||||
#: counter/models.py:179
|
||||
msgid "Phone number"
|
||||
msgstr "Numéro de téléphone"
|
||||
|
||||
#: counter/models.py:225 counter/models.py:251
|
||||
msgid "product type"
|
||||
msgstr "type du produit"
|
||||
|
||||
#: counter/models.py:253
|
||||
#: counter/models.py:257
|
||||
msgid "purchase price"
|
||||
msgstr "prix d'achat"
|
||||
|
||||
#: counter/models.py:254
|
||||
#: counter/models.py:258
|
||||
msgid "selling price"
|
||||
msgstr "prix de vente"
|
||||
|
||||
#: counter/models.py:255
|
||||
#: counter/models.py:259
|
||||
msgid "special selling price"
|
||||
msgstr "prix de vente spécial"
|
||||
|
||||
#: counter/models.py:262
|
||||
#: counter/models.py:266
|
||||
msgid "icon"
|
||||
msgstr "icône"
|
||||
|
||||
#: counter/models.py:267
|
||||
#: counter/models.py:271
|
||||
msgid "limit age"
|
||||
msgstr "âge limite"
|
||||
|
||||
#: counter/models.py:268
|
||||
#: counter/models.py:272
|
||||
msgid "tray price"
|
||||
msgstr "prix plateau"
|
||||
|
||||
#: counter/models.py:272
|
||||
#: counter/models.py:276
|
||||
msgid "parent product"
|
||||
msgstr "produit parent"
|
||||
|
||||
#: counter/models.py:278
|
||||
#: counter/models.py:282
|
||||
msgid "buying groups"
|
||||
msgstr "groupe d'achat"
|
||||
|
||||
#: counter/models.py:280 election/models.py:50
|
||||
#: counter/models.py:284 election/models.py:50
|
||||
msgid "archived"
|
||||
msgstr "archivé"
|
||||
|
||||
#: counter/models.py:283 counter/models.py:993
|
||||
#: counter/models.py:287 counter/models.py:997
|
||||
msgid "product"
|
||||
msgstr "produit"
|
||||
|
||||
#: counter/models.py:382
|
||||
#: counter/models.py:386
|
||||
msgid "products"
|
||||
msgstr "produits"
|
||||
|
||||
#: counter/models.py:385
|
||||
#: counter/models.py:389
|
||||
msgid "counter type"
|
||||
msgstr "type de comptoir"
|
||||
|
||||
#: counter/models.py:387
|
||||
#: counter/models.py:391
|
||||
msgid "Bar"
|
||||
msgstr "Bar"
|
||||
|
||||
#: counter/models.py:387
|
||||
#: counter/models.py:391
|
||||
msgid "Office"
|
||||
msgstr "Bureau"
|
||||
|
||||
#: counter/models.py:390
|
||||
#: counter/models.py:394
|
||||
msgid "sellers"
|
||||
msgstr "vendeurs"
|
||||
|
||||
#: counter/models.py:398 launderette/models.py:192
|
||||
#: counter/models.py:402 launderette/models.py:192
|
||||
msgid "token"
|
||||
msgstr "jeton"
|
||||
|
||||
#: counter/models.py:601
|
||||
#: counter/models.py:605
|
||||
msgid "bank"
|
||||
msgstr "banque"
|
||||
|
||||
#: counter/models.py:603 counter/models.py:693
|
||||
#: counter/models.py:607 counter/models.py:697
|
||||
msgid "is validated"
|
||||
msgstr "est validé"
|
||||
|
||||
#: counter/models.py:606
|
||||
#: counter/models.py:610
|
||||
msgid "refilling"
|
||||
msgstr "rechargement"
|
||||
|
||||
#: counter/models.py:670 eboutic/models.py:227
|
||||
#: counter/models.py:674 eboutic/models.py:227
|
||||
msgid "unit price"
|
||||
msgstr "prix unitaire"
|
||||
|
||||
#: counter/models.py:671 counter/models.py:973 eboutic/models.py:228
|
||||
#: counter/models.py:675 counter/models.py:977 eboutic/models.py:228
|
||||
msgid "quantity"
|
||||
msgstr "quantité"
|
||||
|
||||
#: counter/models.py:690
|
||||
#: counter/models.py:694
|
||||
msgid "Sith account"
|
||||
msgstr "Compte utilisateur"
|
||||
|
||||
#: counter/models.py:690 sith/settings.py:405 sith/settings.py:410
|
||||
#: counter/models.py:694 sith/settings.py:405 sith/settings.py:410
|
||||
#: sith/settings.py:430
|
||||
msgid "Credit card"
|
||||
msgstr "Carte bancaire"
|
||||
|
||||
#: counter/models.py:696
|
||||
#: counter/models.py:700
|
||||
msgid "selling"
|
||||
msgstr "vente"
|
||||
|
||||
#: counter/models.py:800
|
||||
#: counter/models.py:804
|
||||
msgid "Unknown event"
|
||||
msgstr "Événement inconnu"
|
||||
|
||||
#: counter/models.py:801
|
||||
#: counter/models.py:805
|
||||
#, python-format
|
||||
msgid "Eticket bought for the event %(event)s"
|
||||
msgstr "Eticket acheté pour l'événement %(event)s"
|
||||
|
||||
#: counter/models.py:803 counter/models.py:826
|
||||
#: counter/models.py:807 counter/models.py:830
|
||||
#, python-format
|
||||
msgid ""
|
||||
"You bought an eticket for the event %(event)s.\n"
|
||||
@ -3908,63 +3908,63 @@ msgstr ""
|
||||
"Vous pouvez également retrouver tous vos e-tickets sur votre page de compte "
|
||||
"%(url)s."
|
||||
|
||||
#: counter/models.py:862
|
||||
#: counter/models.py:866
|
||||
msgid "last activity date"
|
||||
msgstr "dernière activité"
|
||||
|
||||
#: counter/models.py:865
|
||||
#: counter/models.py:869
|
||||
msgid "permanency"
|
||||
msgstr "permanence"
|
||||
|
||||
#: counter/models.py:898
|
||||
#: counter/models.py:902
|
||||
msgid "emptied"
|
||||
msgstr "coffre vidée"
|
||||
|
||||
#: counter/models.py:901
|
||||
#: counter/models.py:905
|
||||
msgid "cash register summary"
|
||||
msgstr "relevé de caisse"
|
||||
|
||||
#: counter/models.py:969
|
||||
#: counter/models.py:973
|
||||
msgid "cash summary"
|
||||
msgstr "relevé"
|
||||
|
||||
#: counter/models.py:972
|
||||
#: counter/models.py:976
|
||||
msgid "value"
|
||||
msgstr "valeur"
|
||||
|
||||
#: counter/models.py:975
|
||||
#: counter/models.py:979
|
||||
msgid "check"
|
||||
msgstr "chèque"
|
||||
|
||||
#: counter/models.py:977
|
||||
#: counter/models.py:981
|
||||
msgid "True if this is a bank check, else False"
|
||||
msgstr "Vrai si c'est un chèque, sinon Faux."
|
||||
|
||||
#: counter/models.py:981
|
||||
#: counter/models.py:985
|
||||
msgid "cash register summary item"
|
||||
msgstr "élément de relevé de caisse"
|
||||
|
||||
#: counter/models.py:997
|
||||
#: counter/models.py:1001
|
||||
msgid "banner"
|
||||
msgstr "bannière"
|
||||
|
||||
#: counter/models.py:999
|
||||
#: counter/models.py:1003
|
||||
msgid "event date"
|
||||
msgstr "date de l'événement"
|
||||
|
||||
#: counter/models.py:1001
|
||||
#: counter/models.py:1005
|
||||
msgid "event title"
|
||||
msgstr "titre de l'événement"
|
||||
|
||||
#: counter/models.py:1003
|
||||
#: counter/models.py:1007
|
||||
msgid "secret"
|
||||
msgstr "secret"
|
||||
|
||||
#: counter/models.py:1042
|
||||
#: counter/models.py:1046
|
||||
msgid "uid"
|
||||
msgstr "uid"
|
||||
|
||||
#: counter/models.py:1047
|
||||
#: counter/models.py:1051
|
||||
msgid "student cards"
|
||||
msgstr "cartes étudiante"
|
||||
|
||||
@ -4439,40 +4439,58 @@ msgstr "Solde restant : "
|
||||
msgid "Billing information"
|
||||
msgstr "Informations de facturation"
|
||||
|
||||
#: eboutic/templates/eboutic/eboutic_makecommand.jinja:104
|
||||
#: eboutic/templates/eboutic/eboutic_makecommand.jinja:103
|
||||
msgid ""
|
||||
"You must fill your billing infos if you want to pay with your credit\n"
|
||||
" card"
|
||||
" card"
|
||||
msgstr ""
|
||||
"Vous devez renseigner vos coordonnées de facturation si vous voulez payer "
|
||||
"par carte bancaire"
|
||||
|
||||
#: eboutic/templates/eboutic/eboutic_makecommand.jinja:117
|
||||
#: eboutic/templates/eboutic/eboutic_makecommand.jinja:108
|
||||
msgid ""
|
||||
"\n"
|
||||
" The Crédit Agricole changed its policy related to the "
|
||||
"billing\n"
|
||||
" information that must be provided in order to pay with a "
|
||||
"credit card.\n"
|
||||
" If you want to pay with your credit card, you must add a "
|
||||
"phone number\n"
|
||||
" to the data you already provided.\n"
|
||||
" "
|
||||
msgstr ""
|
||||
"\n"
|
||||
"Le Crédit Agricole a changé sa politique relative aux informations à "
|
||||
"fournir pour effectuer un paiement par carte bancaire. De ce fait, si vous "
|
||||
"souhaitez payer par carte, vous devez rajouter un numéro de téléphone aux "
|
||||
"données que vous aviez déjà fourni."
|
||||
|
||||
#: eboutic/templates/eboutic/eboutic_makecommand.jinja:124
|
||||
msgid "Pay with credit card"
|
||||
msgstr "Payer avec une carte bancaire"
|
||||
|
||||
#: eboutic/templates/eboutic/eboutic_makecommand.jinja:122
|
||||
#: eboutic/templates/eboutic/eboutic_makecommand.jinja:129
|
||||
msgid ""
|
||||
"AE account payment disabled because your basket contains refilling items."
|
||||
msgstr ""
|
||||
"Paiement par compte AE désactivé parce que votre panier contient des bons de "
|
||||
"rechargement."
|
||||
|
||||
#: eboutic/templates/eboutic/eboutic_makecommand.jinja:124
|
||||
#: eboutic/templates/eboutic/eboutic_makecommand.jinja:131
|
||||
msgid ""
|
||||
"AE account payment disabled because you do not have enough money remaining."
|
||||
msgstr ""
|
||||
"Paiement par compte AE désactivé parce que votre solde est insuffisant."
|
||||
|
||||
#: eboutic/templates/eboutic/eboutic_makecommand.jinja:129
|
||||
#: eboutic/templates/eboutic/eboutic_makecommand.jinja:136
|
||||
msgid "Pay with Sith account"
|
||||
msgstr "Payer avec un compte AE"
|
||||
|
||||
#: eboutic/templates/eboutic/eboutic_makecommand.jinja:140
|
||||
#: eboutic/templates/eboutic/eboutic_makecommand.jinja:147
|
||||
msgid "Billing info registration success"
|
||||
msgstr "Informations de facturation enregistrées"
|
||||
|
||||
#: eboutic/templates/eboutic/eboutic_makecommand.jinja:141
|
||||
#: eboutic/templates/eboutic/eboutic_makecommand.jinja:148
|
||||
msgid "Billing info registration failure"
|
||||
msgstr "Echec de l'enregistrement des informations de facturation."
|
||||
|
||||
@ -6325,3 +6343,6 @@ msgstr "Vous ne pouvez plus écrire de commentaires, la date est passée."
|
||||
#, python-format
|
||||
msgid "Maximum characters: %(max_length)s"
|
||||
msgstr "Nombre de caractères max: %(max_length)s"
|
||||
|
||||
#~ msgid "captured"
|
||||
#~ msgstr "capturé"
|
||||
|
@ -7,7 +7,7 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2024-09-03 15:22+0200\n"
|
||||
"POT-Creation-Date: 2024-09-27 22:32+0200\n"
|
||||
"PO-Revision-Date: 2024-09-17 11:54+0200\n"
|
||||
"Last-Translator: Sli <antoine@bartuccio.fr>\n"
|
||||
"Language-Team: AE info <ae.info@utbm.fr>\n"
|
||||
@ -16,9 +16,24 @@ msgstr ""
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
#: core/static/user/js/family_graph.js:230
|
||||
|
||||
#: core/static/user/js/family_graph.js:233
|
||||
msgid "family_tree.%(extension)s"
|
||||
msgstr "arbre_genealogique.%(extension)s"
|
||||
#: sas/static/sas/js/picture.js:52
|
||||
|
||||
#: core/static/user/js/user_edit.js:93
|
||||
#, javascript-format
|
||||
msgid "captured.%s"
|
||||
msgstr "capture.%s"
|
||||
|
||||
#: eboutic/static/eboutic/js/makecommand.js:50
|
||||
msgid "Incorrect value"
|
||||
msgstr "Valeur incorrecte"
|
||||
|
||||
#: sas/static/sas/js/viewer.js:196
|
||||
msgid "Couldn't moderate picture"
|
||||
msgstr "Echec de la suppression de la photo"
|
||||
|
||||
#: sas/static/sas/js/viewer.js:209
|
||||
msgid "Couldn't delete picture"
|
||||
msgstr "Echec de la suppression de la photo"
|
||||
|
29
poetry.lock
generated
29
poetry.lock
generated
@ -1813,6 +1813,33 @@ files = [
|
||||
[package.dependencies]
|
||||
typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0"
|
||||
|
||||
[[package]]
|
||||
name = "pydantic-extra-types"
|
||||
version = "2.9.0"
|
||||
description = "Extra Pydantic types."
|
||||
optional = false
|
||||
python-versions = ">=3.8"
|
||||
files = []
|
||||
develop = false
|
||||
|
||||
[package.dependencies]
|
||||
pydantic = ">=2.5.2"
|
||||
typing-extensions = "*"
|
||||
|
||||
[package.extras]
|
||||
all = ["pendulum (>=3.0.0,<4.0.0)", "phonenumbers (>=8,<9)", "pycountry (>=23)", "python-ulid (>=1,<2)", "python-ulid (>=1,<3)", "pytz (>=2024.1)", "semver (>=3.0.2)", "semver (>=3.0.2,<3.1.0)", "tzdata (>=2024.1)"]
|
||||
pendulum = ["pendulum (>=3.0.0,<4.0.0)"]
|
||||
phonenumbers = ["phonenumbers (>=8,<9)"]
|
||||
pycountry = ["pycountry (>=23)"]
|
||||
python-ulid = ["python-ulid (>=1,<2)", "python-ulid (>=1,<3)"]
|
||||
semver = ["semver (>=3.0.2)"]
|
||||
|
||||
[package.source]
|
||||
type = "git"
|
||||
url = "https://github.com/pydantic/pydantic-extra-types.git"
|
||||
reference = "HEAD"
|
||||
resolved_reference = "58db4b096d7c90566d3d48d51b4665c01a591df6"
|
||||
|
||||
[[package]]
|
||||
name = "pygments"
|
||||
version = "2.18.0"
|
||||
@ -2626,4 +2653,4 @@ filelock = ">=3.4"
|
||||
[metadata]
|
||||
lock-version = "2.0"
|
||||
python-versions = "^3.12"
|
||||
content-hash = "b6202203d272cecdb607ea8ebc1ba12dd8369e4f387f65692c4a9681915e6f48"
|
||||
content-hash = "c9c49497cc576b24c96ea914b74ef5c3a0c2981c488a599752f05aabb575f8d8"
|
||||
|
@ -45,6 +45,10 @@ dict2xml = "^1.7.3"
|
||||
Sphinx = "^5" # Needed for building xapian
|
||||
tomli = "^2.0.1"
|
||||
django-honeypot = "^1.2.1"
|
||||
# When I introduced pydantic-extra-types, I needed *right now*
|
||||
# the PhoneNumberValidator class which was on the master branch but not released yet.
|
||||
# Once it's released, switch this to a regular version.
|
||||
pydantic-extra-types = { git = "https://github.com/pydantic/pydantic-extra-types.git", rev = "58db4b0" }
|
||||
|
||||
[tool.poetry.group.prod.dependencies]
|
||||
# deps used in prod, but unnecessary for development
|
||||
|
Loading…
Reference in New Issue
Block a user