コード例 #1
0
 def __init__(self, order):
     self._order = order
     self._price_resolver = PriceResolver()
     self.charging_processors = {
         'initial': self._process_initial_charge,
         'recurring': self._process_renovation_charge,
         'usage': self._process_use_charge
     }
     self.end_processors = {
         'initial': self._end_initial_charge,
         'recurring': self._end_renovation_charge,
         'usage': self._end_use_charge
     }
コード例 #2
0
    def resolve_charging(self, new_purchase=False, sdr=False):

        # Check if there is a new purchase
        if new_purchase:
            # Create the contract
            self._create_purchase_contract()
            charge = False
            related_model = {}

            # Check if there are price parts different from pay per use
            if 'single_payment' in self._price_model:
                charge = True
                related_model['single_payment'] = self._price_model[
                    'single_payment']

            if 'subscription' in self._price_model:
                charge = True
                related_model['subscription'] = self._price_model[
                    'subscription']

            price = 0
            if charge:
                # Call the price resolver
                resolver = PriceResolver()
                price = resolver.resolve_price(related_model)

                # Check user expenditure limits and accumulated balance
                self._check_expenditure_limits(price)

                # Make the charge
                redirect_url = self._charge_client(
                    price, 'initial charge',
                    self._price_model['general_currency'])
            else:
                # If it is not necessary to charge the customer the state is set to paid
                self._purchase.state = 'paid'

            if self._purchase.state == 'paid':
                self.end_charging(price, 'initial charge', related_model)
            else:
                price = self._fix_price(price)
                self._purchase.contract.pending_payment = {
                    'price': price,
                    'concept': 'initial charge',
                    'related_model': related_model
                }
                self._purchase.contract.save()
                return redirect_url

        else:
            self._price_model = self._purchase.contract.pricing_model
            self._purchase.state = 'pending'
            self._purchase.save()

            # If not SDR received means that the call is a renovation
            if not sdr:
                # Determine the price parts to renovate
                if 'subscription' not in self._price_model:
                    raise Exception('No subscriptions to renovate')

                related_model = {'subscription': []}

                now = datetime.now()
                unmodified = []

                for s in self._price_model['subscription']:
                    renovation_date = s['renovation_date']

                    if renovation_date < now:
                        related_model['subscription'].append(s)
                    else:
                        unmodified.append(s)

                accounting_info = None
                # If pending SDR documents resolve the use charging
                if len(self._purchase.contract.pending_sdrs) > 0:
                    related_model['pay_per_use'] = self._price_model[
                        'pay_per_use']
                    accounting_info = []
                    accounting_info.extend(
                        self._purchase.contract.pending_sdrs)

                # If deductions have been included resolve the discount
                if 'deductions' in self._price_model and len(
                        self._price_model['deductions']) > 0:
                    related_model['deductions'] = self._price_model[
                        'deductions']

                resolver = PriceResolver()
                price = resolver.resolve_price(related_model, accounting_info)

                # Deductions can make the price 0
                if price > 0:
                    # If not use made, check expenditure limits and accumulated balance
                    if not accounting_info:
                        self._check_expenditure_limits(price)

                    redirect_url = self._charge_client(
                        price, 'Renovation',
                        self._price_model['general_currency'])

                if len(unmodified) > 0:
                    related_model['unmodified'] = unmodified

                # Check if applied accounting info is needed to finish the purchase
                applied_accounting = None
                if accounting_info:
                    applied_accounting = resolver.get_applied_sdr()

                if self._purchase.state == 'paid':
                    self.end_charging(price, 'Renovation', related_model,
                                      applied_accounting)
                else:
                    price = self._fix_price(price)
                    pending_payment = {
                        'price': price,
                        'concept': 'Renovation',
                        'related_model': related_model
                    }

                    # If some accounting has been used include it to be saved
                    if accounting_info:
                        pending_payment['accounting'] = applied_accounting

                    self._purchase.contract.pending_payment
                    self._purchase.contract.save()
                    return redirect_url

            # If sdr is true means that the call is a request for charging the use
            # made of a service.
            else:
                # Aggregate the calculated charges
                pending_sdrs = []
                pending_sdrs.extend(self._purchase.contract.pending_sdrs)

                if len(pending_sdrs) == 0:
                    raise Exception('No SDRs to charge')

                related_model = {
                    'pay_per_use': self._price_model['pay_per_use']
                }

                if 'deductions' in self._price_model and len(
                        self._price_model['deductions']) > 0:
                    related_model['deductions'] = self._price_model[
                        'deductions']

                resolver = PriceResolver()
                price = resolver.resolve_price(related_model, pending_sdrs)
                # Charge the client

                # Deductions can make the price 0
                if price > 0:
                    redirect_url = self._charge_client(
                        price, 'Pay per use',
                        self._price_model['general_currency'])

                applied_accounting = resolver.get_applied_sdr()

                if self._purchase.state == 'paid':
                    self.end_charging(price, 'pay per use', related_model,
                                      applied_accounting)
                else:
                    price = self._fix_price(price)
                    self._purchase.contract.pending_payment = {
                        'price': price,
                        'concept': 'pay per use',
                        'related_model': related_model,
                        'accounting': applied_accounting
                    }
                    self._purchase.contract.save()
                    return redirect_url