Repository URL to install this package:
|
Version:
0.4.194 ▾
|
lib-py-b2b
/
order_totals.py
|
|---|
from decimal import Decimal
from lib_b2b.additional_charge import AdditionalCharge
from lib_b2b.discount import Discount
from lib_b2b.order_line import OrderLine
from lib_b2b.persistent import Persistable
from lib_b2b.refund import Refund
class OrderTotals(Persistable):
@classmethod
def calculate(cls, order_lines: [OrderLine], discounts: [Discount], additional_charges: [AdditionalCharge], refunds: [Refund]) -> 'OrderTotals':
_total_line_amount = cls.__calculate_total_line_amount(order_lines)
_total_discount = cls.__calculate_total_discount(order_lines, discounts)
_total_additional_charges = cls.__calculate_total_additional_charges(additional_charges)
_total_tax = cls.__calculate_total_tax(order_lines, additional_charges)
_total_refund = cls.__calculate_total_refund(refunds)
_total_amount = _total_line_amount + _total_tax + _total_additional_charges - _total_discount
_total_net = _total_amount - _total_refund
return OrderTotals(
total_amount=_total_amount,
total_line_amount=_total_line_amount,
total_discount=_total_discount,
total_additional_charges=_total_additional_charges,
total_tax=_total_tax,
total_refund=_total_refund,
total_net=_total_net
)
@classmethod
def create(cls, order_lines: [OrderLine], discounts: [Discount],
additional_charges: [AdditionalCharge], refunds: [Refund],
total_amount: Decimal = None, total_line_amount: Decimal = None,
total_tax: Decimal = None, total_discount: Decimal = None,
total_additional_charges: Decimal = None, total_refund: Decimal = None,
total_net: Decimal = None
) -> 'OrderTotals':
_total_line_amount = total_line_amount or cls.__calculate_total_line_amount(order_lines)
_total_discount = total_discount or cls.__calculate_total_discount(order_lines, discounts)
_total_additional_charges = total_additional_charges \
or cls.__calculate_total_additional_charges(additional_charges)
_total_tax = total_tax or cls.__calculate_total_tax(order_lines, additional_charges)
_total_refund = total_refund or cls.__calculate_total_refund(refunds)
_total_amount = total_amount or (_total_line_amount + _total_tax + _total_additional_charges - _total_discount)
_total_net = total_net or (_total_amount - _total_refund)
return OrderTotals(
total_amount=_total_amount,
total_line_amount=_total_line_amount,
total_discount=_total_discount,
total_additional_charges=_total_additional_charges,
total_tax=_total_tax,
total_refund=_total_refund,
total_net=_total_net
)
@staticmethod
def __calculate_total_discount(order_lines: [OrderLine], discounts: [Discount]):
_total_discount = sum([x.amount or 0 for x in discounts or []])
for line in order_lines:
_total_discount += sum([x.amount or 0 for x in line.discounts or []])
return _total_discount
@staticmethod
def __calculate_total_refund(refunds: [Refund]):
return sum(x.amount or 0 for x in refunds or [])
@staticmethod
def __calculate_total_line_amount(order_lines: [OrderLine]):
return sum(x.amount or 0 for x in order_lines or [])
@staticmethod
def __calculate_total_tax(order_lines: [OrderLine], additional_charges: [AdditionalCharge]):
_total_tax = sum(t.amount or 0 for l in order_lines for t in l.tax_lines or [])
_total_tax += sum(t.amount or 0 for a in additional_charges or [] for t in a.tax_lines or [])
return _total_tax
@staticmethod
def __calculate_total_additional_charges(additional_charges: [AdditionalCharge]):
return sum(a.amount or 0 for a in additional_charges or [])
def __init__(self, total_amount: Decimal, total_line_amount: Decimal,
total_tax: Decimal, total_discount: Decimal,
total_additional_charges: Decimal, total_refund: Decimal,
total_net: Decimal):
self.total_net = total_net
self.total_refund = total_refund
self.total_additional_charges = total_additional_charges
self.total_discount = total_discount
self.total_tax = total_tax
self.total_line_amount = total_line_amount
self.total_amount = total_amount
@staticmethod
def from_dict(data: dict):
return OrderTotals(
total_amount=Decimal(str(data.get('total_amount', 0))),
total_additional_charges=Decimal(str(data.get('total_additional_charges', 0))),
total_discount=Decimal(str(data.get('total_discount', 0))),
total_line_amount=Decimal(str(data.get('total_line_amount', 0))),
total_tax=Decimal(str(data.get('total_tax', 0))),
total_refund=Decimal(str(data.get('total_refund', 0))),
total_net=Decimal(str(data.get('total_net', 0))),
)
def as_dict(self) -> dict:
return vars(self)
def __eq__(self, o: object) -> bool:
if isinstance(o, OrderTotals):
other: OrderTotals = o
return self.total_amount == other.total_amount \
and self.total_line_amount == other.total_line_amount \
and self.total_discount == other.total_discount \
and self.total_tax == other.total_tax \
and self.total_additional_charges == other.total_additional_charges \
and self.total_refund == other.total_refund \
and self.total_net == other.total_net
else:
return super().__eq__(o)
def __ne__(self, o: object) -> bool:
return not self.__eq__(o)