Skip to content

Commit

Permalink
Merge branch '3.1' into fix-adyen-incorrect-payment-captured-amount-3-1
Browse files Browse the repository at this point in the history
  • Loading branch information
korycins committed Jan 10, 2023
2 parents 0e848c2 + 7c80fb7 commit 1b712b7
Show file tree
Hide file tree
Showing 15 changed files with 284 additions and 89 deletions.
3 changes: 3 additions & 0 deletions .github/workflows/pytest.yml
Expand Up @@ -44,8 +44,11 @@ jobs:
restore-keys: |
${{ runner.os }}-pip-
# sphinxcontrib-applehelp added due to https://github.com/coddingtonbear/python-measurement/issues/75.
# To remove once the issue is resolved.
- name: Install dependencies
run: |
python -m pip install sphinxcontrib-applehelp==1.0.2
python -m pip install wheel
python -m pip install -r requirements_dev.txt
Expand Down
2 changes: 1 addition & 1 deletion .pre-commit-config.yaml
Expand Up @@ -15,7 +15,7 @@ repos:
exclude: ^templates/templated_email/compiled/
exclude_types: [svg]

- repo: https://gitlab.com/pycqa/flake8
- repo: https://github.com/PyCQA/flake8
rev: 3.9.2
hooks:
- id: flake8
Expand Down
2 changes: 2 additions & 0 deletions Dockerfile
Expand Up @@ -10,6 +10,8 @@ RUN apt-get -y update \
# Install Python dependencies
COPY requirements_dev.txt /app/
WORKDIR /app
## sphinxcontrib-applehelp installed due to https://github.com/saleor/saleor/issues/11664
RUN pip install sphinxcontrib-applehelp==1.0.2
RUN pip install -r requirements_dev.txt

### Final image
Expand Down
4 changes: 2 additions & 2 deletions package-lock.json

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

