chore: ruff --fix

This commit is contained in:
nikolark authored and nikolark committed 2025-05-30 11:33:40 +02:00
1 parent 39a3d05154
commit 1f02ed5eff
19 files changed
+382 -369

No files matched your search

+15 -8
View File
@@ -1,12 +1,19 @@
from apps.kassa.models import KassaEvent
from django.contrib import admin
from apps.kassa.models import KassaEvent
@admin.register(KassaEvent)
class KassaEventAdmin(admin.ModelAdmin):
list_display = ['id', 'event', 'card_number', 'user_phone_number', 'user_galtinn_id',
'user_inside_id', 'created', 'transaction_id']
list_filter = ['event']
search_fields = ['card_number', 'user_phone_number', 'user_galtinn_id',
'user_inside_id', 'transaction_id']
admin.site.register(KassaEvent, KassaEventAdmin)
list_display = [
"id",
"event",
"card_number",
"user_phone_number",
"user_galtinn_id",
"user_inside_id",
"created",
"transaction_id",
]
list_filter = ["event"]
search_fields = ["card_number", "user_phone_number", "user_galtinn_id", "user_inside_id", "transaction_id"]
+2 -2
View File
@@ -1,5 +1,5 @@
from django.conf import settings
def sentry(request):
return {'SENTRY_DSN': settings.SENTRY_DSN or '', 'SENTRY_ENVIRONMENT': settings.SENTRY_ENVIRONMENT}
def sentry(_):
return {"SENTRY_DSN": settings.SENTRY_DSN or "", "SENTRY_ENVIRONMENT": settings.SENTRY_ENVIRONMENT}
+4 -5
View File
@@ -1,17 +1,16 @@
from django import forms
from django.utils.translation import gettext_lazy as _
from phonenumber_field.formfields import PhoneNumberField
from django.utils.translation import ugettext_lazy as _
class SearchUserForm(forms.Form):
query = forms.CharField(
required=False,
widget=forms.TextInput(attrs={'placeholder': _('Firstname, lastname, card number or email')})
required=False, widget=forms.TextInput(attrs={"placeholder": _("Firstname, lastname, card number or email")})
)
class AddCardForm(forms.Form):
card_number = forms.IntegerField(widget=forms.NumberInput(attrs={'autofocus': True}))
phone_number = PhoneNumberField(widget=forms.TextInput(attrs={'type': 'tel'}))
card_number = forms.IntegerField(widget=forms.NumberInput(attrs={"autofocus": True}))
phone_number = PhoneNumberField(widget=forms.TextInput(attrs={"type": "tel"}))
user_id = forms.IntegerField(widget=forms.HiddenInput(), required=False)
order_uuid = forms.IntegerField(widget=forms.HiddenInput(), required=False)
+20 -15
View File
@@ -1,25 +1,30 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
]
dependencies = []
operations = [
migrations.CreateModel(
name='KassaEvent',
name="KassaEvent",
fields=[
('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
('event', models.TextField(max_length=255, choices=[('new_card_membership', 'Added new card membership (no user yet)'), ('update_card', 'Updated user card number'), ('add_or_renew', 'Added or renewed membership user membership')])),
('card_number', models.IntegerField(null=True, blank=True)),
('user_inside_id', models.IntegerField(null=True, blank=True)),
('user_phone_number', models.TextField(max_length=100, null=True, blank=True)),
('created', models.DateTimeField(auto_now_add=True)),
('updated', models.DateTimeField(auto_now=True)),
("id", models.AutoField(verbose_name="ID", serialize=False, auto_created=True, primary_key=True)),
(
"event",
models.TextField(
max_length=255,
choices=[
("new_card_membership", "Added new card membership (no user yet)"),
("update_card", "Updated user card number"),
("add_or_renew", "Added or renewed membership user membership"),
],
),
),
("card_number", models.IntegerField(null=True, blank=True)),
("user_inside_id", models.IntegerField(null=True, blank=True)),
("user_phone_number", models.TextField(max_length=100, null=True, blank=True)),
("created", models.DateTimeField(auto_now_add=True)),
("updated", models.DateTimeField(auto_now=True)),
],
),
]
@@ -1,24 +1,27 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('kassa', '0001_initial'),
("kassa", "0001_initial"),
]
operations = [
migrations.AlterField(
model_name='kassaevent',
name='event',
field=models.CharField(max_length=255, choices=[('new_card_membership', 'Added new card membership (no user yet)'), ('update_card', 'Updated user card number'), ('add_or_renew', 'Added or renewed membership user membership')]),
model_name="kassaevent",
name="event",
field=models.CharField(
max_length=255,
choices=[
("new_card_membership", "Added new card membership (no user yet)"),
("update_card", "Updated user card number"),
("add_or_renew", "Added or renewed membership user membership"),
],
),
),
migrations.AlterField(
model_name='kassaevent',
name='user_phone_number',
model_name="kassaevent",
name="user_phone_number",
field=models.CharField(max_length=100, null=True, blank=True),
),
]
@@ -1,19 +1,23 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('kassa', '0002_auto_20150810_1327'),
("kassa", "0002_auto_20150810_1327"),
]
operations = [
migrations.AlterField(
model_name='kassaevent',
name='event',
field=models.CharField(max_length=255, choices=[('new_card_membership', 'Added new card membership (no user yet)'), ('sms_card_notify', 'Notified phone number about activation'), ('update_card', 'Updated user card number'), ('add_or_renew', 'Added or renewed membership user membership')]),
model_name="kassaevent",
name="event",
field=models.CharField(
max_length=255,
choices=[
("new_card_membership", "Added new card membership (no user yet)"),
("sms_card_notify", "Notified phone number about activation"),
("update_card", "Updated user card number"),
("add_or_renew", "Added or renewed membership user membership"),
],
),
),
]
@@ -1,19 +1,24 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('kassa', '0003_auto_20150812_1530'),
("kassa", "0003_auto_20150812_1530"),
]
operations = [
migrations.AlterField(
model_name='kassaevent',
name='event',
field=models.CharField(max_length=255, choices=[('new_card_membership', 'Added new card membership (no user yet)'), ('sms_card_notify', 'Notified phone number about activation'), ('update_card', 'Updated user card number'), ('add_or_renew', 'Added or renewed membership user membership'), ('refund', 'Refunded membership')]),
model_name="kassaevent",
name="event",
field=models.CharField(
max_length=255,
choices=[
("new_card_membership", "Added new card membership (no user yet)"),
("sms_card_notify", "Notified phone number about activation"),
("update_card", "Updated user card number"),
("add_or_renew", "Added or renewed membership user membership"),
("refund", "Refunded membership"),
],
),
),
]
@@ -1,19 +1,25 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('kassa', '0004_auto_20150825_1130'),
("kassa", "0004_auto_20150825_1130"),
]
operations = [
migrations.AlterField(
model_name='kassaevent',
name='event',
field=models.CharField(max_length=255, choices=[('new_card_membership', 'Added new card membership (no user yet)'), ('sms_card_notify', 'Notified phone number about activation'), ('update_card', 'Updated user card number'), ('add_or_renew', 'Added or renewed user membership'), ('renew_only', 'Renewed user membership'), ('refund', 'Refunded membership')]),
model_name="kassaevent",
name="event",
field=models.CharField(
max_length=255,
choices=[
("new_card_membership", "Added new card membership (no user yet)"),
("sms_card_notify", "Notified phone number about activation"),
("update_card", "Updated user card number"),
("add_or_renew", "Added or renewed user membership"),
("renew_only", "Renewed user membership"),
("refund", "Refunded membership"),
],
),
),
]
@@ -1,19 +1,26 @@
# -*- coding: utf-8 -*-
from __future__ import unicode_literals
from django.db import models, migrations
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('kassa', '0005_auto_20150829_1525'),
("kassa", "0005_auto_20150829_1525"),
]
operations = [
migrations.AlterField(
model_name='kassaevent',
name='event',
field=models.CharField(max_length=255, choices=[('add_or_renew', 'New or renewed user membership'), ('new_card_membership', 'New card membership (no user yet)'), ('refund', 'Refunded membership'), ('renew_only', 'Renewed user membership'), ('sms_card_notify', 'Sent activation link to phone number'), ('update_card', 'Updated card'), ('membership_trial', 'New membership trial')]),
model_name="kassaevent",
name="event",
field=models.CharField(
max_length=255,
choices=[
("add_or_renew", "New or renewed user membership"),
("new_card_membership", "New card membership (no user yet)"),
("refund", "Refunded membership"),
("renew_only", "Renewed user membership"),
("sms_card_notify", "Sent activation link to phone number"),
("update_card", "Updated card"),
("membership_trial", "New membership trial"),
],
),
),
]
@@ -1,20 +1,17 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.3 on 2017-07-22 12:40
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('kassa', '0006_auto_20150829_1811'),
("kassa", "0006_auto_20150829_1811"),
]
operations = [
migrations.AddField(
model_name='kassaevent',
name='transaction_id',
model_name="kassaevent",
name="transaction_id",
field=models.UUIDField(blank=True, null=True),
),
]
@@ -1,20 +1,17 @@
# -*- coding: utf-8 -*-
# Generated by Django 1.11.3 on 2017-07-22 12:43
from __future__ import unicode_literals
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('kassa', '0007_kassaevent_transaction_id'),
("kassa", "0007_kassaevent_transaction_id"),
]
operations = [
migrations.AddField(
model_name='kassaevent',
name='user_galtinn_id',
model_name="kassaevent",
name="user_galtinn_id",
field=models.IntegerField(blank=True, null=True),
),
]
+17 -17
View File
@@ -1,32 +1,32 @@
from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
class KassaEvent(models.Model):
ADD_OR_RENEW = 'add_or_renew'
NEW_CARD_MEMBERSHIP = 'new_card_membership'
REFUND = 'refund'
RENEW_ONLY = 'renew_only'
SMS_CARD_NOTIFY = 'sms_card_notify'
UPDATE_CARD = 'update_card'
MEMBERSHIP_TRIAL = 'membership_trial'
ADD_OR_RENEW = "add_or_renew"
NEW_CARD_MEMBERSHIP = "new_card_membership"
REFUND = "refund"
RENEW_ONLY = "renew_only"
SMS_CARD_NOTIFY = "sms_card_notify"
UPDATE_CARD = "update_card"
MEMBERSHIP_TRIAL = "membership_trial"
EVENT_CHOICES = (
(ADD_OR_RENEW, _('New or renewed user membership')),
(NEW_CARD_MEMBERSHIP, _('New card membership (no user yet)')),
(REFUND, _('Refunded membership')),
(RENEW_ONLY, _('Renewed user membership')),
(SMS_CARD_NOTIFY, _('Sent activation link to phone number')),
(UPDATE_CARD, _('Updated card')),
(MEMBERSHIP_TRIAL, _('New membership trial'))
(ADD_OR_RENEW, _("New or renewed user membership")),
(NEW_CARD_MEMBERSHIP, _("New card membership (no user yet)")),
(REFUND, _("Refunded membership")),
(RENEW_ONLY, _("Renewed user membership")),
(SMS_CARD_NOTIFY, _("Sent activation link to phone number")),
(UPDATE_CARD, _("Updated card")),
(MEMBERSHIP_TRIAL, _("New membership trial")),
)
event = models.CharField(max_length=255, choices=EVENT_CHOICES)
card_number = models.IntegerField(null=True, blank=True)
user_galtinn_id = models.IntegerField(null=True, blank=True)
user_inside_id = models.IntegerField(null=True, blank=True)
user_phone_number = models.CharField(max_length=100, null=True, blank=True)
user_phone_number = models.CharField(max_length=100, null=True, blank=True) # noqa: DJ001
transaction_id = models.UUIDField(null=True, blank=True)
created = models.DateTimeField(auto_now_add=True)
updated = models.DateTimeField(auto_now=True)
def __str__(self):
return 'KassaEvent: <{}>'.format(self.pk)
return f"KassaEvent: <{self.pk}>"
-1
View File
@@ -1 +0,0 @@
from django.test import TestCase
+15 -9
View File
@@ -1,13 +1,19 @@
from django.urls import path, re_path
from django.urls import path
from apps.kassa.views import (register, user_search, check_card, check_phone_number, register_card_and_membership,
renew_membership)
from apps.kassa.views import (
check_card,
check_phone_number,
register,
register_card_and_membership,
renew_membership,
user_search,
)
urlpatterns = [
re_path(r'^$', register, name='register'),
path('user-search/', user_search, name='user-search'),
path('check-phone-number/', check_phone_number, name='check-phone-number'),
path('check-card/', check_card, name='check-card'),
path('register-card-membership/', register_card_and_membership, name='register-card-and-membership'),
path('renew-membership/', renew_membership, name='renew-membership'),
path("", register, name="register"),
path("user-search/", user_search, name="user-search"),
path("check-phone-number/", check_phone_number, name="check-phone-number"),
path("check-card/", check_card, name="check-card"),
path("register-card-membership/", register_card_and_membership, name="register-card-and-membership"),
path("renew-membership/", renew_membership, name="renew-membership"),
]
+53 -57
View File
@@ -1,102 +1,98 @@
# coding: utf-8
from django.conf import settings
import datetime
import logging
import phonenumbers
import requests
import logging
from django.conf import settings
logger = logging.getLogger(__name__)
galtinn_auth = {
'Authorization': 'Token {}'.format(settings.GALTINN_API_KEY)
}
galtinn_auth = {"Authorization": f"Token {settings.GALTINN_API_KEY}"}
tekstmelding_auth = {
'Authorization': 'Token {}'.format(settings.TEKSTMELDING_API_KEY)
}
tekstmelding_auth = {"Authorization": f"Token {settings.TEKSTMELDING_API_KEY}"}
def send_sms_activation_link(phone_number, transaction_id):
to = phone_number.replace('+', '')
to = phone_number.replace("+", "")
code = transaction_id[:8]
activation_url = settings.GALTINN_ACTIVATION_URL.format(to=to, code=code)
message = settings.TEKSTMELDING_ACTIVATION_SMS_TEMPLATE.format(url=activation_url)
payload = {
'to': to,
'message': message
}
payload = {"to": to, "message": message}
if not settings.TEKSTMELDING_ENABLED:
logger.info('Tekstmelding disabled. Payload would be: {}'.format(payload))
return
url = '{}send'.format(settings.TEKSTMELDING_API_URL)
response = requests.post(url, json=payload, headers=tekstmelding_auth)
logger.info(f"Tekstmelding disabled. Payload would be: {payload}")
return None
url = f"{settings.TEKSTMELDING_API_URL}send"
response = requests.post(url, json=payload, headers=tekstmelding_auth, timeout=10)
return response.json()
def get_card(card_number):
url = '{}cards/{}/'.format(settings.GALTINN_API_URL, card_number)
return requests.get(url, headers=galtinn_auth)
url = f"{settings.GALTINN_API_URL}cards/{card_number}/"
return requests.get(url, headers=galtinn_auth, timeout=10)
def get_order(order_uuid):
url = '{}orders/{}/'.format(settings.GALTINN_API_URL, order_uuid)
return requests.get(url, headers=galtinn_auth)
url = f"{settings.GALTINN_API_URL}orders/{order_uuid}/"
return requests.get(url, headers=galtinn_auth, timeout=10)
def get_latest_order_by_card(card_number):
url = '{}orders/'.format(settings.GALTINN_API_URL)
payload = {'card_number': card_number}
orders = requests.get(url, params=payload, headers=galtinn_auth).json()
return orders.get('results')[0]
url = f"{settings.GALTINN_API_URL}orders/"
payload = {"card_number": card_number}
orders = requests.get(url, params=payload, headers=galtinn_auth, timeout=10).json()
return orders.get("results")[0]
def get_latest_order_by_phone(phone_number):
url = '{}orders/'.format(settings.GALTINN_API_URL)
payload = {'phone_number': phone_number}
orders = requests.get(url, params=payload, headers=galtinn_auth).json()
if orders.get('count'):
return orders.get('results')[0]
url = f"{settings.GALTINN_API_URL}orders/"
payload = {"phone_number": phone_number}
orders = requests.get(url, params=payload, headers=galtinn_auth, timeout=10).json()
if orders.get("count"):
return orders.get("results")[0]
return None
def get_user(user_id):
url = '{}users/{}/'.format(settings.GALTINN_API_URL, user_id)
return requests.get(url, headers=galtinn_auth)
url = f"{settings.GALTINN_API_URL}users/{user_id}/"
return requests.get(url, headers=galtinn_auth, timeout=10)
def get_user_by_phone(phone_number):
url = '{}users/'.format(settings.GALTINN_API_URL)
payload = {'phone_number': phone_number}
users = requests.get(url, params=payload, headers=galtinn_auth).json()
if users.get('count') == 1:
return users.get('results')[0]
url = f"{settings.GALTINN_API_URL}users/"
payload = {"phone_number": phone_number}
users = requests.get(url, params=payload, headers=galtinn_auth, timeout=10).json()
if users.get("count") == 1:
return users.get("results")[0]
return None
def update_card(card_number, user_id=None, order_uuid=None, transaction_id=None):
assert not (user_id and order_uuid)
url = '{}kassa/card/'.format(settings.GALTINN_API_URL)
if user_id and order_uuid:
raise ValueError("Cannot provide both user_id and order_uuid. Provide one or the other.")
url = f"{settings.GALTINN_API_URL}kassa/card/"
payload = {
'member_card': card_number,
'user': user_id,
'order': order_uuid,
'transaction_id': str(transaction_id) if transaction_id else None,
"member_card": card_number,
"user": user_id,
"order": order_uuid,
"transaction_id": str(transaction_id) if transaction_id else None,
}
return requests.patch(url, json=payload, headers=galtinn_auth)
return requests.patch(url, json=payload, headers=galtinn_auth, timeout=10)
def update_membership(user=None, phone_number=None, card_number=None, membership_type=None,
transaction_id=None):
assert membership_type in ('standard', 'trial')
url = '{}kassa/membership/'.format(settings.GALTINN_API_URL)
def update_membership(user=None, phone_number=None, card_number=None, membership_type=None, transaction_id=None):
if membership_type not in ("standard", "trial"):
raise ValueError("Invalid membership type provided. Must be 'standard' or 'trial'.")
url = f"{settings.GALTINN_API_URL}kassa/membership/"
payload = {
'user': user,
'phone_number': phone_number,
'member_card': card_number,
'membership_type': membership_type,
'transaction_id': transaction_id,
"user": user,
"phone_number": phone_number,
"member_card": card_number,
"membership_type": membership_type,
"transaction_id": transaction_id,
}
return requests.post(url, json=payload, headers=galtinn_auth)
return requests.post(url, json=payload, headers=galtinn_auth, timeout=10)
def format_phone_number(number):
@@ -104,7 +100,7 @@ def format_phone_number(number):
return number
try:
p = phonenumbers.parse(number, region='NO')
p = phonenumbers.parse(number, region="NO")
except phonenumbers.NumberParseException:
return number
@@ -115,7 +111,7 @@ def format_phone_number(number):
def is_autumn():
today = datetime.date.today()
today = datetime.datetime.now(tz=datetime.UTC).date()
_min = datetime.date(year=today.year, month=8, day=1)
_max = datetime.date(year=today.year + 1, month=1, day=1)
return _min <= today < _max
+95 -91
View File
@@ -1,21 +1,30 @@
# coding: utf-8
import json
import logging
import uuid
from http import HTTPStatus
import phonenumbers
import requests
from django.conf import settings
from django.contrib.auth.decorators import login_required
from django.http import JsonResponse
from django.shortcuts import render
from django.utils import timezone
from itertools import groupby
import json
import uuid
import logging
import phonenumbers
import requests
from apps.kassa.models import KassaEvent
from apps.kassa.forms import AddCardForm, SearchUserForm
from apps.kassa.utils import send_sms_activation_link, update_card, get_card, \
get_order, get_latest_order_by_card, get_latest_order_by_phone, get_user, get_user_by_phone, \
galtinn_auth, update_membership, format_phone_number, is_autumn
from apps.kassa.models import KassaEvent
from apps.kassa.utils import (
format_phone_number,
galtinn_auth,
get_card,
get_latest_order_by_card,
get_latest_order_by_phone,
get_user,
get_user_by_phone,
is_autumn,
send_sms_activation_link,
update_card,
update_membership,
)
logger = logging.getLogger(__name__)
@@ -23,142 +32,136 @@ logger = logging.getLogger(__name__)
@login_required
def register(request):
context = {
'add_card_form': AddCardForm(),
'search_user_form': SearchUserForm(),
'show_trial_membership': is_autumn()
"add_card_form": AddCardForm(),
"search_user_form": SearchUserForm(),
"show_trial_membership": is_autumn(),
}
return render(request, 'kassa/register.html', context)
return render(request, "kassa/register.html", context)
@login_required
def user_search(request):
payload = {
'search': request.GET.get('search', '')
}
url = '{}users/'.format(settings.GALTINN_API_URL)
data = requests.get(url, params=payload, headers=galtinn_auth).json()
payload = {"search": request.GET.get("search", "")}
url = f"{settings.GALTINN_API_URL}users/"
data = requests.get(url, params=payload, headers=galtinn_auth, timeout=10).json()
return JsonResponse(data)
@login_required
def check_phone_number(request):
number = request.GET.get('phone_number', '').strip()
number = request.GET.get("phone_number", "").strip()
if len(number) < 2:
return JsonResponse({'error': 'Phone number is too short'})
min_length = 2
if len(number) < min_length:
return JsonResponse({"error": "Phone number is too short"})
# Is phone number valid?
try:
p = phonenumbers.parse(number, region='NO')
p = phonenumbers.parse(number, region="NO")
if not phonenumbers.is_valid_number(p):
return JsonResponse({'error': "Phone number '{}' is invalid.".format(number)})
return JsonResponse({"error": f"Phone number '{number}' is invalid."})
except phonenumbers.NumberParseException as e:
return JsonResponse({'error': str(e).replace('(1) ', '')})
return JsonResponse({"error": str(e).replace("(1) ", "")})
number = phonenumbers.format_number(p, phonenumbers.PhoneNumberFormat.E164)
user = get_user_by_phone(number)
order = get_latest_order_by_phone(number)
return JsonResponse({
'user': user,
'order': order
})
return JsonResponse({"user": user, "order": order})
@login_required
def check_card(request):
if request.method != 'GET':
return JsonResponse({'error': 'Only method GET supported'})
if request.method != "GET":
return JsonResponse({"error": "Only method GET supported"})
card_number = request.GET.get('card_number')
card_number = request.GET.get("card_number")
response = get_card(card_number)
if response.status_code != 200:
if response.status_code != HTTPStatus.OK:
return JsonResponse(response.json(), status=response.status_code)
card = response.json()
if card.get('user'):
card['user'] = get_user(card['user']).json()
card['order'] = None
if card.get('orders'):
card['order'] = get_latest_order_by_card(card_number)
card.pop('orders')
if card.get("user"):
card["user"] = get_user(card["user"]).json()
card["order"] = None
if card.get("orders"):
card["order"] = get_latest_order_by_card(card_number)
card.pop("orders")
return JsonResponse(card, status=response.status_code)
@login_required
def register_card_and_membership(request):
if request.method != 'POST':
return JsonResponse({'error': 'Only method POST supported'})
if request.method != "POST":
return JsonResponse({"error": "Only method POST supported"})
post_data = json.loads(request.body.decode('utf-8'))
post_data = json.loads(request.body.decode("utf-8"))
# new_card_membership, update_card, add_or_renew, sms_card_notify
# TODO: multiple actions (to allow renewal only)
action = post_data.get('action')
user_id = post_data.get('user_id')
order_uuid = post_data.get('order_uuid')
card_number = post_data.get('card_number')
phone_number_raw = post_data.get('phone_number')
membership_trial = post_data.get('membership_trial')
membership_type = 'trial' if membership_trial else 'standard'
action = post_data.get("action")
user_id = post_data.get("user_id")
order_uuid = post_data.get("order_uuid")
card_number = post_data.get("card_number")
phone_number_raw = post_data.get("phone_number")
membership_trial = post_data.get("membership_trial")
membership_type = "trial" if membership_trial else "standard"
transaction_id = uuid.uuid4()
logger.debug('register_card_and_membership post_data %r', post_data)
logger.debug("register_card_and_membership post_data %r", post_data)
phone_number = format_phone_number(phone_number_raw)
# Update card number on user or order
if action in ('update_card', 'sms_card_notify'):
if action == 'update_card' and user_id:
response = update_card(card_number,
user_id=user_id)
elif action == 'sms_card_notify' and order_uuid:
response = update_card(card_number,
order_uuid=order_uuid,
transaction_id=transaction_id)
else:
assert user_id or order_uuid
if response.status_code != 200:
if action in ("update_card", "sms_card_notify"):
if action == "update_card" and user_id:
response = update_card(card_number, user_id=user_id)
elif action == "sms_card_notify" and order_uuid:
response = update_card(card_number, order_uuid=order_uuid, transaction_id=transaction_id)
elif not user_id and not order_uuid:
return JsonResponse({"error": "Either user_id or order_uuid must be set"}, status=HTTPStatus.BAD_REQUEST)
if response.status_code != HTTPStatus.OK:
return JsonResponse(response.json(), status=response.status_code)
event_data = {
'event': KassaEvent.UPDATE_CARD,
'user_phone_number': phone_number,
'card_number': card_number,
'user_galtinn_id': user_id,
'transaction_id': transaction_id
"event": KassaEvent.UPDATE_CARD,
"user_phone_number": phone_number,
"card_number": card_number,
"user_galtinn_id": user_id,
"transaction_id": transaction_id,
}
logger.debug(event_data)
KassaEvent.objects.create(**event_data)
# Add initial or renew membership for existing user or order
if action in ('add_or_renew', 'new_card_membership'):
if action in ("add_or_renew", "new_card_membership"):
response = update_membership(
user=user_id,
phone_number=phone_number,
card_number=card_number,
membership_type=membership_type,
transaction_id=str(transaction_id))
transaction_id=str(transaction_id),
)
KassaEvent.objects.create(
event=KassaEvent.ADD_OR_RENEW if membership_type != 'trial' else KassaEvent.MEMBERSHIP_TRIAL,
event=KassaEvent.ADD_OR_RENEW if membership_type != "trial" else KassaEvent.MEMBERSHIP_TRIAL,
user_galtinn_id=user_id,
card_number=card_number,
user_phone_number=phone_number,
transaction_id=transaction_id
transaction_id=transaction_id,
)
# Send activation notification (link) to user by SMS
if action in ('new_card_membership', 'sms_card_notify'):
if action in ("new_card_membership", "sms_card_notify"):
event = KassaEvent.NEW_CARD_MEMBERSHIP
if action == 'sms_card_notify':
if action == "sms_card_notify":
event = KassaEvent.SMS_CARD_NOTIFY
# FIXME: could be async
send_sms_activation_link(phone_number=phone_number,
transaction_id=str(transaction_id))
send_sms_activation_link(phone_number=phone_number, transaction_id=str(transaction_id))
KassaEvent.objects.create(
event=event,
card_number=card_number,
user_phone_number=phone_number,
transaction_id=transaction_id
event=event, card_number=card_number, user_phone_number=phone_number, transaction_id=transaction_id
)
return JsonResponse(response.json(), status=response.status_code)
@@ -166,18 +169,18 @@ def register_card_and_membership(request):
@login_required
def renew_membership(request):
if request.method != 'POST':
return JsonResponse({'error': 'Only method POST supported'})
if request.method != "POST":
return JsonResponse({"error": "Only method POST supported"})
post_data = json.loads(request.body.decode('utf-8'))
user_id = post_data.get('user_id')
phone_number_raw = post_data.get('phone_number')
card_number = post_data.get('card_number')
membership_trial = post_data.get('membership_trial')
membership_type = 'trial' if membership_trial else 'standard'
post_data = json.loads(request.body.decode("utf-8"))
user_id = post_data.get("user_id")
phone_number_raw = post_data.get("phone_number")
card_number = post_data.get("card_number")
membership_trial = post_data.get("membership_trial")
membership_type = "trial" if membership_trial else "standard"
transaction_id = str(uuid.uuid4())
logger.debug('renew_membership post_data %r', post_data)
logger.debug("renew_membership post_data %r", post_data)
phone_number = format_phone_number(phone_number_raw)
response = update_membership(
@@ -185,11 +188,12 @@ def renew_membership(request):
phone_number=phone_number,
card_number=card_number,
membership_type=membership_type,
transaction_id=transaction_id)
transaction_id=transaction_id,
)
KassaEvent.objects.create(
event=KassaEvent.RENEW_ONLY if membership_trial is None else KassaEvent.MEMBERSHIP_TRIAL,
user_galtinn_id=user_id,
transaction_id=transaction_id
transaction_id=transaction_id,
)
return JsonResponse(response.json(), status=response.status_code)
Vendored
+16 -16
View File
@@ -7,27 +7,27 @@ from invoke import task
@task()
def deploy(c):
"""Make sure proxy_user is set to your neuf username."""
project_path = '/var/www/neuf.no/kassa'
proxy_user = os.getenv('DEPLOY_USER', os.getenv('USER'))
project_path = "/var/www/neuf.no/kassa"
proxy_user = os.getenv("DEPLOY_USER", os.getenv("USER"))
c = Connection(host='gitdeploy@dreamcast.neuf.no', gateway=Connection('login.neuf.no', user=proxy_user))
c = Connection(host="gitdeploy@dreamcast.neuf.no", gateway=Connection("login.neuf.no", user=proxy_user))
with c.cd(project_path), c.prefix('source {}/venv/bin/activate'.format(project_path)):
c.run('git pull') # Get source
c.run('pip install -U pip')
c.run('pip install -r requirements.txt') # install deps in virtualenv
with c.cd('static'): # install and compile frontend deps
c.run('npm i')
c.run('npm run build')
c.run('python manage.py collectstatic --noinput -i node_modules') # Collect static
c.run('python manage.py migrate') # Run DB migrations
with c.cd(project_path), c.prefix(f"source {project_path}/venv/bin/activate"):
c.run("git pull") # Get source
c.run("pip install -U pip")
c.run("pip install -r requirements.txt") # install deps in virtualenv
with c.cd("static"): # install and compile frontend deps
c.run("npm i")
c.run("npm run build")
c.run("python manage.py collectstatic --noinput -i node_modules") # Collect static
c.run("python manage.py migrate") # Run DB migrations
# Reload gunicorn
c.sudo('/usr/bin/supervisorctl pid kassa.neuf.no | xargs kill -HUP', shell=False)
c.sudo("/usr/bin/supervisorctl pid kassa.neuf.no | xargs kill -HUP", shell=False)
@task
def build(c):
with c.cd('static'):
c.run('npm i')
c.run('npm run build')
with c.cd("static"):
c.run("npm i")
c.run("npm run build")
+65 -81
View File
@@ -9,16 +9,17 @@ https://docs.djangoproject.com/en/1.8/ref/settings/
"""
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
import os
import contextlib
from pathlib import Path
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
BASE_DIR = Path(__file__).parent.parent
# Quick-start development settings - unsuitable for production
# See https://docs.djangoproject.com/en/1.8/howto/deployment/checklist/
# SECURITY WARNING: keep the secret key used in production secret!
SECRET_KEY = '79l0@&(^ra9=s783rqeo2awhs6@c!j&wan6t-0wi8azyd@!x+7'
SECRET_KEY = "79l0@&(^ra9=s783rqeo2awhs6@c!j&wan6t-0wi8azyd@!x+7" # noqa: S105
# SECURITY WARNING: don't run with debug turned on in production!
DEBUG = True
@@ -29,134 +30,117 @@ ALLOWED_HOSTS = []
# Application definition
INSTALLED_APPS = (
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'bootstrapform',
'django_extensions',
'corsheaders',
"django.contrib.admin",
"django.contrib.auth",
"django.contrib.contenttypes",
"django.contrib.sessions",
"django.contrib.messages",
"django.contrib.staticfiles",
"bootstrapform",
"django_extensions",
"corsheaders",
)
LOCAL_APPS = ('apps.kassa',)
LOCAL_APPS = ("apps.kassa",)
INSTALLED_APPS += LOCAL_APPS
MIDDLEWARE = (
'django.contrib.sessions.middleware.SessionMiddleware',
'corsheaders.middleware.CorsMiddleware',
'django.middleware.common.CommonMiddleware',
'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
'django.middleware.clickjacking.XFrameOptionsMiddleware',
'django.middleware.security.SecurityMiddleware',
"django.contrib.sessions.middleware.SessionMiddleware",
"corsheaders.middleware.CorsMiddleware",
"django.middleware.common.CommonMiddleware",
"django.middleware.csrf.CsrfViewMiddleware",
"django.contrib.auth.middleware.AuthenticationMiddleware",
"django.contrib.messages.middleware.MessageMiddleware",
"django.middleware.clickjacking.XFrameOptionsMiddleware",
"django.middleware.security.SecurityMiddleware",
)
ROOT_URLCONF = 'kassasite.urls'
ROOT_URLCONF = "kassasite.urls"
TEMPLATES = [
{
'BACKEND': 'django.template.backends.django.DjangoTemplates',
'DIRS': [
os.path.join(BASE_DIR, 'apps/kassa/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',
'apps.kassa.context_processors.sentry',
"BACKEND": "django.template.backends.django.DjangoTemplates",
"DIRS": [BASE_DIR.joinpath("apps/kassa/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",
"apps.kassa.context_processors.sentry",
],
},
},
]
WSGI_APPLICATION = 'kassasite.wsgi.application'
WSGI_APPLICATION = "kassasite.wsgi.application"
# Database
# https://docs.djangoproject.com/en/1.8/ref/settings/#databases
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
"default": {
"ENGINE": "django.db.backends.sqlite3",
"NAME": BASE_DIR.joinpath("db.sqlite3"),
}
}
# Internationalization
# https://docs.djangoproject.com/en/1.8/topics/i18n/
LANGUAGE_CODE = 'en-us'
TIME_ZONE = 'Europe/Oslo'
LANGUAGE_CODE = "en-us"
TIME_ZONE = "Europe/Oslo"
USE_I18N = True
USE_L10N = True
USE_TZ = True
# Static files (CSS, JavaScript, Images)
# https://docs.djangoproject.com/en/1.8/howto/static-files/
STATIC_URL = '/static/'
STATICFILES_DIRS = (
os.path.join(BASE_DIR, 'static'),
)
STATIC_ROOT = os.path.join(BASE_DIR, 'staticfiles')
STATIC_URL = "/static/"
STATICFILES_DIRS = (BASE_DIR.joinpath("static"),)
STATIC_ROOT = BASE_DIR.joinpath("staticfiles")
LOGIN_REDIRECT_URL = '/'
LOGIN_REDIRECT_URL = "/"
GALTINN_API_KEY = ''
GALTINN_API_URL = 'https://galtinn.neuf.no/api/'
GALTINN_ACTIVATION_URL = 'https://galtinn.neuf.no/activate/{to}/{code}'
GALTINN_API_KEY = ""
GALTINN_API_URL = "https://galtinn.neuf.no/api/"
GALTINN_ACTIVATION_URL = "https://galtinn.neuf.no/activate/{to}/{code}"
TEKSTMELDING_API_KEY = ''
TEKSTMELDING_API_URL = 'https://tekstmelding.neuf.no/'
TEKSTMELDING_API_KEY = ""
TEKSTMELDING_API_URL = "https://tekstmelding.neuf.no/"
TEKSTMELDING_ENABLED = True
TEKSTMELDING_ACTIVATION_SMS_TEMPLATE = 'Velkommen som medlem! Registrer deg her: {url}'
TEKSTMELDING_ACTIVATION_SMS_TEMPLATE = "Velkommen som medlem! Registrer deg her: {url}"
CORS_ORIGIN_ALLOW_ALL = True
LOGGING = {
'version': 1,
'disable_existing_loggers': True,
'formatters': {
'verbose': {
'format': '%(levelname)s %(asctime)s %(module)s '
'%(process)d %(thread)d %(message)s'
},
"version": 1,
"disable_existing_loggers": True,
"formatters": {
"verbose": {"format": "%(levelname)s %(asctime)s %(module)s %(process)d %(thread)d %(message)s"},
},
'handlers': {
'console': {
'level': 'DEBUG',
'class': 'logging.StreamHandler',
'formatter': 'verbose'
}
},
'loggers': {
'root': {
'level': 'WARNING',
'handlers': ['console'],
"handlers": {"console": {"level": "DEBUG", "class": "logging.StreamHandler", "formatter": "verbose"}},
"loggers": {
"root": {
"level": "WARNING",
"handlers": ["console"],
},
'django.db.backends': {
'level': 'ERROR',
'handlers': ['console'],
'propagate': False,
"django.db.backends": {
"level": "ERROR",
"handlers": ["console"],
"propagate": False,
},
},
}
SENTRY_DSN = None
SENTRY_ENVIRONMENT = 'dev'
SENTRY_ENVIRONMENT = "dev"
DEFAULT_AUTO_FIELD = "django.db.models.BigAutoField"
# Local settings
try:
from .local_settings import *
except ImportError:
pass
with contextlib.suppress(ImportError):
from .local_settings import * # noqa: F403
+2 -8
View File
@@ -1,13 +1,7 @@
from django.conf.urls import include, url
from django.contrib import admin
from django.urls import path
from django.contrib.auth import urls as auth_urls
from django.urls import include, path
from apps.kassa import urls as kassa_urls
urlpatterns = [
path('admin/', admin.site.urls),
url('^', include(kassa_urls)),
path('accounts/', include(auth_urls))
]
urlpatterns = [path("admin/", admin.site.urls), path("", include(kassa_urls)), path("accounts/", include(auth_urls))]