Add support for gift card products on Shopify

Closes #14417
This commit is contained in:
Cédric Krier
2026-01-09 18:31:28 +01:00
parent af646f2d25
commit f9cfa0c422
8 changed files with 83 additions and 0 deletions
+9
View File
@@ -110,3 +110,12 @@ class Sale(metaclass=PoolMeta):
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()
+5
View File
@@ -14,6 +14,7 @@ extras_depend:
account_tax_rule_country
product_attribute
product_image
sale_gift_card
sale_price_list
sale_shipment_cost
xml:
@@ -50,6 +51,10 @@ model:
model:
product.Image
[register sale_gift_card]
model:
sale.Line_GiftCard
[register sale_price_list]
model:
web.Shop_PriceList
+5
View File
@@ -274,6 +274,11 @@ class Shop(DeactivableMixin, ModelSQL, ModelView):
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'
+1
View File
@@ -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
+17
View File
@@ -89,3 +89,20 @@ You can use these links to create an `admin link extension
- ``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>`.
+33
View File
@@ -240,6 +240,24 @@ class Template_SaleSecondaryUnit(metaclass=PoolMeta):
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 @@ class Product(IdentifiersMixin, metaclass=PoolMeta):
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'
+6
View File
@@ -20,6 +20,7 @@ extras_depend:
product_kit
product_measurements
sale_discount
sale_gift_card
sale_invoice_grouping
sale_secondary_unit
sale_shipment_cost
@@ -92,6 +93,11 @@ model:
model:
sale.Line_Discount
[register sale_gift_card]
model:
product.Template_GiftCard
product.Product_GiftCard
[register sale_secondary_unit]
model:
product.Template_SaleSecondaryUnit
+7
View File
@@ -222,6 +222,13 @@ class Shop(metaclass=PoolMeta):
'/%(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() + [