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)
Exemple #2
0
    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)
Exemple #3
0
    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)
Exemple #4
0
    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)
Exemple #5
0
    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'])
Exemple #6
0
 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)