details:   https://code.tryton.org/tryton/commit/158941e2a9d5
branch:    default
user:      Cédric Krier <[email protected]>
date:      Tue Jun 16 20:40:21 2026 +0200
description:
        Add a refund line for Shopify refund that are not linked to items

        Closes #14875
diffstat:

 modules/web_shop_shopify/sale.py |  85 +++++++++++++++++++++++++++++++++++++++-
 modules/web_shop_shopify/web.py  |   7 ++-
 2 files changed, 89 insertions(+), 3 deletions(-)

diffs (155 lines):

diff -r dfbbbe26ad8e -r 158941e2a9d5 modules/web_shop_shopify/sale.py
--- a/modules/web_shop_shopify/sale.py  Wed Jun 03 15:06:05 2026 +0200
+++ b/modules/web_shop_shopify/sale.py  Tue Jun 16 20:40:21 2026 +0200
@@ -221,6 +221,36 @@
                         'endCursor': None,
                         },
                     },
+                'refundShippingLines(first: 10)': {
+                    'nodes': {
+                        'shippingLine': {
+                            'id': None,
+                            },
+                        },
+                    'pageInfo': {
+                        'hasNextPage': None,
+                        'endCursor': None,
+                        },
+                    },
+                'orderAdjustments(first: 10)': {
+                    'nodes': {
+                        'amountSet': {
+                            'presentmentMoney': {
+                                'amount': None,
+                                },
+                            },
+                        'taxAmountSet': {
+                            'presentmentMoney': {
+                                'amount': None,
+                                },
+                            },
+                        },
+                    },
+                'totalRefundedSet': {
+                    'presentmentMoney': {
+                        'amount': None,
+                        }
+                    },
                 },
             'lineItems(first: 100)': {
                 'nodes': Line.shopify_fields(),
@@ -288,6 +318,11 @@
                     'amount': None,
                     },
                 },
+            'totalRefundedSet': {
+                'presentmentMoney': {
+                    'amount': None,
+                    },
+                },
             'statusPageUrl': None,
             }
 
@@ -374,6 +409,7 @@
             setattr_changed(sale, 'contact', contact_mechanism)
 
         refund_line_items = defaultdict(list)
+        refunded_amount = Decimal(0)
         for refund in order['refunds']:
             shopify_refund_line_items = graphql.iterate(
                 shop, QUERY_REFUND_CURSOR % {
@@ -388,6 +424,9 @@
             for refund_line_item in shopify_refund_line_items:
                 line_item_id = gid2id(refund_line_item['lineItem']['id'])
                 refund_line_items[line_item_id].append(refund_line_item)
+            if refund['orderAdjustments']['nodes']:
+                refunded_amount += Decimal(
+                    refund['totalRefundedSet']['presentmentMoney']['amount'])
 
         line2warehouses = defaultdict(set)
         shopify_fulfillment_orders = graphql.iterate(
@@ -447,8 +486,15 @@
             l.shopify_identifier: l for l in getattr(sale, 'lines', [])
             if l.shopify_identifier}
         shipping_lines = [
-            l for l in getattr(sale, 'lines', []) if not
-            l.shopify_identifier]
+            l for l in getattr(sale, 'lines', [])
+            if l.type == 'line'
+            and not l.shopify_identifier
+            and l.quantity > 0]
+        refund_lines = [
+            l for l in getattr(sale, 'lines', [])
+            if l.type == 'line'
+            and not l.shopify_identifier
+            and l.quantity < 0]
         lines = []
         shopify_line_items = graphql.iterate(
             shop, QUERY_ORDER_CURSOR % {
@@ -497,6 +543,20 @@
             else:
                 line.quantity = 0
             lines.append(line)
+
+        if refund_lines:
+            line = refund_lines[0]
+        else:
+            line = None
+        if refunded_amount or line:
+            line = Line.get_from_shopify_refund(
+                sale, refunded_amount, line=line)
+            lines.append(line)
+        if len(refund_lines) > 1:
+            for line in refund_lines[1:]:
+                line.quantity = 0
+                lines.append(line)
+
         for line in id2line.values():
             line.quantity = 0
             lines.append(line)
@@ -929,6 +989,27 @@
     def _set_shopify_shipping_product(self, sale, shipping_line):
         pass
 
+    @classmethod
+    def get_from_shopify_refund(cls, sale, amount, line=None):
+        pool = Pool()
+        Tax = pool.get('account.tax')
+
+        if not line:
+            line = cls(type='line')
+            line.sale = sale
+            line.product = None
+        line._set_shopify_refund_product(sale)
+        setattr_changed(line, 'quantity', -1)
+        if line._changed_values:
+            line.on_change_product()
+        unit_price = round_price(Tax.reverse_compute(
+                amount, line.taxes, sale.sale_date))
+        setattr_changed(line, 'unit_price', unit_price)
+        return line
+
+    def _set_shopify_refund_product(self, sale):
+        pass
+
     def _get_invoice_line_quantity(self):
         quantity = super()._get_invoice_line_quantity()
         if self.sale.web_shop and self.sale.web_shop.type == 'shopify':
diff -r dfbbbe26ad8e -r 158941e2a9d5 modules/web_shop_shopify/web.py
--- a/modules/web_shop_shopify/web.py   Wed Jun 03 15:06:05 2026 +0200
+++ b/modules/web_shop_shopify/web.py   Tue Jun 16 20:40:21 2026 +0200
@@ -871,8 +871,13 @@
         for sale, order in to_update.items():
             current_total_price = Decimal(
                 order['currentTotalPriceSet']['presentmentMoney']['amount'])
+            total_refunded = sum(
+                l.amount for l in sale.lines
+                if l.type == 'line'
+                and not l.shopify_identifier
+                and l.quantity < 0)
             sale.shopify_tax_adjustment = (
-                current_total_price - sale.total_amount)
+                current_total_price + total_refunded - sale.total_amount)
         Sale.save(to_update.keys())
         Sale.store_cache(to_update.keys())
         Amendment._clear_sale(to_update.keys())

Reply via email to