OK. How to do it?
I think that more people wants better performance in their situations
(when you read this forum) and reliability than extending the
complexity.
The name by_product_and_price sounds redundant, hmm, but it is not.It
can be useful because price calculation is an expensive operation and
should not be unnecessarily repeated. It is also useful to keep tax
modules and discount methods independent and preferably simple. Method
by_product is not usable for undiscounted prices. Method get_rate
looks universal and it is basic method for two complicated tax
processors, but it should be internal method because it is not known
out of tax processor which context parameters are mandatory for that
processor.
Why are too much tax.by_* methods? May have been attempts to solve
rounding problems with 2 decimal places arithmetics with specialized
methods for one and total. Finally, it was decided at commit 166 three
years ago to save all 10 decimal places. Then it became less
important. It was before issues history.
> So patching Satchmo to change those calls shouldn't mean
> any disruption to people using those processors.
How do you ensure it? How will the new method by_product_and_price
help you ?
The big problem is with functions which depends on taxer and call only
by_price:
shop.models.OrderItem.update_tax
payment.forms._get_shipping_choices
product.utils.productvariation_details
(All 3 templatetags satchmo_discounts.taxed_* can be eventually
replaced without changing Satchmo or templates.)
Some deep stored methods depends on it.
shop.models.OrderItem.save
product.modules.configurable.models.Configurable.add_template_context
payment.forms.SimplePayShipForm.__init__
Also product itself depends on that. This does look nice at all.
Normal fuction can be dirty patched in a private project by
manipulation with sys.models['modelname'].__dict__['function_name'],
but to do it with django.db.models children would be a harakiri.
This is a mystery now
if self.product.taxable:
self.unit_tax = processor.by_price(taxclass,
self.unit_price)
self.tax = processor.by_orderitem(self)
After you verify internals and simplify existing tax processors it can
be probably also simplified without by_orderitem and make it
deprecated.
These approximately 6 lines with by_price can be replaced by:
- .... taxer.by_price(product.taxClass, price)
+ if hasattr(taxer, 'need_product_detail'):
+ .... price * taxer.get_rate(product=product)
+ else:
+ .... taxer.by_price(product.taxClass, price)
and you can use it soon.
While it will not make any problems some time (exactly the same
results, speed, database queries and memory requirements for normal
taxed projects), it can be something done to be eventually unified in
BaseProcessor and some redundant methods declared as deprecated and
not used in a new development.