def test_is_requred(self): f = MultipleFormField(FooForm) with self.assertRaises(ValidationError) as cm: f.clean([]) self.assertEqual( 'Input is required. Expected not empty list but got [].', cm.exception.message)
def test_max_count(self): f = MultipleFormField(FooForm, max_count=2) with self.assertRaises(ValidationError) as cm: f.clean([{'name': 'abcde'}, {'name': 'fghij'}, {'name': 'klmno'}]) self.assertEqual('There needs to be at most 2 items.', cm.exception.message)
def test_min_count(self): f = MultipleFormField(FooForm, min_count=2) with self.assertRaises(ValidationError) as cm: f.clean(['1']) self.assertEqual('There needs to be at least 2 items.', cm.exception.message)
def test_sub_form_validation(self): f = MultipleFormField(FooForm) with self.assertRaises(ValidationError) as cm: f.clean([{'name': ''}]) self.assertIn('[0]', cm.exception.message) self.assertIn('name', cm.exception.message) self.assertIn('This field is required.', cm.exception.message)
def test_sanitation(self): f = MultipleFormField(FooForm) cleaned_data = f.clean([{'name': 'abcde'}, {'name': 'fghij'}]) self.assertEqual(FooForm, type(cleaned_data[0])) self.assertEqual('abcde', cleaned_data[0].cleaned_data['name']) self.assertEqual(FooForm, type(cleaned_data[1])) self.assertEqual('fghij', cleaned_data[1].cleaned_data['name'])
def test_is_not_requred(self): f = MultipleFormField(FooForm, required=False) # should not raise any exception f.clean(None) f.clean([])
class InstalmentPayment(Service): instalment_list_to_pay = MultipleFormField(InstalmentsForms, required=True) # Validaciones que implica la operacion de pagar al solicitane # 1- que la operacion esté financiada # 2- que la operacion tenga suficiente financiamiento para pagar al solicitante y todos los costos asociados # 3- que los costos mas el monto a transferir sean iguales a el monto total de la transferencia # 4- que los costos no sean mayor que el monto a transferir al solicitante def clean(self): cleaned_data = super().clean() list_validation_payment_error = [] for instalment in cleaned_data.get('instalment_list_to_pay'): payer_account_id = instalment.cleaned_data["payer_account_id"] instalment_amount = instalment.cleaned_data["instalment_amount"] fine_amount = instalment.cleaned_data["fine_amount"] instalment_id = instalment.cleaned_data["instalment_id"] pay_date = instalment.cleaned_data['pay_date'] external_operation_id = instalment.cleaned_data['external_operation_id'] payer_posting_amount = Posting.objects.filter(account_id=payer_account_id).aggregate(Sum('amount')) # posting = Posting(account) if payer_posting_amount['amount__sum'] is not None and payer_posting_amount['amount__sum'] >= Decimal( instalment_amount + fine_amount): pass else: instalment_error = { "id": instalment_id, "pay_date": str(pay_date), "message": 'El pagador no tiene monto suficiente para pagar el monto de Cuota ID:' + str( instalment_id) + "- Monto Actual en cuenta pagador:" + str(payer_posting_amount['amount__sum']) } list_validation_payment_error.append(instalment_error) if len(list_validation_payment_error) > 0: sqs = SqsService(json_data={ "result": "NOT-OK", "operation_id": external_operation_id, "instalments": list_validation_payment_error }) sqs.push('sqs_account_engine_instalment_payment_notification') raise forms.ValidationError(list_validation_payment_error) else: return cleaned_data def process(self): # TODO: modificar este valor en duro transaction_type = 6 # Pago de cuotas # Get Data instalments_ok_for_notification=[] for instalment in self.cleaned_data['instalment_list_to_pay']: payer_account_id = instalment.cleaned_data['payer_account_id'] external_operation_id = instalment.cleaned_data['external_operation_id'] instalment_id = instalment.cleaned_data['instalment_id'] instalment_amount = instalment.cleaned_data['instalment_amount'] fine_amount = instalment.cleaned_data['fine_amount'] pay_date = instalment.cleaned_data['pay_date'] asset_type = instalment.cleaned_data['asset_type'] # Get and Process Data # TODO: definir transacción de Pago a solicitante journal_transaction = JournalTransactionType.objects.get(id=transaction_type) to_operation_account = OperationAccount.objects.get(external_account_id=external_operation_id) from_payer_account = Account.objects.get(id=payer_account_id) asset_type = AssetType.objects.get(id=asset_type) # Create Data ################################################################################################################ ################################################################################################################ # Creacion de asiento journal = Journal.objects.create(batch=None, gloss=journal_transaction.description, journal_transaction=journal_transaction) # Descuento a la cuenta de operacion por el monto total posting_from = Posting.objects.create(account=from_payer_account, asset_type=asset_type, journal=journal, amount=(Decimal(instalment_amount + fine_amount ) * -1)) # Asignacion de inversionista a operacion posting_to = Posting.objects.create(account=to_operation_account, asset_type=asset_type, journal=journal, amount=Decimal(instalment_amount + fine_amount )) DwhAccountAmountService.execute( { 'account_id': from_payer_account.id } ) DwhAccountAmountService.execute( { 'account_id': to_operation_account.id } ) instalments_ok_for_notification.append( { "pay_date":str(pay_date), "id":instalment_id } ) # TODO: DEFINIR COLA PARA ENVIAR ENVIAR INFO DE PAGO A SOLICITANTE # #TODO: DEFINIR COLA PARA ENVIAR LA CONFIRMACION DEL PAGO DE LA CUOTA sqs = SqsService(json_data={ "result":"OK", "operation_id":external_operation_id, "instalments": instalments_ok_for_notification, }) sqs.push('sqs_account_engine_instalment_payment_notification') return model_to_dict(journal_transaction)
class RequesterPaymentFromOperation(Service): account = forms.IntegerField(required=True) total_amount = forms.DecimalField(required=True) transfer_amount = forms.DecimalField(required=True) external_operation_id = forms.IntegerField(required=True) asset_type = forms.IntegerField(required=True) requester_costs = MultipleFormField(CostForm, required=False) # Validaciones que implica la operacion de pagar al solicitane # 1- que la operacion esté financiada # 2- que la operacion tenga suficiente financiamiento para pagar al solicitante y todos los costos asociados # 3- que los costos mas el monto a transferir sean iguales a el monto total de la transferencia # 4- que los costos no sean mayor que el monto a transferir al solicitante def clean(self): cleaned_data = super().clean() total_amount = cleaned_data.get("total_amount") transfer_amount = cleaned_data.get("transfer_amount") external_operation_id = cleaned_data.get("external_operation_id") operation_data = OperationAccount.objects.get(external_account_id=external_operation_id) operation_financing_total_amount = Posting.objects.filter(account=operation_data).aggregate(Sum('amount')) # 2- que la operacion tenga suficiente financiamiento para pagar al solicitante y todos los costos asociados if operation_financing_total_amount['amount__sum'] is None or operation_financing_total_amount[ 'amount__sum'] < total_amount: raise forms.ValidationError( "La operacion No tiene Financiamiento suficiente para pagar el total de la transacción") # 3- que los costos mas el monto a transferir sean iguales a el monto total de la transferencia total_amount_cost = 0 #if requester_costs: for requester_cost in cleaned_data.get("requester_costs"): # # asignacion de inversionista a costos cumplo requester_cost_amount = requester_cost.clean() total_amount_cost = total_amount_cost + requester_cost_amount['amount'] if total_amount_cost + transfer_amount != total_amount: raise forms.ValidationError("Los montos no coinciden") # 4- que los costos no sean mayor que el monto a transferir al solicitante if total_amount_cost > transfer_amount: raise forms.ValidationError( "Los costos asociados al pago son mayores que el monto a transferir al solicitante") #5- Validar cuentas bancarias return cleaned_data def process(self): # TODO: modificar este valor en duro transaction_type = 5 # Pago a solicitante # Get Data account = self.cleaned_data['account'] total_amount = self.cleaned_data['total_amount'] transfer_amount = self.cleaned_data['transfer_amount'] external_operation_id = self.cleaned_data['external_operation_id'] requester_costs = self.cleaned_data['requester_costs'] asset_type = self.cleaned_data['asset_type'] # Get and Process Data # TODO: definir transacción de Pago a solicitante journal_transaction = JournalTransactionType.objects.get(id=transaction_type) from_account = OperationAccount.objects.get(external_account_id=external_operation_id) cumplo_operation_bank_account = Account.objects.get(external_account_type_id=4, external_account_id=2) to_requester_account = Account.objects.get(id=account) asset_type = AssetType.objects.get(id=asset_type) # Traigo la cuenta de cumplo asesorias cumplo_cost_account = Account.objects.get(id=CUMPLO_COST_ACCOUNT) # Create Data ################################################################################################################ ################################################################################################################ # TODO: Llamar al modulo de facturación # asignacion de inversionista a costos cumplo total_amount_cost = 0 for requester_cost in requester_costs: total_amount_cost = total_amount_cost + requester_cost.cleaned_data['amount'] if total_amount_cost + transfer_amount != total_amount: raise Exception("Montos totales no coinciden") # Creacion de asiento journal = Journal.objects.create(batch=None, gloss=journal_transaction.description, journal_transaction=journal_transaction) # Descuento a la cuenta de operacion por el monto total posting_from = Posting.objects.create(account=from_account, asset_type=asset_type, journal=journal, amount=(Decimal(total_amount) * -1)) # Asignacion de inversionista a operacion posting_to = Posting.objects.create(account=to_requester_account, asset_type=asset_type, journal=journal, amount=Decimal(transfer_amount)) to_requestor_account_bank = BankAccount.objects.filter( account=to_requester_account).order_by('-updated')[0:1] from_account_bank = BankAccount.objects.filter( account=cumplo_operation_bank_account).order_by('-updated')[0:1] if to_requestor_account_bank.exists(): to_requestor_account_bank = to_requestor_account_bank.get() else: raise Exception("No hay cuenta bancaria registrada para el solicitante. Operación Cancelada!!") if from_account_bank.exists(): from_account_bank = from_account_bank.get() else: raise Exception("No hay cuenta bancaria registrada para la cuenta de operación. Operación Cancelada!!") DwhAccountAmountService.execute( { 'account_id': from_account.id } ) DwhAccountAmountService.execute( { 'account_id': to_requester_account.id } ) # TODO: DEFINIR COLA PARA ENVIAR ENVIAR INFO DE PAGO A SOLICITANTE # if settings.DEBUG and settings.DEBUG != True: # print("Enviando a SQS") # #TODO: DEFINIR COLA PARA ENVIAR LA CONFIRMACION DEL PAGO DE LA CUOTA sqs = SqsService(json_data={ "origin_account": from_account_bank.bank_account_number, "beneficiary_name": to_requestor_account_bank.account_holder_name, "document_number": to_requestor_account_bank.account_holder_document_number, "email": to_requestor_account_bank.account_notification_email, "mesagge": journal_transaction.description, "destination_account": to_requestor_account_bank.bank_account_number, "transfer_amount": str(transfer_amount), "currency_type": "CLP", "paysheet_line_type" : "requestor" }) sqs.push('sqs_account_engine_payment_requestor') return model_to_dict(journal_transaction)
class FinanceOperationByInvestmentTransaction(Service): account = forms.IntegerField(required=True) investment_id = forms.IntegerField(required=True) total_amount = forms.DecimalField(required=True) investment_amount = forms.DecimalField(required=True) investment_costs = MultipleFormField(CostForm, required=False) external_operation_id = forms.IntegerField(required=True) asset_type = forms.IntegerField(required=True) def process(self): # TODO: modificar este valor en duro transaction_type = 4 # Financiamiento de operación por Inversión # Get Data account = self.cleaned_data['account'] investment_id = self.cleaned_data['investment_id'] total_amount = self.cleaned_data['total_amount'] investment_amount = self.cleaned_data['investment_amount'] investment_costs = self.cleaned_data['investment_costs'] external_operation_id = self.cleaned_data['external_operation_id'] asset_type = self.cleaned_data['asset_type'] # Get and Process Data # TODO: definir transacción de financimiento journal_transaction = JournalTransactionType.objects.get(id=transaction_type) from_account = Account.objects.get(id=account) to_operation_account = OperationAccount.objects.get(external_account_id=external_operation_id) asset_type = AssetType.objects.get(id=asset_type) # Traigo la cuenta de cumplo asesorias cumplo_cost_account = Account.objects.get(id=CUMPLO_COST_ACCOUNT) # Create Data ################################################################################################################ ################################################################################################################ # Creacion de asiento journal = Journal.objects.create(batch=None, gloss=journal_transaction.description, journal_transaction=journal_transaction) # Descuento a la cuenta del inversionista posting_from = Posting.objects.create(account=from_account, asset_type=asset_type, journal=journal, amount=(Decimal(total_amount) * -1)) # Asignacion de inversionista a operacion posting_to = Posting.objects.create(account=to_operation_account, asset_type=asset_type, journal=journal, amount=Decimal(investment_amount)) # asignacion de inversionista a costos cumplo if investment_costs: for investment_cost in investment_costs: # asignacion de inversionista a costos cumplo print("investment_cost") # TODO: Llamar al modulo de facturación # if investment_cost.cleaned_data['type'] == 1: # # posting_to = Posting.objects.create(account=cumplo_cost_account, asset_type=asset_type, journal=journal, # amount=Decimal(investment_cost.cleaned_data['amount'])) # # else: # print("Error") DwhAccountAmountService.execute( { 'account_id': from_account.id } ) #if settings.DEBUG and settings.DEBUG != True: print("Enviando a SQS") sqs = SqsService(json_data={"result": True, "message": "TODO OK", "investment_id": investment_id, "investor_type": 1 }) sqs.push('response-engine-pay-investment') # else: # print("No se envia a SQS") return model_to_dict(journal)