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')
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()
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')
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)
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
def __init__(self): self.payment_method_process = PaymentMethodProcess() self.customer_manager = CustomerManager() self.payment_method_manager = PaymentMethodManager()