class CollectionProcess(Process):

    customer_manager = CustomerManager()

    ######################################################
    # PUBLIC
    ######################################################

    def start_collection_process(self, account_id, start, end):

        (account, start_date,
         end_date) = self._validate_params(account_id, start, end)

        if not account or not start_date or not end_date:
            return None

        process = self.create_process_model(account, 'COLLECTION')
        subprocess = self.create_subprocess_model(process,
                                                  'HARVESTING INVOICE DATA')

        self._start_collection_process(subprocess, account, start_date,
                                       end_date)

        return True

    ######################################################
    # PRIVATE
    ######################################################

    def _start_collection_process(self, subprocess, account, start_date,
                                  end_date):

        sp_id = subprocess.id
        email = account.email

        orders = [
            order.to_dict_for_revenue_report()
            for order in Order.objects.filter(date__gte=start_date,
                                              date__lte=end_date)
        ]

        chain = generate_revenue_report_task.s(
            True, orders, sp_id) | generate_journal_task.s(
                orders, sp_id) | send_collections_email_task.s(email, sp_id)

        chain()

    def _validate_params(self, account_id, start, end):
        try:
            start_date = format_date(start)
            end_date = format_date(end)
        except:
            return (None, None, None)

        account = self.customer_manager.get_account(account_id)

        if not account:
            return (None, None, None)

        return (account, start_date, end_date)
class TestContractingProcess(TestCase):

    customer_manager = CustomerManager()
    contracting_process = ContractingProcess()

    def setUp(self):
        self.dummy_account = self.create_dummy_account()
        self.dummy_contract = self.create_dummy_contract()

    def create_dummy_account(self):
        params = {'channel': 'ONLINE', 'email': '*****@*****.**'}

        return self.customer_manager.store_account(params)

    def create_dummy_contract(self):
        params = {
            'sign_date': '29/05/2013',
            'tos': 'http://contratos.com',
            'start_date': '29/05/2013',
            'account': self.dummy_account
        }

        return self.customer_manager.store_contract(params, self.dummy_account)

    @override_settings(CELERY_EAGER_PROPAGATES_EXCEPTIONS=True,
                       CELERY_ALWAYS_EAGER=True,
                       BROKER_BACKEND='memory')
    def test_valid_salesforce_contracting_process(self):
        fn = self.contracting_process._start_salesforce_contracting_process

        self.contracting_process.start_contracting_process(
            self.dummy_contract, fn)

        bp = BusinessProcess.objects.get(account=self.dummy_account,
                                         name='CONTRACTING')
        sp = SubProcess.objects.get(process=bp, name='NOTIFYING CONTRACT')

        tasks = Task.objects.filter(subprocess=sp)

        self.assertEquals(
            len(tasks), 3,
            'Wrong number of tasks in salesforce contracting process')

    def test_valid_standalone_contracting_process(self):
        fn = self.contracting_process._start_standalone_contracting_process

        self.contracting_process.start_contracting_process(
            self.dummy_contract, fn)

        bp = BusinessProcess.objects.get(account=self.dummy_account,
                                         name='CONTRACTING')
        sp = SubProcess.objects.get(process=bp, name='NOTIFYING CONTRACT')

        tasks = Task.objects.filter(subprocess=sp)

        self.assertEquals(
            len(tasks), 0,
            'Wrong number of tasks in standalone contracting process')
Example #3
0
class BPMonitoringManager:

    customer_manager = CustomerManager()

    ################################################################################
    # PUBLIC METHODS
    ################################################################################

    def get_process_tree(self, account_id):
        processes = self._get_processes_by_user(account_id)

        subprocesses = {}
        tasks = {}

        for process in processes:
            subprocess = self._get_subprocesses_by_process(process)
            subprocesses[process] = subprocess

            for sub in subprocess:
                tasks[sub] = self._get_tasks_by_subprocess(sub)

        args = {
            "processes": processes,
            "subprocesses": subprocesses,
            "tasks": tasks
        }

        return args

    ################################################################################
    # PRIVATE METHODS
    ################################################################################

    def _get_processes_by_user(self, email):
        account = self.customer_manager.get_account(email)

        if not account:
            return []

        processes = BusinessProcess.objects.filter(
            account=account).order_by("start")

        return processes.reverse()

    def _get_subprocesses_by_process(self, process):
        return process.subprocess_set.all()

    def _get_tasks_by_subprocess(self, subprocess):
        return subprocess.task_set.all()
