Why Gemfury? Push, build, and install  RubyGems npm packages Python packages Maven artifacts PHP packages Go Modules Debian packages RPM packages NuGet packages

Repository URL to install this package:

Details    
lib-py-b2b / additional_charge.py
Size: Mime:
import uuid
from decimal import Decimal
from lib_b2b.address import Address
from lib_b2b.discount import Discount
from lib_b2b.order_line import OrderLine
from lib_b2b.shipping import Shipping, ShippingRateType
from lib_b2b.tax_line import TaxLine
from lib_b2b.persistent import Persistable


class AdditionalCharge(Persistable):

    def __init__(self, amount: Decimal, title: str, charge_type: str, value: Decimal, tax_lines: [TaxLine], discounts: [Discount], charge_id: str = None, channel_line_id: str = None):
        if charge_id:
            self.charge_id = charge_id
        else:
            self.charge_id = str(uuid.uuid1())
        self.discounts = discounts
        self.tax_lines = tax_lines
        self.value = value
        self.charge_type = charge_type
        self.title = title
        self.amount = amount or Decimal(0)
        self.channel_line_id = channel_line_id

    @staticmethod
    def create_freight_charges(customer, order_line: OrderLine, ship_to: Address) -> '[AdditionalCharge]':
        """
        If the order line requires freight (not configured with free shipping), create
        an appropriate AdditionalCharge record(s).
        :param customer: the customer account
        :type customer: Customer or str
        :param order_line: the order line
        :type order_line: OrderLine
        :param ship_to: the address where it is being shipped
        :type ship_to: Address
        :return: the additional charge records
        :rtype: [AdditionalCharge]
        """
        from . import profile as pf
        additional_charges = []
        _customer_edi_id = customer if isinstance(customer, str) else customer.get('customer_edi_id')
        profile = pf.Profile.profile_for(_customer_edi_id)
        if not profile.fulfillment_config.free_shipping:
            shipping_rate = Shipping.get_shipping_rate(customer_edi_id=_customer_edi_id,
                                                       postal_code=ship_to.postalCode,
                                                       product_id=order_line.product_id)
            if shipping_rate:
                if shipping_rate.rate_type is ShippingRateType.FIXED_AMOUNT:
                    value = shipping_rate.rate
                else:
                    # percentage of line amount
                    value = order_line.amount * shipping_rate.rate

                for i in range(0, int(order_line.quantity)):
                    ac = AdditionalCharge(
                        amount=shipping_rate.rate,
                        title="FRGT",
                        charge_type="Shipping",
                        value=value,
                        tax_lines=[],
                        discounts=[]
                    )
                    ac.tax_lines = TaxLine.create_for(ac, _customer_edi_id, ship_to)
                    additional_charges.append(ac)
        return additional_charges

    @property
    def recycling(self):
        return self.charge_type == 'Fees'

    @property
    def freight(self):
        return self.charge_type == 'FRGT'

    @staticmethod
    def from_dict(data: dict):
        return AdditionalCharge(
            amount=Decimal(str(data.get('amount'))) if data.get('amount') is not None else Decimal(0),
            title=data.get('title'),
            charge_type=data.get('type'),
            value=Decimal(str(data.get('value'))) if data.get('value') is not None else None,
            tax_lines=list(map(lambda x: TaxLine.from_dict(x), data.get('tax_lines', []))),
            discounts=list(map(lambda x: Discount.from_dict(x), data.get('discounts', []))),
            charge_id=data.get('charge_id', None),
            channel_line_id=data.get('channel_line_id', None)
        )

    def as_dict(self) -> dict:
        return {
            'amount': self.amount,
            'title': self.title,
            'type': self.charge_type,
            'value': self.value,
            'tax_lines': list(map(lambda x: x.as_dict(), self.tax_lines)),
            'discounts': list(map(lambda x: x.as_dict(), self.discounts)),
            'charge_id': self.charge_id,
            'channel_line_id': self.channel_line_id
        }