details:   https://code.tryton.org/tryton/commit/e3cb55f2d8f6
branch:    default
user:      Cédric Krier <[email protected]>
date:      Fri Jan 09 18:31:28 2026 +0100
description:
        Add support for gift card products on Shopify

        Closes #14417
diffstat:

 modules/web_shop/sale.py               |   9 +++++++++
 modules/web_shop/tryton.cfg            |   5 +++++
 modules/web_shop/web.py                |   5 +++++
 modules/web_shop_shopify/CHANGELOG     |   1 +
 modules/web_shop_shopify/doc/usage.rst |  17 +++++++++++++++++
 modules/web_shop_shopify/product.py    |  33 +++++++++++++++++++++++++++++++++
 modules/web_shop_shopify/tryton.cfg    |   6 ++++++
 modules/web_shop_shopify/web.py        |   7 +++++++
 8 files changed, 83 insertions(+), 0 deletions(-)

diffs (175 lines):

diff -r dd98790370ed -r e3cb55f2d8f6 modules/web_shop/sale.py
--- a/modules/web_shop/sale.py  Thu Mar 05 11:48:32 2026 +0100
+++ b/modules/web_shop/sale.py  Fri Jan 09 18:31:28 2026 +0100
@@ -110,3 +110,12 @@
     def web_shop_update(cls, sales):
         for web_shop, s_sales in groupby(sales, lambda s: s.web_shop):
             web_shop.update_sales(list(s_sales))
+
+
+class Line_GiftCard(metaclass=PoolMeta):
+    __name__ = 'sale.line'
+
+    def get_gift_cards(self):
+        if self.sale.web_shop and self.sale.web_shop.is_managing_gift_card:
+            return
+        return super().get_gift_cards()
diff -r dd98790370ed -r e3cb55f2d8f6 modules/web_shop/tryton.cfg
--- a/modules/web_shop/tryton.cfg       Thu Mar 05 11:48:32 2026 +0100
+++ b/modules/web_shop/tryton.cfg       Fri Jan 09 18:31:28 2026 +0100
@@ -14,6 +14,7 @@
     account_tax_rule_country
     product_attribute
     product_image
+    sale_gift_card
     sale_price_list
     sale_shipment_cost
 xml:
@@ -50,6 +51,10 @@
 model:
     product.Image
 
+[register sale_gift_card]
+model:
+    sale.Line_GiftCard
+
 [register sale_price_list]
 model:
     web.Shop_PriceList
diff -r dd98790370ed -r e3cb55f2d8f6 modules/web_shop/web.py
--- a/modules/web_shop/web.py   Thu Mar 05 11:48:32 2026 +0100
+++ b/modules/web_shop/web.py   Fri Jan 09 18:31:28 2026 +0100
@@ -274,6 +274,11 @@
     def update_sales(self, sales):
         assert all(s.web_shop == self for s in sales)
 
+    @property
+    def is_managing_gift_card(self):
+        "Return if the webshop manages gift cards"
+        pass
+
 
 class Shop_PriceList(metaclass=PoolMeta):
     __name__ = 'web.shop'
diff -r dd98790370ed -r e3cb55f2d8f6 modules/web_shop_shopify/CHANGELOG
--- a/modules/web_shop_shopify/CHANGELOG        Thu Mar 05 11:48:32 2026 +0100
+++ b/modules/web_shop_shopify/CHANGELOG        Fri Jan 09 18:31:28 2026 +0100
@@ -1,3 +1,4 @@
+* Add support for gift card products
 * Add support for Python 3.14
 * Remove support for Python 3.9
 * Manage payment terms
diff -r dd98790370ed -r e3cb55f2d8f6 modules/web_shop_shopify/doc/usage.rst
--- a/modules/web_shop_shopify/doc/usage.rst    Thu Mar 05 11:48:32 2026 +0100
+++ b/modules/web_shop_shopify/doc/usage.rst    Fri Jan 09 18:31:28 2026 +0100
@@ -89,3 +89,20 @@
    - ``GET`` ``/<database_name>/web_shop_shopify/customers/<customer id>``
 
    - ``GET`` ``/<database_name>/web_shop_shopify/orders/<order id>``
