✨ Start on error handling

♻ Use TypedDocumentNode's instead of apollo-react-typescript codegen
💄 Add toast
This commit is contained in:
nikolark committed 2021-11-06 21:49:28 +01:00
1 parent ed82ca3891
commit 0a435d3224
21 files changed
+565 -117

No files matched your search

+22
View File
@@ -0,0 +1,22 @@
import strawberry
@strawberry.interface
class Error:
message: str
@strawberry.field()
def error(self) -> bool:
return True
@strawberry.type
class FieldError(Error):
field: str
@strawberry.type
class FormErrors:
fields: list[FieldError]
message: str = ''
error: bool = True
+66
View File
@@ -0,0 +1,66 @@
import strawberry
from django.contrib.auth import get_user_model
from django.db import transaction
from django.shortcuts import get_object_or_404
from strawberry import ID
from main import models
from main.api.errors import Error, FormErrors, FieldError
from main.api.types import Order
UserModel = get_user_model()
@strawberry.input
class OrderLineInput:
product_id: ID
amount: int
@strawberry.type
class CreateOrderSuccess:
order: Order
@strawberry.type
class InsufficientFunds(Error):
amount_lacking: float
Response = strawberry.union("CreateOrderResponse", [CreateOrderSuccess, InsufficientFunds, FormErrors])
@strawberry.mutation
@transaction.atomic
def create_order(customer_id: ID, order_lines: list[OrderLineInput], is_external: bool = False) -> Response:
# clean and validate
try:
customer = UserModel.objects.get(pk=customer_id)
except (UserModel.DoesNotExist, ValueError):
customer = None
if customer is None and not is_external:
message = "Du har ikke valgt hvem som skal kjøpe."
return FormErrors(
message=message,
fields=[FieldError(field="customer_id", message=message)],
)
ols = []
order_sum = 0
for ol in order_lines:
product = get_object_or_404(models.Product, pk=ol.product_id)
price = product.sale_price_ext if is_external else product.sale_price_int
ols.append(models.OrderLine(product=product, amount=ol.amount, unit_price=price))
order_sum += ol.amount * price
if not is_external and customer.profile.balance <= order_sum:
return InsufficientFunds(amount_lacking=abs(order_sum - customer.profile.balance))
# create
order = models.Order.objects.create(customer=customer, order_sum=order_sum)
for ol in ols:
ol.order = order
models.OrderLine.objects.bulk_create(ols)
return CreateOrderSuccess(order=order)
+9 -2
View File
@@ -1,13 +1,20 @@
import strawberry
import strawberry_django
from main.api.types import Product, User
from main.api import mutations
from main.api.types import Product, User, Order
@strawberry.type
class Query:
all_products: list[Product] = strawberry_django.field()
all_users: list[User] = strawberry_django.field()
all_orders: list[Order] = strawberry_django.field()
schema = strawberry.Schema(query=Query)
@strawberry.type
class Mutation:
create_order = mutations.create_order
schema = strawberry.Schema(query=Query, mutation=Mutation)
+8
View File
@@ -43,3 +43,11 @@ class User:
last_name: auto
profile: UserProfile
# todo
@strawberry_django.type(models.Order)
class Order:
id: auto
customer: 'User'
order_sum: auto
created: auto
+23
View File
@@ -0,0 +1,23 @@
from pathlib import Path
from django.core.management import BaseCommand, CommandParser
from strawberry.printer import print_schema
from bbssite.settings import BASE_DIR
from main.api.schema import schema as schema_symbol
class Command(BaseCommand):
help = " Write graphql schema to file or stdout"
def add_arguments(self, parser: CommandParser):
parser.add_argument("--filename", default='schema.graphql', help='`-` prints to stdout')
def handle(self, *args, filename=None, **options):
schema_output = print_schema(schema_symbol)
if filename != '-':
with Path(BASE_DIR, filename).open("w+") as fp:
fp.write(schema_output)
self.stdout.write(self.style.SUCCESS('OK'))
else:
print(schema_output)