Example #4
0
class BillingAddressController:

    customer_manager = CustomerManager()

    @classmethod
    @transaction.commit_on_success
    @csrf_exempt
    def create(cls, request):
        if request.method != 'POST':
            return ContractController._build_error_response('Invalid HTTP method')

        body   = request.body
        params = simplejson.loads(body)

        billing_address = cls.customer_manager.store_billing_address(params)

        if not billing_address:
            return ContractController._build_error_response('Missing parameters')

        return ContractController._build_ok_response('Billing address updated!')

    @classmethod
    @transaction.commit_on_success
    @csrf_exempt
    def list(cls, request):
        if request.method != 'GET':
            return ContractController._build_error_response('Invalid HTTP method')

        params = request.GET

        email = params.get('account', None)

        if not email:
            return ContractController._build_error_response('Missing account parameter')

        account = cls.customer_manager.get_account(email)

        if not account:
            return ContractController._build_error_response('Invalid account')

        billing_address = cls.customer_manager.get_billing_address(account)

        return ContractController._build_ok_with_data_response('Listing registered billing address', billing_address.to_dict())
class TestPaymentDataAcquisition(TestCase):

    gateways_manager = PaymentGatewayManager()
    customer_manager = CustomerManager()

    payment_method_manager = PaymentMethodManager()

    def setUp(self):
        self.dummy_account         = self.create_dummy_account()
        self.dummy_billing_address = self.create_dummy_billing_address()

    def create_dummy_account(self):
        params = {'channel': 'ONLINE', 'email': '*****@*****.**'}

        return self.customer_manager.store_account(params)

    def create_dummy_billing_address(self):
        params  = { 'email': '*****@*****.**', 'first_name': 'nombre', 'last_name': 'apellidos', 'address': 'direccion',
                    'postal_code': '28393', 'city': 'madrid', 'country': "ES"}

        return self.customer_manager.store_billing_address(params)

    def test_valid_redirection_to_adyen(self):
        self.dummy_billing_address.country = 'BR'
        self.dummy_billing_address.save()

        url = self.gateways_manager.get_payment_gateway_redirect_url(self.dummy_billing_address)

        self.assertTrue(url.startswith('https://test.adyen.com/hpp/pay.shtml'), 'Accounts from BR should redirect to Adyen')

    def test_valid_redirection_to_worldpay(self):
        self.dummy_billing_address.country = 'ES'
        self.dummy_billing_address.save()

        url = self.gateways_manager.get_payment_gateway_redirect_url(self.dummy_billing_address)

        self.assertTrue(url.startswith('https://secure-test.worldpay.com/wcc/dispatcher'), 'Accounts from ES should redirect to WorldPay')

    def test_valid_billing_address_storage(self):
        # Storing number of billing method BEFORE calling
        num_before = len(self.payment_method_manager.get_payment_methods(self.dummy_account, 'PENDING'))

        url = self.gateways_manager.get_payment_gateway_redirect_url(self.dummy_billing_address)

        # Storing number of billing method AFTER calling
        num_after = len(self.payment_method_manager.get_payment_methods(self.dummy_account, 'PENDING'))

        self.assertEqual(num_before, 0, 'No payment method should be registered!')
        self.assertEqual(num_after,  1, '1 payment method should be registered!')

    def test_worldpay_callback_xml(self):
        charger, gateway = self.gateways_manager.get_charger_by_name("WORLDPAY")

        payment_method = self.payment_method_manager.store_payment_method(self.dummy_account, 'c99831a4b9', gateway)

        charger.update_order_status(WORLDPAY_CALLBACK_XML)

        payment_method = self.payment_method_manager.get_payment_methods_by_order_code('c99831a4b9', 'VALIDATED')

        payment_method_dict = payment_method.to_dict()

        self.assertEqual(payment_method_dict['mask'], '5454********5454', 'Mask does not fit')
        self.assertEqual(payment_method_dict['expiration'], '01/2016', 'Expiration date does not fit')