+
+.. _Setup Gift Cards:
+
+Setup Gift Cards
+================
+
+To use gift cards on Shopify, you must activate the :doc:`*Sale Gift Card
+Module* <sale_gift_card:index>`.
+`Products <sale_gift_card:concept-product>` defined as gift cards are also
+registered as such on Shopify.
+When a gift card is sold on Shopify, no `gift card
+<sale_gift_card:model-sale.gift_card>` is created by the corresponding `sale
+<sale_gift_card:model-sale.sale>` order as these are managed by Shopify.
+When a gift card is redeemed on Shopify, it appears as a payment from the
+``gift_card`` gateway.
+It is recommended that you use this criteria to setup a different `payment 
journal
+<account_payment:model-account.payment.journal>`.
diff -r dd98790370ed -r e3cb55f2d8f6 modules/web_shop_shopify/product.py
--- a/modules/web_shop_shopify/product.py       Thu Mar 05 11:48:32 2026 +0100
+++ b/modules/web_shop_shopify/product.py       Fri Jan 09 18:31:28 2026 +0100
@@ -240,6 +240,24 @@
         return uom
 
 
+class Template_GiftCard(metaclass=PoolMeta):
+    __name__ = 'product.template'
+
+    @classmethod
+    def __setup__(cls):
+        super().__setup__()
+        readonly = cls.gift_card.states.get('readonly', False)
+        cls.gift_card.states['readonly'] = (
+            readonly | Eval('shopify_identifiers', []))
+
+    def get_shopify(self, shop, categories):
+        product = super().get_shopify(shop, categories)
+        if not product.get('id'):
+            # The product gift_card attribute cannot be changed after creation
+            product['giftCard'] = self.gift_card
+        return product
+
+
 class Product(IdentifiersMixin, metaclass=PoolMeta):
     __name__ = 'product.product'
 
@@ -365,6 +383,21 @@
             factor=self.shopify_uom_factor, rate=self.shopify_uom_rate)
 
 
+class Product_GiftCard(metaclass=PoolMeta):
+    __name__ = 'product.product'
+
+    def get_shopify(
+            self, shop, sale_price, sale_tax, price, tax,
+            shop_taxes_included=True):
+        variant = super().get_shopify(
+            shop, sale_price, sale_tax, price, tax,
+            shop_taxes_included=shop_taxes_included)
+        if self.gift_card:
+            # taxable is readonly for gift card on Shopify
+            variant.pop('taxable', None)
+        return variant
+
+
 class ProductURL(metaclass=PoolMeta):
     __name__ = 'product.web_shop_url'
 
diff -r dd98790370ed -r e3cb55f2d8f6 modules/web_shop_shopify/tryton.cfg
--- a/modules/web_shop_shopify/tryton.cfg       Thu Mar 05 11:48:32 2026 +0100
+++ b/modules/web_shop_shopify/tryton.cfg       Fri Jan 09 18:31:28 2026 +0100
@@ -20,6 +20,7 @@
     product_kit
     product_measurements
     sale_discount
+    sale_gift_card
     sale_invoice_grouping
     sale_secondary_unit
     sale_shipment_cost
@@ -92,6 +93,11 @@
 model:
     sale.Line_Discount
 
+[register sale_gift_card]
+model:
+    product.Template_GiftCard
+    product.Product_GiftCard
+
 [register sale_secondary_unit]
 model:
     product.Template_SaleSecondaryUnit
diff -r dd98790370ed -r e3cb55f2d8f6 modules/web_shop_shopify/web.py
--- a/modules/web_shop_shopify/web.py   Thu Mar 05 11:48:32 2026 +0100
+++ b/modules/web_shop_shopify/web.py   Fri Jan 09 18:31:28 2026 +0100
@@ -222,6 +222,13 @@
                 '/%(database_name)s/web_shop_shopify/webhook/%(shop)s/order' %
                 url_part))
 
+    @property
+    def is_managing_gift_card(self):
+        managing = super().is_managing_gift_card
+        if self.type == 'shopify':
+            managing = True
+        return managing
+
     @classmethod
     def view_attributes(cls):
         return super().view_attributes() + [

Reply via email to