Skip to content

Commit

Permalink
Merge branch 'master' into add-user-avatar-managment
Browse files Browse the repository at this point in the history
  • Loading branch information
maarcingebala committed May 6, 2019
2 parents fb01653 + 9331b04 commit 6477603
Show file tree
Hide file tree
Showing 34 changed files with 206 additions and 216 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,8 @@ All notable, unreleased changes to this project will be documented in this file.
- Ensure adding to quantities in checkout is respecting the limits set both in storefront 1.0 and in the API - #4005 by @NyanKiyoshi
- Fix price_range_as_dict function - #3999 by @zodiacfireworks
- Remove unused decorator - #4036 by @maarcingebala
- Overall improvement of the GraphQL performances, especially on single nodes - #3968 @NyanKiyoshi
- Remove unnecessary dedents from GraphQL schema so new Playground can work - #4045 by @salwator
- Add user avatar management - #4030 by @benekex2


Expand Down
2 changes: 1 addition & 1 deletion Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ celery = {version = ">=4.3", extras = ["redis"]}
redis = "<4.0"
kombu = "<5.0.0"
weasyprint = ">=0.42.2"
graphene-django-optimizer = "*"
graphene-django-optimizer = ">=0.4.0"
braintree = "==3.49.0"
razorpay = ">=1.1.1"
stripe = "*"
Expand Down
20 changes: 10 additions & 10 deletions Pipfile.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 10 additions & 10 deletions docs/architecture/payments.rst
Original file line number Diff line number Diff line change
Expand Up @@ -43,19 +43,19 @@ Several payment methods can be used within a single order.

Payment has 5 possible charge statuses:

+--------------------+--------------------+-------------------------------------------------------------------------------------- -----+
| Code | GraphQL API value | Description |
+--------------------+--------------------+--------------------------------------------------------------------------------------------+
+--------------------+--------------------+---------------------------------------------------------------------------------------------+
| Code | GraphQL API value | Description |
+--------------------+--------------------+---------------------------------------------------------------------------------------------+
| not-charged | NOT_CHARGED | No funds were take off the customer's funding source yet. |
+--------------------+--------------------+--------------------------------------------------------------------------------------------+
+--------------------+--------------------+---------------------------------------------------------------------------------------------+
| partially-charged | PARTIALLY_CHARGED | Funds were taken off the customer's funding source, partly covering the payment amount. |
+--------------------+--------------------+--------------------------------------------------------------------------------------------+
+--------------------+--------------------+---------------------------------------------------------------------------------------------+
| fully-charged | FULLY_CHARGED | Funds were taken off the customer's funding source, completely covering the payment amount. |
+--------------------+--------------------+--------------------------------------------------------------------------------------------+
| partially-refunded | PARTIALLY_REFUNDED | Part of charged funds were returned to the customer. |
+--------------------+--------------------+--------------------------------------------------------------------------------------------+
| fully-refunded | FULLY_REFUNDED | All charged funds were returned to the customer. |
+--------------------+--------------------+--------------------------------------------------------------------------------------------+
+--------------------+--------------------+---------------------------------------------------------------------------------------------+
| partially-refunded | PARTIALLY_REFUNDED | Part of charged funds were returned to the customer. |
+--------------------+--------------------+---------------------------------------------------------------------------------------------+
| fully-refunded | FULLY_REFUNDED | All charged funds were returned to the customer. |
+--------------------+--------------------+---------------------------------------------------------------------------------------------+

Transactions
------------
Expand Down
6 changes: 3 additions & 3 deletions requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ autopep8==1.4.4
babel==2.6.0
billiard==3.6.0.0
bleach==2.1.4
boto3==1.9.137
botocore==1.12.137
boto3==1.9.138
botocore==1.12.138
braintree==3.49.0
cairocffi==1.0.2
cairosvg==2.3.1
Expand Down Expand Up @@ -54,7 +54,7 @@ freezegun==0.3.11
google-i18n-address==2.3.4
google-measurement-protocol==1.0.0
gprof2dot==2016.10.13
graphene-django-optimizer==0.3.6
graphene-django-optimizer==0.4.0
graphene-django==2.2.0
graphene==2.1.3
graphql-core==2.1
Expand Down
3 changes: 2 additions & 1 deletion saleor/dashboard/order/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -156,7 +156,8 @@ def order_add_note(request, order_pk):
@permission_required('order.manage_orders')
def capture_payment(request, order_pk, payment_pk):
orders = Order.objects.confirmed().prefetch_related('payments')
order = get_object_or_404(orders, pk=order_pk)
order = get_object_or_404(orders.prefetch_related(
'lines', 'user'), pk=order_pk)
payment = get_object_or_404(order.payments, pk=payment_pk)
amount = order.total.gross
form = CapturePaymentForm(
Expand Down
6 changes: 1 addition & 5 deletions saleor/graphql/account/mutations.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
from textwrap import dedent

import graphene
from django.conf import settings
from django.contrib.auth.tokens import default_token_generator
Expand Down Expand Up @@ -617,14 +615,12 @@ class Arguments:
)

