2

When adding a product to the basket, our customer is presented with an optional customiser app which works roughly in this way:

  • for each product (if the quantity is greater than one) be able to add a personalised name
  • for all products, add personalised decals in various positions on the product
  • decals are uploaded by the customer, and there's a one-time extra charge if the decal is not in SVG format
  • etc...

I have already built the models and calculator which calculates just the above customisation portion of a product. The customiser app is a Vue.js app which sits on the product detail page, and via an API creates a JSON blob that represents the complex customisation, keyed against the user, basket, and product IDs, and the calculator parses this JSON blob to get a price for the customisation, which excludes the product price.

Next up is figuring out how to

  • render the customisation cost separate from the product price on the basket line item
  • include the customisation cost as part of the product total, and ultimately the basket total

It seems like neither variants nor attributes make sense in this case, but a oscar.apps.catalogue.abstract_models.AbstractOption does. From the pydoc:

An option that can be selected for a particular item when the product is added to the basket.

For example, a list ID for an SMS message send, or a personalised message to print on a T-shirt.

This is not the same as an 'attribute' as options do not have a fixed value for a particular item. Instead, option need to be specified by a customer when they add the item to their basket.

The "personalised message" on my "T-shirt" can be the customisation JSON blob which is actioned by the warehouse staff before the item is shipped.

However, it doesn't seem like an option affects the price. How can I attach a dynamic price to an option? In a strategy? Or is there another way to achieve this?

opyate
  • 5,388
  • 1
  • 37
  • 64

1 Answers1

2

Paid product options are not currently supported out of the box in Oscar (see the relevant ticket), but it is possible to implement relatively easily by forking a couple of Oscar apps, and (broadly) doing the following:

  1. Create a model for storing the price of an option for a given product (or, if the price is the same for all products for an given option, store it on the Option model itself).

  2. Override the Strategy class methods fetch_for_line and fetch_for_product to pass the options from the line through to the logic that returns a pricing strategy - override this to look up the price for that option and add it to the base price.

This basic implementation only requires overriding a couple of methods in the Strategy, and then storing your prices in a model somewhere. There is room for additional complexity - e.g., if options are mandatory and affect the minimum price, you may want to display that minimum price in search results etc.

solarissmoke
  • 30,039
  • 14
  • 71
  • 73