++bridge update

This commit is contained in:
Nico Schottelius 2021-01-17 15:53:30 +01:00
commit a920887100
16 changed files with 271 additions and 134 deletions

View file

@ -47,9 +47,13 @@ class BillAdmin(admin.ModelAdmin):
raise self._get_404_exception(object_id)
output_file = NamedTemporaryFile()
bill_html = render_to_string("bill.html.j2", {'bill': bill,
'bill_records': bill.billrecord_set.all()
})
bill_html = render_to_string(
"uncloud_pay/bill.html.j2",
{
'bill': bill,
'bill_records': bill.billrecord_set.all()
}
)
bytestring_to_pdf(bill_html.encode('utf-8'), output_file)
response = FileResponse(output_file, content_type="application/pdf")
@ -63,7 +67,7 @@ class BillAdmin(admin.ModelAdmin):
if bill is None:
raise self._get_404_exception(object_id)
return render(request, 'bill.html.j2',
return render(request, 'uncloud_pay/bill.html.j2',
{'bill': bill,
'bill_records': bill.billrecord_set.all()
})

File diff suppressed because one or more lines are too long

View file

@ -1,24 +1,23 @@
import logging
import itertools
import datetime
from math import ceil
from calendar import monthrange
from decimal import Decimal
from functools import reduce
from django.db import models
from django.db.models import Q
from django.contrib.auth import get_user_model
from django.contrib.contenttypes.fields import GenericForeignKey
from django.contrib.contenttypes.models import ContentType
from django.utils.translation import gettext_lazy as _
from django.core.validators import MinValueValidator
from django.utils import timezone
from django.core.exceptions import ObjectDoesNotExist, ValidationError
from django.conf import settings
from django.contrib.auth import get_user_model
from django.core.validators import MinValueValidator
from django.db import models
from django.utils.translation import gettext_lazy as _
from django.utils import timezone
# Verify whether or not to use them here
from django.core.exceptions import ObjectDoesNotExist, ValidationError
from uncloud import AMOUNT_DECIMALS, AMOUNT_MAX_DIGITS
from uncloud.models import UncloudAddress
from .services import *
# Used to generate bill due dates.
BILL_PAYMENT_DELAY=datetime.timedelta(days=10)
@ -26,36 +25,6 @@ BILL_PAYMENT_DELAY=datetime.timedelta(days=10)
# Initialize logger.
logger = logging.getLogger(__name__)
def start_of_month(a_day):
""" Returns first of the month of a given datetime object"""
return a_day.replace(day=1,hour=0,minute=0,second=0, microsecond=0)
def end_of_month(a_day):
""" Returns first of the month of a given datetime object"""
_, last_day = monthrange(a_day.year, a_day.month)
return a_day.replace(day=last_day,hour=23,minute=59,second=59, microsecond=0)
def start_of_this_month():
""" Returns first of this month"""
a_day = timezone.now()
return a_day.replace(day=1,hour=0,minute=0,second=0, microsecond=0)
def end_of_this_month():
""" Returns first of this month"""
a_day = timezone.now()
_, last_day = monthrange(a_day.year, a_day.month)
return a_day.replace(day=last_day,hour=23,minute=59,second=59, microsecond=0)
def end_before(a_date):
""" Return suitable datetimefield for ending just before a_date """
return a_date - datetime.timedelta(seconds=1)
def start_after(a_date):
""" Return suitable datetimefield for starting just after a_date """
return a_date + datetime.timedelta(seconds=1)
def default_payment_delay():
return timezone.now() + BILL_PAYMENT_DELAY
@ -68,7 +37,6 @@ class Currency(models.TextChoices):
# USD = 'USD', _('US Dollar')
###
# Stripe
@ -95,7 +63,7 @@ class StripeCreditCard(models.Model):
class Meta:
constraints = [
models.UniqueConstraint(fields=['owner'],
condition=Q(active=True),
condition=models.Q(active=True),
name='one_active_card_per_user')
]
@ -117,9 +85,7 @@ class Payment(models.Model):
('stripe', 'Stripe'),
('voucher', 'Voucher'),
('referral', 'Referral'),
('unknown', 'Unknown')
),
default='unknown')
))
timestamp = models.DateTimeField(default=timezone.now)
@ -135,6 +101,11 @@ class Payment(models.Model):
class PaymentMethod(models.Model):
"""
Not sure if this is still in use
"""
owner = models.ForeignKey(get_user_model(),
on_delete=models.CASCADE,
editable=False)
@ -151,15 +122,6 @@ class PaymentMethod(models.Model):
stripe_payment_method_id = models.CharField(max_length=32, blank=True, null=True)
stripe_setup_intent_id = models.CharField(max_length=32, blank=True, null=True)
# @property
# def stripe_card_last4(self):
# if self.source == 'stripe' and self.active:
# payment_method = uncloud_pay.stripe.get_payment_method(
# self.stripe_payment_method_id)
# return payment_method.card.last4
# else:
# return None
@property
def active(self):
if self.source == 'stripe' and self.stripe_payment_method_id != None:
@ -276,7 +238,7 @@ class BillingAddress(UncloudAddress):
class Meta:
constraints = [
models.UniqueConstraint(fields=['owner'],
condition=Q(active=True),
condition=models.Q(active=True),
name='one_active_billing_address_per_user')
]
@ -297,18 +259,13 @@ class BillingAddress(UncloudAddress):
if not billing_address:
billing_address = cls.objects.create(owner=owner,
organization="uncloud admins",
name="Uncloud Admin",
full_name="Uncloud Admin",
street="Uncloudstreet. 42",
city="Luchsingen",
postal_code="8775",
country="CH",
active=True)
@staticmethod
def get_address_for(user):
return BillingAddress.objects.get(owner=user, active=True)
def __str__(self):
return "{} - {}, {}, {} {}, {}".format(
self.owner,
@ -1186,7 +1143,7 @@ class Bill(models.Model):
return bill
def __str__(self):
return f"Bill {self.owner}-{self.id}"
return f"{self.owner}-{self.id}"
class BillRecord(models.Model):
@ -1256,7 +1213,7 @@ class ProductToRecurringPeriod(models.Model):
class Meta:
constraints = [
models.UniqueConstraint(fields=['product'],
condition=Q(is_default=True),
condition=models.Q(is_default=True),
name='one_default_recurring_period_per_product'),
models.UniqueConstraint(fields=['product', 'recurring_period'],
name='recurring_period_once_per_product')

View file

@ -21,3 +21,6 @@ def get_spendings_for_user(user):
@transaction.atomic
def get_balance_for_user(user):
return get_payments_for_user(user) - get_spendings_for_user(user)
def get_billing_address_for_user(user):
return BillingAddress.objects.get(owner=user, active=True)

View file

@ -36,6 +36,11 @@ class PaymentSerializer(serializers.ModelSerializer):
class BalanceSerializer(serializers.Serializer):
balance = serializers.DecimalField(max_digits=AMOUNT_MAX_DIGITS, decimal_places=AMOUNT_DECIMALS)
class BillingAddressSerializer(serializers.ModelSerializer):
class Meta:
model = BillingAddress
exclude = [ "owner" ]
################################################################################
# Unchecked code
@ -96,11 +101,6 @@ class BillRecordSerializer(serializers.Serializer):
amount = serializers.DecimalField(AMOUNT_MAX_DIGITS, AMOUNT_DECIMALS)
total = serializers.DecimalField(AMOUNT_MAX_DIGITS, AMOUNT_DECIMALS)
class BillingAddressSerializer(serializers.ModelSerializer):
class Meta:
model = BillingAddress
fields = ['uuid', 'organization', 'name', 'street', 'city', 'postal_code', 'country', 'vat_number']
class BillSerializer(serializers.ModelSerializer):
billing_address = BillingAddressSerializer(read_only=True)
records = BillRecordSerializer(many=True, read_only=True)

32
uncloud_pay/services.py Normal file
View file

@ -0,0 +1,32 @@
from django.utils import timezone
def start_of_month(a_day):
""" Returns first of the month of a given datetime object"""
return a_day.replace(day=1,hour=0,minute=0,second=0, microsecond=0)
def end_of_month(a_day):
""" Returns first of the month of a given datetime object"""
_, last_day = monthrange(a_day.year, a_day.month)
return a_day.replace(day=last_day,hour=23,minute=59,second=59, microsecond=0)
def start_of_this_month():
""" Returns first of this month"""
a_day = timezone.now()
return a_day.replace(day=1,hour=0,minute=0,second=0, microsecond=0)
def end_of_this_month():
""" Returns first of this month"""
a_day = timezone.now()
_, last_day = monthrange(a_day.year, a_day.month)
return a_day.replace(day=last_day,hour=23,minute=59,second=59, microsecond=0)
def end_before(a_date):
""" Return suitable datetimefield for ending just before a_date """
return a_date - datetime.timedelta(seconds=1)
def start_after(a_date):
""" Return suitable datetimefield for starting just after a_date """
return a_date + datetime.timedelta(seconds=1)

View file

@ -680,11 +680,9 @@ oAsAAAAAAACGQNAFAAAAAAAAQyDoAgAAAAAAgCEQdAEAAAAAAMAQCLoAAAAAAABgCP83AL6WQ1Y7
</div>
<div class="d4">
<div class="b1">
{{ bill.starting_date|date:"c" }} -
{{ bill.ending_date|date:"c" }}
<br>Bill id: {{ bill }}
<br>Due: {{ bill.due_date }}
Bill id: {{ bill }}
<br>{{ bill.starting_date|date:"Ymd" }} -
{{ bill.ending_date|date:"Ymd" }}
</div>
</div>
<div style="clear: both;"></div>
@ -703,8 +701,8 @@ oAsAAAAAAACGQNAFAAAAAAAAQyDoAgAAAAAAgCEQdAEAAAAAAMAQCLoAAAAAAABgCP83AL6WQ1Y7
<tbody>
{% for record in bill_records %}
<tr class="table-list">
<td>{{ record.starting_date|date:"c" }}
- {{ record.ending_date|date:"c" }}
<td>{{ record.starting_date|date:"Ymd-H:i:s" }}
- {{ record.ending_date|date:"Ymd-H:i:s" }}
{{ record.order }}
</td>
<td>{{ record.price|floatformat:2 }}</td>