Closed minoxtaurus closed 12 years ago
Ah well, that's correct (of course).
For the moment, you'll have to override Shop.checkout_form
too and provide your own form:
https://gist.github.com/1834813
I'll have to fix the custom
example and document this fact somewhere, too.
Thanks for the report!
Fixed in af13d74268f7baae6d15c50b6694a9625661dd5e
The custom example is working fine now. Many thanks. Best regards,
Rob
[ TIP: You have to grap the latest version of plata ]
Regarding the tip: Yes, of course. We are quickly getting near a 1.0 release containing all these fixes and improvements, though.
Hi Matthias,
Sounds great. I just switched from Django Shop to Plata because of the strange model DS uses for tax (no tax per product but for the whole order ?????)
Concerning shipping, Im still figuring out how to implement different product classes to distinguish physical products (shippable) from digital products (downloadable) and course like products (attendable) and maybe even a product which grants you something (like pre pay)
Still digging...
Best regards
Robert Slotboom
Van Berchemstraat 133 6981 JA Doesburg
T 0313 795055 W studio345.nl
Op 15 feb 2012, om 16:08 heeft Matthias Kestenholz het volgende geschreven:
Regarding the tip: Yes, of course. We are quickly getting near a 1.0 release containing all these fixes and improvements, though.
Reply to this email directly or view it on GitHub: https://github.com/matthiask/plata/issues/14#issuecomment-3981816
You have to add a field to your product to distinguish between these shipping classes; you can of course make this very sophisticated, or very simple:
shipping_class = forms.CharField(choices=(('shippable', 'shippable'), ('downloadable', 'downloadable')), ...)
Your overridden Product.handle_order_item
method (yes, you'll have to override this one) should put the shipping class somewhere into the OrderItem.data
JSON field:
class Product(...):
def handle_order_item(self, item):
super(...)...
data = item.data.copy()
data.update({'shipping_class': self.shipping_class})
item.data = data
# NOTE: Issue #16 will make this dance unnecessary soon
Note: This is required because the product model is not guaranteed to stay the same for old orders. The product foreign key on OrderItem
can even be NULL
-- after all, if the website administrator deletes old products for some reason the orders already in the system must not change.
Next, you'll have to write your own order processor to calculate the shipping total and modify PLATA_ORDER_PROCESSORS
to contain your shipping processor instead of the one that comes with stock Plata.
Probably something like this:
class ShippingProcessor(ProcessorBase):
def process(self, order, items):
classes = [item.data.get('shipping_class') for item in items]
if only 'downloadable':
# set shipping to zero
else:
# do something else
self.set_processor_value('total', 'shipping',
order.shipping_cost - order.shipping_discount + order.shipping_tax)
Finally, if you need a product which "gives you something" (a voucher?) you want to hook into the plata.shop.signals.order_completed
signal which is fired upon order completion (aha! :-) ... meaning that the order has been fully paid for, except if you offer cash-on-delivery) and do something depending on values in OrderItem.data
(again, it's your responsibility to fill the JSON field with something you can work with later -- Plata itself does not do anything with the JSON field on order items.)
Hope this helps somewhat.
Hi Matthias,
Reading and comprehending someone else’s code always takes some time. So I appreciate any help!!!
I was heading for the product subclassing way but adding just an extra field is far more efficient.
The shippingProcessor gets a nice job... Just shippable, just downloadable, just ... or a combination :-) Should be possible to code though.
And regarding the order_completed signal. I already used something similar but for user registration (if user created add userProfile). So this should be fixable too...
There is only one thing that bothers me: class PriceBase "Price for a given product, currency, tax class and time period". I guess tax is related and regulated by the state/country where the shop is located. Shouldn’t the tax field be part of the product then?
(or is this a multi national shopping system :-)
For now I am going to spend my time for some other project (ObjC & iOS) but I’ll return to this matter next week.
Thanks again & have a nice weekend,
Rob
Op 15 feb 2012, om 16:34 heeft Matthias Kestenholz het volgende geschreven:
You have to add a field to your product to distinguish between these shipping classes; you can of course make this very sophisticated, or very simple:
shipping_class = forms.CharField(choices=(('shippable', 'shippable'), ('downloadable', 'downloadable')), ...)
Your overridden
Product.handle_order_item
method (yes, you'll have to override this one) should put the shipping class somewhere into theOrderItem.data
JSON field:def handle_order_item(self, item): super(...)... data = item.data.copy() data.update({'shipping_class': self.shipping_class})
Note: This is required because the product model is not guaranteed to stay the same for old orders. The product foreign key on
OrderItem
can even beNULL
-- after all, if the website administrator deletes old products for some reason the orders already in the system must not change.Next, you'll have to write your own order processor to calculate the shipping total and modify
PLATA_ORDER_PROCESSORS
to contain your shipping processor instead of the one that comes with stock Plata.Probably something like this:
def process(self, order, items): classes = [item.data.get('shipping_class') for item in items] if only 'downloadable': # set shipping to zero else: # do something else self.set_processor_value('total', 'shipping', order.shipping_cost - order.shipping_discount + order.shipping_tax)
Finally, if you need a product which "gives you something" (a voucher?) you want to hook into the
plata.shop.signals.order_completed
signal which is fired upon order completion (aha! :-) ... meaning that the order has been fully paid for, except if you offer cash-on-delivery) and do something depending on values inOrderItem.data
(again, it's your responsibility to fill the JSON field with something you can work with later -- Plata itself does not do anything with the JSON field on order items.)Hope this helps somewhat.
Reply to this email directly or view it on GitHub: https://github.com/matthiask/plata/issues/14#issuecomment-3982307
Hi Rob
On Thu, Feb 16, 2012 at 14:45, minoxtaurus reply@reply.github.com wrote:
There is only one thing that bothers me: class PriceBase "Price for a given product, currency, tax class and time period". I guess tax is related and regulated by the state/country where the shop is located. Shouldn’t the tax field be part of the product then?
(or is this a multi national shopping system :-)
A product can have several prices, one for every currency / tax system or even one for every country if you add a country field to your concrete price class. If the tax field were part of the product, this flexibility would not be possible.
So yes, the tax class is part of the price because Plata supports more than one currency, more than one taxation system and/or more than one country in the same installation.
Best regards Matthias
Hi Mattias,
Ok, I got the point.
Just upgraded from python 2.6 to 2.7 and reinstalled all the stuff. My sample-shop isn’t working anymore due to changes.
I can rewrite some parts but I guess tomorrow you add other changes... So can you give me an estimation of when there will be a kind of stable version?
Cheers,
Rob
Op 16 feb 2012, om 14:57 heeft Matthias Kestenholz het volgende geschreven:
Hi Rob
On Thu, Feb 16, 2012 at 14:45, minoxtaurus reply@reply.github.com wrote:
There is only one thing that bothers me: class PriceBase "Price for a given product, currency, tax class and time period". I guess tax is related and regulated by the state/country where the shop is located. Shouldn’t the tax field be part of the product then?
(or is this a multi national shopping system :-)
A product can have several prices, one for every currency / tax system or even one for every country if you add a country field to your concrete price class. If the tax field were part of the product, this flexibility would not be possible.
So yes, the tax class is part of the price because Plata supports more than one currency, more than one taxation system and/or more than one country in the same installation.
Best regards Matthias
Reply to this email directly or view it on GitHub: https://github.com/matthiask/plata/issues/14#issuecomment-4001032
Hi Rob
I'm really sorry for breaking your code (again). The easiest is to do the following now, after installing South:
'''shell ./manage.py migrate shop 0001 --fake ./manage.py migrate contact 0001 --fake ./manage.py migrate discount 0001 --fake ./manage.py migrate '''
We are only days before a v1.0 release. With the addition of South and with v1.0, backwards-incompatible changes will only happen with very good reasons, with very good documentation and with a big note in the release docs.
Hi Matthias,
Oh no, no apologies; your code, your work. I only wanted to know when things are settling down a bit.
‘Days before’ sounds great because I’m getting to like Plata :-o
The migrations almost worked, had to change the field name in de db myself (will look at that), but it is working again...
Thanks,
Rob
Op 20 feb 2012, om 17:51 heeft Matthias Kestenholz het volgende geschreven:
Hi Rob
I'm really sorry for breaking your code (again). The easiest is to do the following now, after installing South:
''' ./manage.py migrate shop 0001 --fake ./manage.py migrate contact 0001 --fake ./manage.py migrate discount 0001 --fake ./manage.py migrate '''
We are only days before a v1.0 release. With the addition of South and with v1.0, backwards-incompatible changes will only happen with very good reasons, with very good documentation and with a big note in the release docs.
Reply to this email directly or view it on GitHub: https://github.com/matthiask/plata/issues/14#issuecomment-4057185
using examples/custom raises an error
plata/shop/views.py in init, line 300
Check out, fill form, confirm, back to Cart, checkout again.