mirror of
https://github.com/ae-utbm/sith.git
synced 2025-07-11 12:29:24 +00:00
integration of 3D secure v2 for eboutic bank payment
This commit is contained in:
@ -21,6 +21,7 @@
|
||||
# Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||
#
|
||||
#
|
||||
from django.db.models.functions import Length
|
||||
|
||||
from sith.settings import SITH_COUNTER_OFFICES, SITH_MAIN_CLUB
|
||||
from django.db import models
|
||||
@ -38,16 +39,19 @@ import string
|
||||
import os
|
||||
import base64
|
||||
import datetime
|
||||
from dict2xml import dict2xml
|
||||
|
||||
from club.models import Club, Membership
|
||||
from accounting.models import CurrencyField
|
||||
from core.models import Group, User, Notification
|
||||
from subscription.models import Subscription
|
||||
|
||||
from django_countries.fields import CountryField
|
||||
|
||||
|
||||
class Customer(models.Model):
|
||||
"""
|
||||
This class extends a user to make a customer. It adds some basic customers informations, such as the accound ID, and
|
||||
This class extends a user to make a customer. 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
|
||||
"""
|
||||
|
||||
@ -89,13 +93,28 @@ class Customer(models.Model):
|
||||
.subscription_end
|
||||
) < timedelta(days=90)
|
||||
|
||||
@staticmethod
|
||||
def generate_account_id(number):
|
||||
number = str(number)
|
||||
letter = random.choice(string.ascii_lowercase)
|
||||
while Customer.objects.filter(account_id=number + letter).exists():
|
||||
letter = random.choice(string.ascii_lowercase)
|
||||
return number + letter
|
||||
@classmethod
|
||||
def new_for_user(cls, user: User):
|
||||
"""
|
||||
Create a new Customer instance for the user given in parameter without saving it
|
||||
The account if is automatically generated and the amount set at 0
|
||||
"""
|
||||
# account_id are number with a letter appended
|
||||
account_id = (
|
||||
Customer.objects.order_by(Length("account_id"), "account_id")
|
||||
.values("account_id")
|
||||
.last()
|
||||
)
|
||||
if account_id is None:
|
||||
# legacy from the old site
|
||||
return cls(user=user, account_id="1504a", amount=0)
|
||||
account_id = account_id["account_id"]
|
||||
num = int(account_id[:-1])
|
||||
while Customer.objects.filter(account_id=account_id).exists():
|
||||
num += 1
|
||||
account_id = str(num) + random.choice(string.ascii_lowercase)
|
||||
|
||||
return cls(user=user, account_id=account_id, amount=0)
|
||||
|
||||
def save(self, allow_negative=False, is_selling=False, *args, **kwargs):
|
||||
"""
|
||||
@ -122,6 +141,53 @@ class Customer(models.Model):
|
||||
return "".join(["https://", settings.SITH_URL, self.get_absolute_url()])
|
||||
|
||||
|
||||
class BillingInfo(models.Model):
|
||||
"""
|
||||
Represent the billing information of a user, which are required
|
||||
by the 3D-Secure v2 system used by the etransaction module
|
||||
"""
|
||||
|
||||
customer = models.OneToOneField(
|
||||
Customer, related_name="billing_infos", on_delete=models.CASCADE
|
||||
)
|
||||
|
||||
# declaring surname and name even though they are already defined
|
||||
# in User add some redundancy, but ensures that the billing infos
|
||||
# shall stay correct, whatever shenanigans the user commits on its profile
|
||||
first_name = models.CharField(_("First name"), max_length=30)
|
||||
last_name = models.CharField(_("Last name"), max_length=30)
|
||||
address_1 = models.CharField(_("Address 1"), max_length=50)
|
||||
address_2 = models.CharField(_("Address 2"), max_length=50, blank=True, null=True)
|
||||
zip_code = models.CharField(_("Zip code"), max_length=16) # code postal
|
||||
city = models.CharField(_("City"), max_length=50)
|
||||
country = CountryField(blank_label=_("Country"))
|
||||
|
||||
def to_3dsv2_xml(self) -> str:
|
||||
"""
|
||||
Convert the data from this model into a xml usable
|
||||
by the online paying service of the Crédit Agricole bank.
|
||||
see : `https://www.ca-moncommerce.com/espace-client-mon-commerce/up2pay-e-transactions/ma-documentation/manuel-dintegration-focus-3ds-v2/principes-generaux/#boutique-cms-utilisation-des-modules-up2pay-e-transactions-mise-a-jour-module`
|
||||
"""
|
||||
data = {
|
||||
"Billing": {
|
||||
"Address": {
|
||||
"FirstName": self.first_name,
|
||||
"LastName": self.last_name,
|
||||
"Address1": self.address_1,
|
||||
"ZipCode": self.zip_code,
|
||||
"City": self.city,
|
||||
"CountryCode": self.country,
|
||||
}
|
||||
}
|
||||
}
|
||||
if self.address_2:
|
||||
data["Billing"]["Address"]["Address2"] = self.address_2
|
||||
return dict2xml(data)
|
||||
|
||||
def __str__(self):
|
||||
return f"{self.first_name} {self.last_name}"
|
||||
|
||||
|
||||
class ProductType(models.Model):
|
||||
"""
|
||||
This describes a product type
|
||||
|
Reference in New Issue
Block a user