Example #6
0
class ContractController:

    contracting_process = ContractingProcess()
    customer_manager = CustomerManager()

    @classmethod
    @transaction.commit_on_success
    @csrf_exempt
    def create(cls, request):
        if request.method != 'POST':
            return cls._build_error_response('Invalid HTTP method')

        body = request.body
        params = json.loads(body)

        channel = params.get('channel', None)

        if channel not in settings.CHANNELS_TO_MARKET:
            return cls._build_error_response('Invalid channel')

        account = cls.customer_manager.store_account(params)

        if not account:
            return cls._build_error_response('Missing account parameters')

        contract = cls.customer_manager.store_contract(params, account)

        # Starting Contracting process (in this case, STAND ALONE version
        # Async, request doesn't block until process finish
        stand_alone_fn = cls.contracting_process._start_standalone_contracting_process

        cls.contracting_process.start_contracting_process(
            contract, stand_alone_fn)

        return cls._build_ok_response('Contracting process started properly!')

    @classmethod
    def _build_error_response(cls, message):
        error_message = {'result': 'error', 'message': message}

        return HttpResponse(json.dumps(error_message),
                            mimetype="application/json",
                            status=405)

    @classmethod
    def _build_ok_response(cls, message):
        ok_message = {'result': 'ok', 'message': message}

        return HttpResponse(json.dumps(ok_message),
                            mimetype="application/json",
                            status=200)

    @classmethod
    def _build_redirect_response(cls, message, url):
        ok_message = {'result': 'ok', 'message': message, 'url': url}

        return HttpResponse(json.dumps(ok_message),
                            mimetype="application/json",
                            status=200)

    @classmethod
    def _build_ok_with_data_response(cls, message, data):
        ok_message = {'result': 'ok', 'message': message, 'data': data}

        return HttpResponse(json.dumps(ok_message),
                            mimetype="application/json",
                            status=200)
Example #7
0
class PaymentMethodController:

    payment_gateways_manager = PaymentGatewayManager()
    customer_manager = CustomerManager()
    payment_method_manager = PaymentMethodManager()

    @classmethod
    @csrf_exempt
    def list(cls, request):

        if request.method != 'GET':
            return ContractController._build_error_response(
                'Invalid HTTP method')

        params = request.GET

        email = params.get('account', None)

        if not email:
            return ContractController._build_error_response(
                'Missing account parameter')

        account = cls.customer_manager.get_account(email)

        if not account:
            return ContractController._build_error_response('Invalid account')

        payment_methods = cls.payment_method_manager.get_payment_methods(
            account, 'VALIDATED')

        payment_methods = [pm.to_dict() for pm in payment_methods]

        return ContractController._build_ok_with_data_response(
            'Listing registered payment methods', payment_methods)

    @classmethod
    @csrf_exempt
    @transaction.commit_on_success
    def create(cls, request):

        if request.method == 'POST':

            body = request.body
            params = json.loads(body)

            email = params.get('account', None)

            if not email:
                return ContractController._build_error_response(
                    'Missing account parameters')

            account = cls.customer_manager.get_account(email)

            if not account:
                return ContractController._build_error_response(
                    'Invalid account account parameters')

            billing_address = cls.customer_manager.get_billing_address(account)

            if not billing_address:
                return ContractController._build_error_response(
                    'Missing billing address. Add billing address before')

            url = cls.payment_gateways_manager.get_payment_gateway_redirect_url(
                billing_address)

            if not url:
                return ContractController._build_error_response(
                    'Problem with payment gateway')

            return ContractController._build_redirect_response(
                'Redirecting to Payment Gateway', url)
class OrderManager:

    customer_manager = CustomerManager()
    payment_method_manager = PaymentMethodManager()
    order_to_cash_process = OrderToCashProcess()

    def create_order(self, params):

        email = params.get('account', None)
        pm_id = params.get('payment_method', None)
        events = params.get('events', None)

        if not email or not pm_id or not events:
            return None

        account = self.customer_manager.get_account(email)
        payment_method = self.payment_method_manager.get_valid_payment_method(
            pm_id, account)
        billing_address = self.customer_manager.get_billing_address(account)

        if not account or not payment_method:
            return None

        products = [self.get_product(event) for event in events]
        amount = sum([product.price for product in products])

        subs = filter(None, [
            product.create_subscription(account, payment_method)
            for product in products
        ])

        total = amount * 1.20
        vat = total - amount

        currency = 'GBP'
        country = 'ES'
        order_code = compute_uuid()

        order = Order(account=account,
                      payment_method=payment_method,
                      total=total,
                      currency=currency,
                      country=country,
                      order_code=order_code,
                      vat=vat,
                      amount=amount)
        order.save()

        line_items = [
            self.create_line_item(product, event, order)
            for (event, product) in zip(events, products)
        ]

        self.order_to_cash_process.start_online_order_to_cash_process(
            order, line_items, account, billing_address)

        return order

    def get_product(self, event):
        return Product.objects.get(
            code=event['rated_by_billing']['billing_code'])

    def create_line_item(self, product, event, order):
        quantity = event['rated_by_billing'][
            'units'] + event['rated_by_billing']['units'] / 100

        line_item = LineItem(product=product, quantity=quantity, order=order)

        line_item.save()

        return line_item
Example #9
0
 def __init__(self):
     self.payment_method_process = PaymentMethodProcess()
     self.customer_manager = CustomerManager()
     self.payment_method_manager = PaymentMethodManager()