2 changes: 1 addition & 1 deletion package.json
@@ -1,6 +1,6 @@
{
"name": "saleor",
"version": "3.1.39",
"version": "3.1.43",
"engines": {
"node": ">=16 <17",
"npm": ">=7"
Expand Down
133 changes: 72 additions & 61 deletions poetry.lock

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion pyproject.toml
@@ -1,6 +1,6 @@
[tool.poetry]
name = "saleor"
version = "3.1.39"
version = "3.1.43"
description = "A modular, high performance, headless e-commerce platform built with Python, GraphQL, Django, and React."
authors = [ "Saleor Commerce <hello@saleor.io>" ]
license = "BSD-3-Clause"
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Expand Up @@ -96,7 +96,7 @@ opentracing==2.4.0 ; python_version >= "3.9" and python_version < "3.10"
packaging==21.3 ; python_version >= "3.9" and python_version < "3.10"
petl==1.7.8 ; python_version >= "3.9" and python_version < "3.10"
phonenumberslite==8.12.48 ; python_version >= "3.9" and python_version < "3.10"
pillow==9.3.0 ; python_version >= "3.9" and python_version < "3.10"
pillow==9.4.0 ; python_version >= "3.9" and python_version < "3.10"
posuto==2022.5.0 ; python_version >= "3.9" and python_version < "3.10"
prices==1.1.0 ; python_version >= "3.9" and python_version < "3.10"
promise==2.3 ; python_version >= "3.9" and python_version < "3.10"
Expand Down
2 changes: 1 addition & 1 deletion requirements_dev.txt
Expand Up @@ -129,7 +129,7 @@ packaging==21.3 ; python_version >= "3.9" and python_version < "3.10"
pathspec==0.9.0 ; python_version >= "3.9" and python_version < "3.10"
petl==1.7.8 ; python_version >= "3.9" and python_version < "3.10"
phonenumberslite==8.12.48 ; python_version >= "3.9" and python_version < "3.10"
pillow==9.3.0 ; python_version >= "3.9" and python_version < "3.10"
pillow==9.4.0 ; python_version >= "3.9" and python_version < "3.10"
platformdirs==2.5.2 ; python_version >= "3.9" and python_version < "3.10"
pluggy==1.0.0 ; python_version >= "3.9" and python_version < "3.10"
posuto==2022.5.0 ; python_version >= "3.9" and python_version < "3.10"
Expand Down
2 changes: 1 addition & 1 deletion saleor/__init__.py
Expand Up @@ -3,7 +3,7 @@
from .celeryconf import app as celery_app

__all__ = ["celery_app"]
__version__ = "3.1.39"
__version__ = "3.1.43"


def patched_print_object(type):
Expand Down
48 changes: 34 additions & 14 deletions saleor/discount/utils.py
Expand Up @@ -14,6 +14,7 @@
cast,
)

from django.conf import settings
from django.db.models import F
from django.utils import timezone
from prices import Money, TaxedMoney
Expand Down Expand Up @@ -100,7 +101,7 @@ def get_product_discounts(
collections: Iterable["Collection"],
discounts: Iterable[DiscountInfo],
channel: "Channel",
variant_id: Optional[int] = None
variant_id: Optional[int] = None,
) -> Iterator[Tuple[int, Callable]]:
"""Return sale ids, discount values for all discounts applicable to a product."""
product_collections = set(pc.id for pc in collections)
Expand All @@ -120,7 +121,7 @@ def get_sale_id_with_min_price(
collections: Iterable["Collection"],
discounts: Optional[Iterable[DiscountInfo]],
channel: "Channel",
variant_id: Optional[int] = None
variant_id: Optional[int] = None,
) -> Tuple[Optional[int], Money]:
"""Return a sale_id and minimum product's price."""
available_discounts = [
Expand Down Expand Up @@ -150,7 +151,7 @@ def calculate_discounted_price(
collections: Iterable["Collection"],
discounts: Optional[Iterable[DiscountInfo]],
channel: "Channel",
variant_id: Optional[int] = None
variant_id: Optional[int] = None,
) -> Money:
"""Return minimum product's price of all prices with discounts applied."""
if discounts:
Expand All @@ -172,7 +173,7 @@ def get_sale_id_applied_as_a_discount(
collections: Iterable["Collection"],
discounts: Optional[Iterable[DiscountInfo]],
channel: "Channel",
variant_id: Optional[int] = None
variant_id: Optional[int] = None,
) -> Optional[int]:
"""Return an ID of Sale applied to product."""
if not discounts:
Expand Down Expand Up @@ -257,11 +258,15 @@ def get_products_voucher_discount(
return total_amount


def fetch_categories(sale_pks: Iterable[str]) -> Dict[int, Set[int]]:
def fetch_categories(
sale_pks: Iterable[str],
database_connection_name: str = settings.DATABASE_CONNECTION_DEFAULT_NAME,
) -> Dict[int, Set[int]]:
from ..product.models import Category

categories = (
Sale.categories.through.objects.filter(sale_id__in=sale_pks)
Sale.categories.through.objects.using(database_connection_name)
.filter(sale_id__in=sale_pks)
.order_by("id")
.values_list("sale_id", "category_id")
)
Expand All @@ -278,9 +283,13 @@ def fetch_categories(sale_pks: Iterable[str]) -> Dict[int, Set[int]]:
return subcategory_map


def fetch_collections(sale_pks: Iterable[str]) -> Dict[int, Set[int]]:
def fetch_collections(
sale_pks: Iterable[str],
database_connection_name: str = settings.DATABASE_CONNECTION_DEFAULT_NAME,
) -> Dict[int, Set[int]]:
collections = (
Sale.collections.through.objects.filter(sale_id__in=sale_pks)
Sale.collections.through.objects.using(database_connection_name)
.filter(sale_id__in=sale_pks)
.order_by("id")
.values_list("sale_id", "collection_id")
)
Expand All @@ -290,9 +299,13 @@ def fetch_collections(sale_pks: Iterable[str]) -> Dict[int, Set[int]]:
return collection_map


def fetch_products(sale_pks: Iterable[str]) -> Dict[int, Set[int]]:
def fetch_products(
sale_pks: Iterable[str],
database_connection_name: str = settings.DATABASE_CONNECTION_DEFAULT_NAME,
) -> Dict[int, Set[int]]:
products = (
Sale.products.through.objects.filter(sale_id__in=sale_pks)
Sale.products.through.objects.using(database_connection_name)
.filter(sale_id__in=sale_pks)
.order_by("id")
.values_list("sale_id", "product_id")
)
Expand All @@ -302,9 +315,13 @@ def fetch_products(sale_pks: Iterable[str]) -> Dict[int, Set[int]]:
return product_map


def fetch_variants(sale_pks: Iterable[str]) -> Dict[int, Set[int]]:
def fetch_variants(
sale_pks: Iterable[str],
database_connection_name: str = settings.DATABASE_CONNECTION_DEFAULT_NAME,
) -> Dict[int, Set[int]]:
variants = (
Sale.variants.through.objects.filter(sale_id__in=sale_pks)
Sale.variants.through.objects.using(database_connection_name)
.filter(sale_id__in=sale_pks)
.order_by("id")
.values_list("sale_id", "productvariant_id")
)
Expand All @@ -316,9 +333,12 @@ def fetch_variants(sale_pks: Iterable[str]) -> Dict[int, Set[int]]:

def fetch_sale_channel_listings(
sale_pks: Iterable[str],
database_connection_name: str = settings.DATABASE_CONNECTION_DEFAULT_NAME,
):
channel_listings = SaleChannelListing.objects.filter(sale_id__in=sale_pks).annotate(
channel_slug=F("channel__slug")
channel_listings = (
SaleChannelListing.objects.using(database_connection_name)
.filter(sale_id__in=sale_pks)
.annotate(channel_slug=F("channel__slug"))
)
channel_listings_map: Dict[int, Dict[str, SaleChannelListing]] = defaultdict(dict)
for channel_listing in channel_listings:
Expand Down
12 changes: 7 additions & 5 deletions saleor/graphql/discount/dataloaders.py
Expand Up @@ -33,11 +33,13 @@ def batch_load(self, keys):
for datetime in keys
}
pks = {s.pk for d, ss in sales_map.items() for s in ss}
collections = fetch_collections(pks)
channel_listings = fetch_sale_channel_listings(pks)
products = fetch_products(pks)
categories = fetch_categories(pks)
variants = fetch_variants(pks)
collections = fetch_collections(pks, self.database_connection_name)
channel_listings = fetch_sale_channel_listings(
pks, self.database_connection_name
)
products = fetch_products(pks, self.database_connection_name)
categories = fetch_categories(pks, self.database_connection_name)
variants = fetch_variants(pks, self.database_connection_name)

return [
[
Expand Down
1 change: 1 addition & 0 deletions saleor/payment/gateways/adyen/plugin.py
Expand Up @@ -642,6 +642,7 @@ def confirm_payment(
error=None,
raw_response={},
transaction_already_processed=bool(transaction_already_processed),
psp_reference=token,
)

@require_active_plugin
Expand Down
Expand Up @@ -159,6 +159,45 @@ def test_handle_additional_actions_handles_return_urls(
assert response.status_code == 302


@mock.patch("saleor.payment.gateways.adyen.webhooks.api_call")
def test_handle_additional_actions_sets_psp_reference(
api_call_mock, payment_adyen_for_checkout, adyen_plugin
):
# given
plugin = adyen_plugin()
channel_slug = plugin.channel.slug
payment_adyen_for_checkout.to_confirm = True
payment_adyen_for_checkout.extra_data = json.dumps(
{"payment_data": "test_data", "parameters": ["payload"]}
)
payment_adyen_for_checkout.save(update_fields=["to_confirm", "extra_data"])

checkout = payment_adyen_for_checkout.checkout
payment_id = graphene.Node.to_global_id("Payment", payment_adyen_for_checkout.pk)

request_mock = mock.Mock()
request_mock.GET = {
"payment": payment_id,
"checkout": str(checkout.pk),
"payload": "test",
}

expected_psp_reference = "psp-11111"
payment_details_mock = mock.Mock()
message = {
"pspReference": expected_psp_reference,
"resultCode": "authorised",
}
api_call_mock.return_value.message = message

# when
handle_additional_actions(request_mock, payment_details_mock, channel_slug)

# then
payment_adyen_for_checkout.refresh_from_db()
assert payment_adyen_for_checkout.psp_reference == expected_psp_reference


@mock.patch("saleor.payment.gateways.adyen.webhooks.api_call")
def test_handle_additional_actions_get(
api_call_mock, payment_adyen_for_checkout, adyen_plugin
Expand Down

0 comments on commit 1b712b7

Please sign in to comment.