class Meta:
description = dedent(
'''
description = '''
Create a user avatar. Only for staff members. This mutation must
be sent as a `multipart` request. More detailed specs of the
upload format can be found here:
https://github.com/jaydenseric/graphql-multipart-request-spec
'''
)

@classmethod
@staff_member_required
Expand Down
5 changes: 4 additions & 1 deletion saleor/graphql/checkout/mutations.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
from ..account.i18n import I18nMixin
from ..account.types import AddressInput, User
from ..core.mutations import BaseMutation, ModelMutation
from ..core.utils import from_global_id_strict_type
from ..order.types import Order
from ..product.types import ProductVariant
from ..shipping.types import ShippingMethod
Expand Down Expand Up @@ -421,8 +422,10 @@ class Meta:

@classmethod
def perform_mutation(cls, _root, info, checkout_id, shipping_method_id):
checkout = cls.get_node_or_error(
checkout_id = from_global_id_strict_type(
info, checkout_id, only_type=Checkout, field='checkout_id')
checkout = models.Checkout.objects.prefetch_related(
'lines__variant__product__collections').get(pk=checkout_id)
shipping_method = cls.get_node_or_error(
info, shipping_method_id, only_type=ShippingMethod,
field='shipping_method_id')
Expand Down
4 changes: 2 additions & 2 deletions saleor/graphql/core/connection.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import graphene
from graphene import Field, List, NonNull, ObjectType, String
from graphene.relay.connection import Connection
from graphene_django import DjangoObjectType
from graphene_django_optimizer.types import OptimizedDjangoObjectType


class NonNullConnection(Connection):
Expand Down Expand Up @@ -44,7 +44,7 @@ def resolve_total_count(root, *_args, **_kwargs):
return root.length


class CountableDjangoObjectType(DjangoObjectType):
class CountableDjangoObjectType(OptimizedDjangoObjectType):
class Meta:
abstract = True

Expand Down
12 changes: 5 additions & 7 deletions saleor/graphql/core/mutations.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from itertools import chain
from textwrap import dedent
from typing import Tuple

import graphene
Expand Down Expand Up @@ -80,7 +79,6 @@ def __init_subclass_with_meta__(

if not description:
raise ImproperlyConfigured('No description provided in Meta')
description = dedent(description)

if isinstance(permissions, str):
permissions = (permissions, )
Expand Down Expand Up @@ -255,14 +253,14 @@ def clean_input(cls, info, instance, data):

def is_list_of_ids(field):
return (
isinstance(field.type, graphene.List)
and field.type.of_type == graphene.ID)
isinstance(field.type, graphene.List)
and field.type.of_type == graphene.ID)

def is_id_field(field):
return (
field.type == graphene.ID
or isinstance(field.type, graphene.NonNull)
and field.type.of_type == graphene.ID)
field.type == graphene.ID
or isinstance(field.type, graphene.NonNull)
and field.type.of_type == graphene.ID)

def is_upload_field(field):
if hasattr(field.type, 'of_type'):
Expand Down
6 changes: 2 additions & 4 deletions saleor/graphql/core/types/common.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
from textwrap import dedent

import graphene

from ....product.templatetags.product_images import get_thumbnail
Expand All @@ -16,9 +14,9 @@ class CountryDisplay(graphene.ObjectType):

class Error(graphene.ObjectType):
field = graphene.String(
description=dedent("""Name of a field that caused the error. A value of
description="""Name of a field that caused the error. A value of
`null` indicates that the error isn't associated with a particular
field."""), required=False)
field.""", required=False)
message = graphene.String(description='The error message.')

class Meta:
Expand Down
12 changes: 4 additions & 8 deletions saleor/graphql/core/types/money.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
from textwrap import dedent

import graphene
from django_prices.templatetags import prices_i18n

Expand Down Expand Up @@ -39,9 +37,9 @@ class TaxedMoney(graphene.ObjectType):
tax = graphene.Field(Money, description='Amount of taxes.', required=True)

class Meta:
description = dedent("""Represents a monetary value with taxes. In
description = """Represents a monetary value with taxes. In
case when taxes were not applied, net and gross values will be equal.
""")
"""


class TaxedMoneyRange(graphene.ObjectType):
Expand All @@ -60,8 +58,7 @@ class VAT(graphene.ObjectType):
description='Standard VAT rate in percent.')
reduced_rates = graphene.List(
lambda: ReducedRate,
description=dedent('''
Country\'s VAT rate exceptions for specific types of goods.'''),
description='Country\'s VAT rate exceptions for specific types of goods.',
required=True)

class Meta:
Expand All @@ -83,5 +80,4 @@ class ReducedRate(graphene.ObjectType):
rate_type = TaxRateType(description='A type of goods.', required=True)

class Meta:
description = dedent('''
Represents a reduced VAT rate for a particular type of goods.''')
description = 'Represents a reduced VAT rate for a particular type of goods.'
6 changes: 2 additions & 4 deletions saleor/graphql/core/types/upload.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
from textwrap import dedent

import graphene


class Upload(graphene.types.Scalar):

class Meta:
description = dedent('''Variables of this type must be set to null in
description = '''Variables of this type must be set to null in
mutations. They will be replaced with a filename from a following
multipart part containing a binary file. See:
https://github.com/jaydenseric/graphql-multipart-request-spec''')
https://github.com/jaydenseric/graphql-multipart-request-spec'''

@staticmethod
def serialize(value):
Expand Down
11 changes: 11 additions & 0 deletions saleor/graphql/core/utils.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import graphene
from django.core.exceptions import ValidationError


Expand Down Expand Up @@ -26,3 +27,13 @@ def validate_image_file(file, field_name):
"""Validate if the file is an image."""
if not file.content_type.startswith('image/'):
raise ValidationError({field_name: 'Invalid file type'})


def from_global_id_strict_type(info, global_id, only_type, field='id'):
"""Resolve a node global id with a strict given type required."""
_type, _id = graphene.Node.from_global_id(global_id)
graphene_type = info.schema.get_type(_type).graphene_type
if graphene_type != only_type:
raise ValidationError({
field: "Couldn't resolve to a node: %s" % global_id})
return _id
10 changes: 4 additions & 6 deletions saleor/graphql/discount/types.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
from textwrap import dedent

import graphene
import graphene_django_optimizer as gql_optimizer
from graphene import relay
Expand Down Expand Up @@ -41,9 +39,9 @@ class Sale(CountableDjangoObjectType):
resolver=resolve_translation)

class Meta:
description = dedent("""
description = """
Sales allow creating discounts for categories, collections or
products and are visible to all the customers.""")
products and are visible to all the customers."""
interfaces = [relay.Node]
model = models.Sale
only_fields = ['end_date', 'id', 'name', 'start_date', 'type', 'value']
Expand Down Expand Up @@ -88,10 +86,10 @@ class Voucher(CountableDjangoObjectType):
resolver=resolve_translation)

class Meta:
description = dedent("""
description = """
Vouchers allow giving discounts to particular customers on categories,
collections or specific products. They can be used during checkout by
providing valid voucher codes.""")
providing valid voucher codes."""
only_fields = [
'apply_once_per_order', 'code', 'discount_value',
'discount_value_type', 'end_date', 'id', 'min_amount_spent',
Expand Down
16 changes: 8 additions & 8 deletions saleor/graphql/menu/mutations.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
from collections import namedtuple
from textwrap import dedent
from typing import List

import graphene
Expand Down Expand Up @@ -30,9 +29,9 @@ class MenuItemCreateInput(MenuItemInput):
description='Menu to which item belongs to.', name='menu',
required=True)
parent = graphene.ID(
description=dedent('''
description='''
ID of the parent menu. If empty, menu will be top level
menu.'''),
menu.''',
name='parent')


Expand Down Expand Up @@ -66,7 +65,8 @@ def clean_input(cls, info, instance, data):
page = item.get('page')
url = item.get('url')
if len([i for i in [category, collection, page, url] if i]) > 1:
raise ValidationError({'items': 'More than one item provided.'})
raise ValidationError(
{'items': 'More than one item provided.'})

if category:
category = cls.get_node_or_error(
Expand Down Expand Up @@ -124,9 +124,9 @@ class MenuItemCreate(ModelMutation):
class Arguments:
input = MenuItemCreateInput(
required=True,
description=dedent("""Fields required to update a menu item.
description="""Fields required to update a menu item.
Only one of 'url', 'category', 'page', 'collection' is allowed
per item"""))
per item""")

class Meta:
description = 'Creates a new Menu'
Expand All @@ -151,9 +151,9 @@ class Arguments:
required=True, description='ID of a menu item to update.')
input = MenuItemInput(
required=True,
description=dedent("""Fields required to update a menu item.
description="""Fields required to update a menu item.
Only one of 'url', 'category', 'page', 'collection' is allowed
per item"""))
per item""")

class Meta:
description = 'Updates a menu item.'
Expand Down
Loading

0 comments on commit 6477603

Please sign in to comment.