Beispiel #1
0
 def post(self, request):
     serializer = AllowedGuaranteeRequestSerializer(data=request.data)
     if serializer.is_valid():
         allowed = serializer.validated_data['allow_public_guarantees']
         circle, member = Circle.objects.get(
             circle_acc_number=serializer.
             validated_data['circle_acc_number']), request.user.member
         if allowed == 'true':
             try:
                 circle_member = CircleMember.objects.get(circle=circle,
                                                          member=member)
                 CircleMember.objects.filter(
                     circle=circle, member=member).update(
                         allow_public_guarantees_request=True)
                 AllowedGuarantorRequest.objects.filter(
                     circle_member=circle_member).delete()
             except Exception as e:
                 print(str(e))
                 CircleMember.objects.filter(
                     circle=circle, member=member).update(
                         allow_public_guarantees_request=False)
                 data = {
                     "status": 0,
                     "message":
                     "Unable to change allowed guarantees setting"
                 }
                 return Response(data, status=status.HTTP_200_OK)
             fcm_data = {
                 "request_type": "UPDATE_ALLOW_GUARANTOR_REQUEST",
                 "circle_acc_number": circle.circle_acc_number,
                 "phone_number": member.phone_number,
                 "allow_guarantor_request": True
             }
             fcm_instance = fcm_utils.Fcm()
             registration_ids = fcm_instance.get_circle_members_token(
                 circle, member)
             fcm_instance.data_push("multiple", registration_ids, fcm_data)
             print(fcm_data)
             updating_loan_limit.delay(circle.id, member.id)
             data = {"status": 1}
             return Response(data, status=status.HTTP_200_OK)
         fcm_instance = fcm_utils.Fcm()
         registration_ids = fcm_instance.get_circle_members_token(
             circle, member)
         fcm_data = {
             "request_type": "UPDATE_ALLOW_GUARANTOR_REQUEST",
             "circle_acc_number": circle.circle_acc_number,
             "phone_number": member.phone_number,
             "allow_guarantor_request": False
         }
         fcm_instance.data_push("multiple", registration_ids, fcm_data)
         print(fcm_data)
         updating_loan_limit.delay(circle.id, member.id)
         CircleMember.objects.filter(
             circle=circle,
             member=member).update(allow_public_guarantees_request=False)
         data = {"status": 1}
         return Response(data, status=status.HTTP_200_OK)
     data = {"status": 0, "message": serializer.errors}
     return Response(data, status=status.HTTP_200_OK)
Beispiel #2
0
    def send_chat_to_all_members(message, message_channel):
        if message_channel == 1:
            instance = fcm_utils.Fcm()
            device_tokens = Member.objects.all().values_list('device_token',
                                                             flat=True)

            fcm_data = {
                'request_type': 'REPLY_TO_CHAT',
                'sender': 'Opencircles',
                'body': message,
                'time_sent':
                datetime.datetime.now().strftime('%Y-%m-%d %H-%m-%s')
            }

            members = Member.objects.all()
            for obj in members:
                Chat(sender='Opencircles',
                     recipient='SELF',
                     body=message,
                     owner=obj,
                     time_chat_sent=datetime.datetime.now(),
                     has_been_responded_to=True).save()
            try:
                instance.data_push("multiple", device_tokens, fcm_data)
                return True
            except:
                return False
        else:
            member_phone_numbers = Member.objects.all().values_list(
                'phone_number', flat=True)
            phone_numbers = ','.join(member_phone_numbers)
            print(phone_numbers)
            response, unsent = sms_utils.Sms().sendmultiplesms(
                phone_numbers, message)
            return response
    def delete_inactive_circles(self):
        current_time = datetime.datetime.now().date()

        initiated_time = current_time - relativedelta(days=90)

        circles = CircleModel.objects.filter(
            ~Q(time_initiated__range=[initiated_time, current_time])
            & Q(is_active=False))

        # for every circle to be deleted get the circle members
        circle_members = CircleMember.objects.filter(circle__in=circles)

        # for every circle member get their shares
        member_shares = Shares.objects.filter(circle_member__in=circle_members)

        # for every shares get the transaction association
        circle_transactions = IntraCircleShareTransaction.objects.filter(
            shares__in=member_shares)

        # loop through the transaction list
        for circle_transaction in circle_transactions:
            member = circle_transaction.shares.circle_member.member
            print("{} {} {}".format(member.user.first_name,
                                    member.user.last_name, member.national_id))
            wallet = member.wallet
            amount = circle_transaction.num_of_shares
            wallet_balance = wallet_utils.Wallet().calculate_wallet_balance(
                wallet) + amount
            trxt_desc = "Circle {} has been deactivated due to inactivity. " \
                        "Your savings of {} {} have been unlocked. " \
                        "New wallet balance is {} {}".format(circle_transaction.shares.circle_member.circle.circle_name,
                                                             member.currency,
                                                             amount, member.currency,
                                                             wallet_balance)
            time_processed = datetime.datetime.now()
            print(trxt_desc)
            circle_transaction.transaction_type = "WITHDRAW"
            circle_transaction.transaction_desc = trxt_desc
            trxt_code = "RT" + circle_transaction.transaction_code
            circle_transaction.save()
            transaction = Transactions.objects.create(
                wallet=circle_transaction.shares.circle_member.member.wallet,
                transaction_type='CREDIT',
                transaction_time=time_processed,
                transaction_desc=trxt_desc,
                transaction_amount=amount,
                transaction_code=trxt_code,
                source="shares")
            instance = fcm_utils.Fcm()
            registration_id = circle_transaction.shares.circle_member.member.device_token
            serializer = WalletTransactionsSerializer(transaction)
            fcm_data = {
                "request_type": "WALLET_TO_MPESA_TRANSACTION",
                "transaction": serializer.data
            }
            print(fcm_data)
            instance.data_push("single", registration_id, fcm_data)

        for circle in circles:
            circle.delete()
Beispiel #4
0
    def reply_to_chat(chat_id, body):
        body = body.strip()
        if len(body) == 0:
            return False

        in_reply_to_chat = Chat.objects.get(id=chat_id)
        member = in_reply_to_chat.owner
        try:
            Chat(sender='Opencircles',
                 recipient='SELF',
                 body=body,
                 owner=member,
                 time_chat_sent=datetime.datetime.now(),
                 has_been_responded_to=True).save()
            in_reply_to_chat.has_been_responded_to = True
            in_reply_to_chat.save()

            instance = fcm_utils.Fcm()
            registration_id = member.device_token

            fcm_data = {
                'request_type': 'REPLY_TO_CHAT',
                'sender': 'Opencircles',
                'body': body,
                'time_sent':
                datetime.datetime.now().strftime('%Y-%m-%d %H-%m-%s')
            }
            instance.data_push("single", registration_id, fcm_data)
            return True
        except Exception as exp:
            print(exp)
            return False
Beispiel #5
0
    def send_single_chat(message, member, message_channel):
        try:
            if message_channel == 1:
                Chat(sender='Opencircles',
                     recipient='SELF',
                     body=message,
                     owner=member,
                     time_chat_sent=datetime.datetime.now(),
                     has_been_responded_to=True).save()
                instance = fcm_utils.Fcm()
                registration_id = member.device_token

                fcm_data = {
                    'request_type':
                    'REPLY_TO_CHAT',
                    'sender':
                    'Opencircles',
                    'body':
                    message,
                    'time_sent':
                    datetime.datetime.now().strftime('%Y-%m-%d %H-%m-%s')
                }
                instance.data_push("single", registration_id, fcm_data)
                return True
            else:
                print(member.phone_number)
                print(message)
                response = sms_utils.Sms().sendsms(member.phone_number,
                                                   message)
                return response
        except Exception as exp:
            print(exp)
            return False
    def commit_mpesa_c2b_transaction(mpesa_transaction):
        trx_code = mpesa_transaction['transaction_code']
        amount = mpesa_transaction['amount']
        trx_time = mpesa_transaction['time']

        response_json = json.loads(mpesa_transaction['response'])
        bill_ref_number = response_json['BillRefNumber']
        msisdn = response_json['MSISDN']
        c2b_first_name = response_json['FirstName']
        c2b_middle_name = response_json['MiddleName']

        sms = Sms()
        member_phone_number = sms.format_phone_number(bill_ref_number)
        mpesa_trx_obj = AdminMpesaTransaction_logs.objects.get(
            TransactioID=trx_code.strip())
        if Member.objects.filter(phone_number=member_phone_number).exists(
        ) and mpesa_trx_obj.is_committed is False:
            member = Member.objects.get(phone_number=member_phone_number)
            wallet = Wallet.objects.get(member=member)
            try:
                wallet_utils = WalletUtils()
                new_balance = wallet_utils.calculate_wallet_balance() + amount
                trx_obj = Transactions()
                trx_obj.transaction_type = 'CREDIT'
                trx_obj.transaction_time = trx_time
                trx_obj.transaction_desc = """
                    {} confirmed. You have received KES {} from {} {} {} via M-PESA at {}. New wallet balance is KES {}
                """.format(trx_code, amount, msisdn, c2b_first_name,
                           c2b_middle_name,
                           trx_time.strftime('%Y-%m-%d %H-%M-%s'),
                           new_balance).strip()
                trx_obj.transaction_amount = amount
                trx_obj.transacted_by = '{} {} {}'.format(
                    msisdn, c2b_first_name, c2b_middle_name)
                trx_obj.recipient = 'SELF'
                trx_obj.transaction_code = trx_code
                trx_obj.wallet = wallet
                trx_obj.source = 'MPESA C2B'
                trx_obj.save()
                mpesa_trx_obj.is_committed = True
                mpesa_trx_obj.save()

                serializer = WalletTransactionsSerializer(trx_obj)
                instance = fcm_utils.Fcm()
                registration_id = member.device_token
                fcm_data = {
                    "request_type": "MPESA_TO_WALLET_TRANSACTION",
                    "transaction": serializer.data
                }
                instance.data_push("single", registration_id, fcm_data)
                return True
            except Exception as e:
                return False
        else:
            return False
Beispiel #7
0
def remove_allowed_guarantee_request(request):
    serializer = AllowedGuaranteeSerializer(data=request.data)
    if serializer.is_valid():
        member = request.user.member
        instance = sms_utils.Sms()
        circle = Circle.objects.get(
            circle_acc_number=serializer.validated_data['circle_acc_number'])
        phone_number = instance.format_phone_number(
            serializer.validated_data['guarantee'])
        user_circle_member = CircleMember.objects.get(circle=circle,
                                                      member=member)
        guarantee_circle_member = CircleMember.objects.get(
            circle=circle,
            member=Member.objects.get(phone_number=phone_number))
        try:
            AllowedGuarantorRequest.objects.filter(
                circle_member=user_circle_member,
                allows_request_from=guarantee_circle_member).delete()
            message = " {} {} removed from guarantee request list".format(
                guarantee_circle_member.member.user.first_name,
                guarantee_circle_member.member.user.last_name)
            data = {"status": 1, "message": message}
        except Exception as e:
            print(str(e))
            message = " Unable to remove {} {} from guarantee request list".format(
                guarantee_circle_member.member.user.first_name,
                guarantee_circle_member.member.user.last_name)
            data = {"status": 0, "message": message}
            return Response(data, status=status.HTTP_200_OK)
        fcm_instance = fcm_utils.Fcm()
        registration_id = guarantee_circle_member.member.device_token
        fcm_data = {
            "request_type": "UPDATE_ALLOW_GUARANTOR_REQUEST",
            "circle_acc_number": circle.circle_acc_number,
            "phone_number": member.phone_number,
            "allow_guarantor_request": False
        }
        fcm_instance.data_push("single", registration_id, fcm_data)
        print(fcm_data)
        updating_loan_limit.delay(circle.id, member.id)
        return Response(data, status=status.HTTP_200_OK)
    data = {"status": 0, "message": serializer.errors}
    return Response(data, status=status.HTTP_200_OK)
 def send_circle_invitation(self, circle_invitations):
     sms_instance = sms_utils.Sms()
     for invite in circle_invitations:
         circle, member = invite.invited_by.circle, invite.invited_by.member
         if invite.is_member:
             invited_member = Member.objects.get(
                 phone_number=invite.phone_number)
             DeclinedCircles.objects.filter(circle=circle,
                                            member=invited_member).delete()
             registration_id = invited_member.device_token
             if len(registration_id):
                 fcm_instance = fcm_utils.Fcm()
                 invited_by = "{} {}".format(member.user.first_name,
                                             member.user.last_name)
                 invited_serializer = InvitedCircleSerializer(
                     circle, context={"invited_by": invited_by})
                 fcm_data = {
                     "request_type": "NEW_CIRCLE_INVITATION",
                     "circle": invited_serializer.data
                 }
                 print(fcm_data)
                 fcm_instance.data_push("single", registration_id, fcm_data)
             else:
                 # Logged out so send sms
                 message = "{} {} has invited you to join {} on Opencircles.".format(
                     member.user.first_name, member.user.last_name,
                     circle.circle_name)
                 sms_instance.sendsms(invite.phone_number, message)
         else:
             # Not a member so send sms
             message =  "{} {} has invited you to join {} on Opencircles. " \
                        "Opencircles is a peer to peer credit and savings platform that makes you " \
                        "and your close friends, family and colleagues into investment and saving partners. " \
                        "Download the app from google play store {}".format(member.user.first_name,
                                                                            member.user.last_name,
                                                                            circle.circle_name,
                                                                            settings.APP_STORE_LINK)
             sms_instance.sendsms(invite.phone_number, message)
         invite.is_sent = True
         invite.save()
Beispiel #9
0
 def post(self, request):
     serializer = SharesWithdrawalSerializer(data=request.data)
     if serializer.is_valid():
         pin = serializer.validated_data['pin']
         circle = Circle.objects.get(circle_acc_number=serializer.
                                     validated_data['circle_acc_number'])
         member = request.user.member
         created_objects = []
         if circle.is_active:
             circle_member = CircleMember.objects.get(circle=circle,
                                                      member=member)
             if circle_member.is_active:
                 if request.user.check_password(pin):
                     amount = serializer.validated_data['amount']
                     valid, response = shares_utils.Shares(
                     ).validate_withdrawal_amount(amount)
                     if valid:
                         circle_instance = circle_utils.Circle()
                         available_shares = circle_instance.get_available_circle_member_shares(
                             circle, member)
                         print("before available_shares")
                         print(available_shares)
                         if amount <= available_shares:
                             shares_tariff = SharesWithdrawalTariff.objects.get(
                                 max_amount__gte=amount,
                                 min_amount__lte=amount)
                             fcm_available_shares = circle_instance.get_guarantor_available_shares(
                                 circle, member)
                             total_amount = amount + shares_tariff.amount
                             if total_amount <= available_shares:
                                 if total_amount <= fcm_available_shares:
                                     shares = None
                                     try:
                                         loan_instance = loan_utils.Loan()
                                         general_instance, wallet_instance = general_utils.General(
                                         ), wallet_utils.Wallet()
                                         circle_member = CircleMember.objects.get(
                                             circle=circle, member=member)
                                         shares = circle_member.shares.get()
                                         time_processed = datetime.datetime.now(
                                         )
                                         transaction_code = general_instance.generate_unique_identifier(
                                             'STW')
                                         shares_desc = "{} confirmed.You have withdrawn shares worth {} {} from " \
                                                       "circle {}.Transaction cost {} {}".format(transaction_code,
                                                                                                 member.currency,
                                                                                                 amount,
                                                                                                 circle.circle_name,
                                                                                                 member.currency,
                                                                                                 shares_tariff.amount)
                                         shares_transaction = IntraCircleShareTransaction.objects.create(
                                             shares=shares,
                                             transaction_type="WITHDRAW",
                                             num_of_shares=total_amount,
                                             transaction_desc=shares_desc,
                                             transaction_code=
                                             transaction_code)
                                         created_objects.append(
                                             shares_transaction)
                                         revenue = RevenueStreams.objects.create(
                                             stream_amount=shares_tariff.
                                             amount,
                                             stream_type="SHARES WITHDRAW",
                                             stream_code=transaction_code,
                                             time_of_transaction=
                                             time_processed)
                                         created_objects.append(revenue)
                                         transaction_code = general_instance.generate_unique_identifier(
                                             'WTC')
                                         wallet_balance = wallet_instance.calculate_wallet_balance(
                                             member.wallet) + amount
                                         wallet_desc = "{} confirmed.You have received {} {} from circle {} shares " \
                                                       "withdrawal.New wallet balance is {} {}".format(transaction_code,
                                                                                                       member.currency,
                                                                                                       amount,
                                                                                                       circle.circle_name,
                                                                                                       member.currency,
                                                                                                       wallet_balance)
                                         wallet_transaction = Transactions.objects.create(
                                             wallet=member.wallet,
                                             transaction_type='CREDIT',
                                             transaction_time=time_processed,
                                             transaction_desc=wallet_desc,
                                             transaction_amount=amount,
                                             transaction_code=
                                             transaction_code,
                                             source="shares")
                                         created_objects.append(
                                             wallet_transaction)
                                         shares_transaction_serializer = SharesTransactionSerializer(
                                             shares_transaction)
                                         wallet_transaction_serializer = WalletTransactionsSerializer(
                                             wallet_transaction)
                                         fcm_available_shares = circle_instance.get_guarantor_available_shares(
                                             circle, member)
                                         print(
                                             "others view of available_shares"
                                         )
                                         print(fcm_available_shares)
                                         available_shares = circle_instance.get_available_circle_member_shares(
                                             circle, member)
                                         print("new available_shares")
                                         print(available_shares)
                                         loan_limit = loan_instance.calculate_loan_limit(
                                             circle, member)
                                         print("loan limit")
                                         print(loan_limit)
                                         data = {
                                             "status":
                                             1,
                                             "shares_transaction":
                                             shares_transaction_serializer.
                                             data,
                                             "wallet_transaction":
                                             wallet_transaction_serializer.
                                             data,
                                             "loan_limit":
                                             loan_limit,
                                             "message":
                                             wallet_desc
                                         }
                                     except Exception as e:
                                         print(str(e))
                                         general_instance = general_utils.General(
                                         )
                                         general_instance.delete_created_objects(
                                             created_objects)
                                         data = {
                                             "status":
                                             0,
                                             "message":
                                             "Unable to process the shares withdrawal request"
                                         }
                                         return Response(
                                             data,
                                             status=status.HTTP_200_OK)
                                     # unblock task
                                     # loan_instance.update_loan_limit(circle,member)
                                     updating_loan_limit.delay(
                                         circle.id, member.id)
                                     fcm_instance = fcm_utils.Fcm()
                                     fcm_data = {
                                         "request_type":
                                         "UPDATE_AVAILABLE_SHARES",
                                         "circle_acc_number":
                                         circle.circle_acc_number,
                                         "phone_number":
                                         member.phone_number,
                                         "available_shares":
                                         fcm_available_shares
                                     }
                                     registration_id = fcm_instance.get_circle_members_token(
                                         circle, member)
                                     fcm_instance.data_push(
                                         "multiple", registration_id,
                                         fcm_data)
                                     return Response(
                                         data, status=status.HTTP_200_OK)
                                 data = {
                                     "status":
                                     0,
                                     "message":
                                     "Unable to perform shares withdrawal request due to"
                                     " pending loan guarantee requests."
                                     "Kindly response to the requests."
                                 }
                                 return Response(data,
                                                 status=status.HTTP_200_OK)
                             data = {
                                 "status":
                                 0,
                                 "message":
                                 "Insufficient shares to cover the shares withdrawal charges"
                             }
                             return Response(data,
                                             status=status.HTTP_200_OK)
                         data = {
                             "status":
                             0,
                             "message":
                             "Amount entered exceeds your available shares."
                         }
                         return Response(data, status=status.HTTP_200_OK)
                     data = {"status": 0, "message": response}
                     return Response(data, status=status.HTTP_200_OK)
                 data = {"status": 0, "message": "Invalid pin"}
                 return Response(data, status=status.HTTP_200_OK)
             data = {
                 "status":
                 0,
                 "message":
                 "Unable to withdraw savings from circle. Your account is currently "
                 "deactivated due to delayed loan repayment."
             }
             return Response(data, status=status.HTTP_200_OK)
         data = {
             "status":
             0,
             "message":
             "Unable to withdraw savings from circle.Circle is inactive."
         }
     data = {"status": 0, "message": serializer.errors}
     return Response(data, status=status.HTTP_200_OK)
Beispiel #10
0
 def post(self, request, *args, **kwargs):
     serializer = PurchaseSharesSerializer(data=request.data)
     if serializer.is_valid():
         pin, amount = serializer.validated_data[
             'pin'], serializer.validated_data['amount']
         circle_acc_number = serializer.validated_data['circle_acc_number']
         circle, member = Circle.objects.get(
             circle_acc_number=circle_acc_number), request.user.member
         if circle.is_active:
             circle_member = CircleMember.objects.get(circle=circle,
                                                      member=member)
             if circle_member.is_active:
                 if amount < settings.MIN_SUBSEQUENT_SHARES:
                     data = {
                         "status":
                         0,
                         "message":
                         "The allowed minimum purchased shares is "
                         "KES {}".format(settings.MIN_SUBSEQUENT_SHARES)
                     }
                     return Response(data, status=status.HTTP_200_OK)
                 valid, response = shares_utils.Shares(
                 ).validate_purchased_shares(amount, circle, member)
                 if valid:
                     wallet_instance = wallet_utils.Wallet()
                     valid, response = wallet_instance.validate_account(
                         request, pin, amount)
                     created_objects = []
                     shares = None
                     if valid:
                         loan_instance = loan_utils.Loan()
                         try:
                             general_instance = general_utils.General()
                             circle_member = CircleMember.objects.get(
                                 circle=circle, member=member)
                             shares = circle_member.shares.get()
                             wallet = member.wallet
                             wallet_balance = wallet_instance.calculate_wallet_balance(
                                 wallet) - amount
                             transaction_code = general_instance.generate_unique_identifier(
                                 'WTD')
                             wallet_desc = "{} confirmed.You have purchased shares worth {} {} in circle {}." \
                                           "New wallet balance is {} {}.".format(transaction_code, member.currency,
                                                                                 amount, circle.circle_name,
                                                                                 member.currency, wallet_balance)
                             wallet_transaction = Transactions.objects.create(
                                 wallet=wallet,
                                 transaction_type="DEBIT",
                                 transaction_time=datetime.datetime.now(),
                                 transaction_desc=wallet_desc,
                                 transaction_amount=amount,
                                 recipient=circle_acc_number,
                                 transaction_code=transaction_code,
                                 source="wallet")
                             created_objects.append(wallet_transaction)
                             print("wallet transaction")
                             print(wallet_transaction.transaction_amount)
                             transaction_code = general_instance.generate_unique_identifier(
                                 'STD')
                             shares_desc = "{} confirmed.You have purchased shares worth {} {} " \
                                           "in circle {}.".format(transaction_code, member.currency,
                                                                  amount, circle.circle_name)
                             shares_transaction = IntraCircleShareTransaction.objects.create(
                                 shares=shares,
                                 transaction_type="DEPOSIT",
                                 sender=circle_member,
                                 recipient=circle_member,
                                 num_of_shares=amount,
                                 transaction_desc=shares_desc,
                                 transaction_code=transaction_code)
                             created_objects.append(shares_transaction)
                             circle_instance = circle_utils.Circle()
                             available_shares = circle_instance.get_available_circle_member_shares(
                                 circle, member)
                             print("available shares")
                             print(available_shares)
                             fcm_available_shares = circle_instance.get_guarantor_available_shares(
                                 circle, member)
                             wallet_serializer = WalletTransactionsSerializer(
                                 wallet_transaction)
                             shares_serializer = SharesTransactionSerializer(
                                 shares_transaction)
                             loan_limit = loan_instance.calculate_loan_limit(
                                 circle, member)
                             print("loan limit")
                             print(loan_limit)
                             data = {
                                 "status": 1,
                                 "wallet_transaction":
                                 wallet_serializer.data,
                                 "shares_transaction":
                                 shares_serializer.data,
                                 "loan_limit": loan_limit
                             }
                         except Exception as e:
                             print(str(e))
                             general_utils.General().delete_created_objects(
                                 created_objects)
                             data = {
                                 "status": 0,
                                 "message": "Unable to complete transaction"
                             }
                             return Response(data,
                                             status=status.HTTP_200_OK)
                         # unblock task
                         # loan_instance.update_loan_limit(circle,member)
                         updating_loan_limit.delay(circle.id, member.id)
                         fcm_instance = fcm_utils.Fcm()
                         fcm_data = {
                             "request_type": "UPDATE_AVAILABLE_SHARES",
                             "circle_acc_number": circle.circle_acc_number,
                             "phone_number": member.phone_number,
                             "available_shares": fcm_available_shares
                         }
                         registration_id = fcm_instance.get_circle_members_token(
                             circle, member)
                         fcm_instance.data_push("multiple", registration_id,
                                                fcm_data)
                         print(fcm_data)
                         return Response(data, status=status.HTTP_200_OK)
                     data = {"status": 0, "message": response}
                     return Response(data, status=status.HTTP_200_OK)
             data = {
                 "status":
                 0,
                 "message":
                 "Unable to deposit to circle.Your account is currently deactivated due"
                 " to delayed loan repayment."
             }
             return Response(data, status=status.HTTP_200_OK)
         data = {
             "status": 0,
             "message": "Unable to deposit to circle.Circle is inactive."
         }
         return Response(data, status=status.HTTP_200_OK)
         data = {"status": 0, "message": response}
         return Response(data, status=status.HTTP_200_OK)
     data = {"status": 0, "message": serializer.errors}
     return Response(data, status=status.HTTP_200_OK)
Beispiel #11
0
 def post(self, request):
     serializer = JoinCircleSerializer(data=request.data)
     if serializer.is_valid():
         acc_number, amount, pin = serializer.validated_data[
             'circle_acc_number'], serializer.validated_data[
                 'amount'], serializer.validated_data['pin']
         circle = Circle.objects.get(circle_acc_number=acc_number)
         circle_members_count = CircleMember.objects.filter(
             circle=circle).count()
         has_defaulted = CircleMember.objects.filter(
             member=request.user.member, is_active=False)
         if has_defaulted.exists():
             data = {
                 "status":
                 0,
                 "message":
                 "Unable to join circle.One of your accounts is currently deactivated due"
                 " to delayed loan repayment. Kindly repay your loan to be able to join this circle."
             }
             return Response(data, status=status.HTTP_200_OK)
         if circle_members_count <= settings.MAX_CIRCLE_MEMBER:
             if amount < circle.minimum_share:
                 data = {"status":0, "message":"The allowed minimum initial deposit for circle " \
                                               "{} is KES {}".format(circle.circle_name, circle.minimum_share)}
                 return Response(data, status=status.HTTP_200_OK)
             wallet_instance = wallet_utils.Wallet()
             valid, response = wallet_instance.validate_account(
                 request, pin, amount)
             if valid:
                 created_objects = []
                 try:
                     loan_instance = loan_utils.Loan()
                     general_instance = general_utils.General()
                     member = request.user.member
                     existing_circle_member = CircleMember.objects.filter(
                         member=member).count()
                     wallet_transaction_code = general_instance.generate_unique_identifier(
                         'WTD')
                     shares_transaction_code = general_instance.generate_unique_identifier(
                         'STD')
                     wallet_balance = wallet_instance.calculate_wallet_balance(
                         member.wallet) - amount
                     wallet_desc = "{} confirmed. You have purchased shares worth {} {} in circle {}. " \
                                   "New wallet balance is {} {}.".format(wallet_transaction_code,
                                                                         member.currency, amount,
                                                                         circle.circle_name,
                                                                         member.currency, wallet_balance)
                     shares_desc = "{} confirmed. You have purchased shares " \
                                   "worth {} {}".format(shares_transaction_code, member.currency, amount)
                     circle_instance = circle_utils.Circle()
                     circle_member = CircleMember.objects.create(
                         circle=circle, member=member)
                     created_objects.append(circle_member)
                     wallet_transaction = Transactions.objects.create(
                         wallet=request.user.member.wallet,
                         transaction_type="DEBIT",
                         transaction_time=datetime.datetime.now(),
                         transaction_amount=amount,
                         transaction_desc=wallet_desc,
                         recipient=circle.circle_acc_number,
                         transaction_code=wallet_transaction_code,
                         source="wallet")
                     created_objects.append(wallet_transaction)
                     shares = Shares.objects.create(
                         circle_member=circle_member)
                     shares_transaction = IntraCircleShareTransaction.objects.create(
                         shares=shares,
                         transaction_type="DEPOSIT",
                         recipient=circle_member,
                         transaction_time=datetime.datetime.now(),
                         transaction_desc=shares_desc,
                         num_of_shares=amount,
                         transaction_code=shares_transaction_code)
                     wallet_serializer = WalletTransactionsSerializer(
                         wallet_transaction)
                     shares_serializer = SharesTransactionSerializer(
                         shares_transaction)
                     circle_member_serializer = UnloggedCircleMemberSerializer(
                         member, context={"circle": circle})
                     loan_limit = loan_instance.calculate_loan_limit(
                         circle, member)
                     fcm_instance = fcm_utils.Fcm()
                     old_circle_status = circle.is_active
                     is_active = old_circle_status
                     if not old_circle_status:
                         new_circle_status = circle_instance.check_update_circle_status(
                             circle)
                         if new_circle_status:
                             fcm_data = {
                                 "request_type": "UPDATE_CIRCLE_STATUS",
                                 "circle_acc_number":
                                 circle.circle_acc_number,
                                 "is_active": True
                             }
                             is_active = True
                             registration_ids = fcm_instance.get_circle_members_token(
                                 circle, None)
                             fcm_instance.data_push("mutiple",
                                                    registration_ids,
                                                    fcm_data)
                             print(fcm_data)
                     # unblock task
                     updating_loan_limit.delay(circle.id, member.id)
                     fcm_data = {
                         "request_type": "NEW_CIRCLE_MEMBERSHIP",
                         "circle_acc_number": circle.circle_acc_number,
                         "circle_member": circle_member_serializer.data
                     }
                     registration_ids = fcm_instance.get_circle_members_token(
                         circle, member)
                     fcm_instance.data_push("mutiple", registration_ids,
                                            fcm_data)
                     print(fcm_data)
                     ref = False
                     if existing_circle_member == 0:
                         try:
                             is_invited = CircleInvitation.objects.get(
                                 phone_number=member.phone_number,
                                 invited_by__circle=circle)
                             referral_fee = settings.REFERRAL_FEE
                             today = datetime.date.today()
                             if is_invited.time_invited.date(
                             ) == today and today.weekday() == 4:
                                 referral_fee = settings.FRIDAY_REFERRAL_FEE
                             ref = True
                             referral_programme_promotion.delay(
                                 is_invited.id, referral_fee)
                         except CircleInvitation.DoesNotExist:
                             print("object does not exist")
                         except CircleInvitation.MultipleObjectsReturned:
                             ReferralFee.objects.create(
                                 member=member,
                                 circle=circle,
                                 is_disbursed=False,
                                 extra_info=
                                 "user has been invited by more than one circle member"
                             )
                     if not ref:
                         CircleInvitation.objects.filter(
                             phone_number=member.phone_number,
                             invited_by__circle=circle).delete()
                     data = {
                         "status": 1,
                         "wallet_transaction": wallet_serializer.data,
                         "shares_transaction": shares_serializer.data,
                         "loan_limit": loan_limit,
                         "is_active": is_active
                     }
                 except Exception as e:
                     print(str(e))
                     instance = general_utils.General()
                     instance.delete_created_objects(created_objects)
                     data = {
                         "status": 0,
                         "message": "Unable to add member to circle"
                     }
                     return Response(data, status=status.HTTP_200_OK)
                 fcm_available_shares = circle_instance.get_guarantor_available_shares(
                     circle, member)
                 fcm_instance = fcm_utils.Fcm()
                 fcm_data = {
                     "request_type": "UPDATE_AVAILABLE_SHARES",
                     "circle_acc_number": circle.circle_acc_number,
                     "phone_number": member.phone_number,
                     "available_shares": fcm_available_shares
                 }
                 registration_ids = fcm_instance.get_circle_members_token(
                     circle, member)
                 fcm_instance.data_push("multiple", registration_ids,
                                        fcm_data)
                 return Response(data, status=status.HTTP_200_OK)
             data = {"status": 0, "message": response}
             return Response(data, status=status.HTTP_200_OK)
         data = {
             "status": 0,
             "message": "Unable to join circle.The circle is already full."
         }
         return Response(data, status=status.HTTP_200_OK)
     data = {"status": 0, "message": serializer.errors}
     return Response(data, status.HTTP_200_OK)
Beispiel #12
0
 def post(self, request):
     serializer = CircleInviteSerializer(data=request.data)
     if serializer.is_valid():
         circle = Circle.objects.get(circle_acc_number=serializer.
                                     validated_data['circle_acc_number'])
         sms_instance = sms_utils.Sms()
         phone = sms_instance.format_phone_number(
             serializer.validated_data['phone_number'])
         circle_member = CircleMember.objects.get(
             member=request.user.member, circle=circle)
         try:
             CircleMember.objects.get(
                 circle=circle,
                 member=Member.objects.filter(phone_number=phone))
             data = {
                 "status": 0,
                 "message": "The user is already a member of the circle."
             }
         except CircleMember.DoesNotExist:
             invites = CircleInvitation.objects.filter(
                 invited_by__in=CircleMember.objects.filter(circle=circle),
                 phone_number=phone)
             if invites.exists():
                 invite = invites.latest('id')
                 if invite.status == "Pending":
                     data = {
                         "status":
                         0,
                         "message":
                         "Unable to send invitation."
                         "Member has already been invited to join this circle."
                     }
                 else:
                     data = {
                         "status":
                         0,
                         "message":
                         "Unable to send invitation."
                         "Member already declined previous circle invitation"
                     }
             else:
                 created_objects = []
                 try:
                     member_instance = member_utils.OpenCircleMember()
                     circle_invite = CircleInvitation.objects.create(
                         phone_number=phone,
                         invited_by=circle_member,
                         is_member=member_instance.get_is_member(phone))
                     print(circle_invite)
                     created_objects.append(circle_invite)
                     try:
                         invited_member = Member.objects.get(
                             phone_number=phone)
                         DeclinedCircles.objects.filter(
                             circle=circle, member=invited_member).delete()
                         registration_id = invited_member.device_token
                         if len(registration_id):
                             fcm_instance = fcm_utils.Fcm()
                             invited_by = "{} {}".format(
                                 request.user.first_name,
                                 request.user.last_name)
                             invited_serializer = InvitedCircleSerializer(
                                 circle, context={"invited_by": invited_by})
                             fcm_data = {
                                 "request_type": "NEW_CIRCLE_INVITATION",
                                 "circle": invited_serializer.data
                             }
                             fcm_instance.data_push("single",
                                                    registration_id,
                                                    fcm_data)
                         else:
                             message = "{} {} has invited you to join circle {} on " \
                                       "Opencircles.".format(request.user.first_name,
                                                             request.user.last_name,
                                                             circle.circle_name)
                             sms_instance.sendsms(phone, message)
                     except Member.DoesNotExist:
                         #send sms
                         message = "{} {} has invited you to join circle {} on Opencircles." \
                                   "Opencircles is a peer to peer credit and savings platform that makes you " \
                                   "and your close friends, family and colleagues into investment and " \
                                   "saving partners.Get it on {} ".format(request.user.first_name,
                                                                          request.user.last_name,
                                                                          circle.circle_name,
                                                                          settings.APP_STORE_LINK)
                         sms_instance.sendsms(phone, message)
                     ms = "Invitation to {} has been sent.".format(phone)
                     data = {"status": 1, "message": ms}
                 except Exception as e:
                     print(str(e))
                     general_utils.General().delete_created_objects(
                         created_objects)
                     data = {
                         "status": 0,
                         "message": "Unable to send circle invitation"
                     }
             return Response(data, status=status.HTTP_200_OK)
         return Response(data, status=status.HTTP_200_OK)
     data = {"status": 0, "message": serializer.erors}
     return Response(data, status=status.HTTP_200_OK)
    def commit_mpesa_b2b_transaction(mpesa_transaction):
        trx_code = mpesa_transaction['transaction_code']
        amount = mpesa_transaction['amount']
        transaction_time = mpesa_transaction['time']
        response_json = json.loads(mpesa_transaction['response'])
        result = response_json['Result']
        originator_conversation_id = result['OriginatorConversationID']
        result_code = int(result['ResultCode'])
        ResultParameters = result["ResultParameters"]["ResultParameter"]
        paybill_dict = {
            n['Key']: n['Value']
            for n in ResultParameters for key, value in n.iteritems()
            if value == "ReceiverPartyPublicName"
        }
        ReferenceData = result['ReferenceData']['ReferenceItem']

        acc_no_dict = {
            n['Key']: n['Value']
            for n in ReferenceData for key, value in n.iteritems()
            if value == "BillReferenceNumber"
        }
        paybill = paybill_dict["ReceiverPartyPublicName"].split(" ")[0]
        acc_no = acc_no_dict['BillReferenceNumber']
        mpesa_trx_obj = AdminMpesaTransaction_logs.objects.get(
            TransactioID=trx_code)
        try:
            pending_trx = PendingMpesaTransactions.objects.get(
                originator_conversation_id=originator_conversation_id)
            print("Normal")
            print(pending_trx.originator_conversation_id)
        except PendingMpesaTransactions.DoesNotExist:
            pending_trx_ids = PendingMpesaTransactions.objects.filter(
                is_valid=True,
                trx_time__date=transaction_time.date(),
                type="B2B",
                amount=amount).values_list('originator_conversation_id',
                                           flat=True)
            print(pending_trx_ids)
            print(paybill_dict["ReceiverPartyPublicName"])
            print(acc_no)
            b2b_trx = B2BTransaction_log.objects.filter(
                OriginatorConversationID__in=pending_trx_ids,
                Recipient_PayBillNumber=paybill,
                AccountNumber=acc_no)
            print(b2b_trx)
            if b2b_trx.exists():
                b2b_trx_id = b2b_trx[0].OriginatorConversationID
                pending_trx = PendingMpesaTransactions.objects.get(
                    originator_conversation_id=b2b_trx_id)
            else:
                return False
            print("Not normal")
            print(pending_trx.originator_conversation_id)
        b2b_trx = B2BTransaction_log.objects.get(
            OriginatorConversationID=pending_trx.originator_conversation_id)
        member = pending_trx.member
        if paybill == "525900" and acc_no == "sammienjihia.api":
            is_buyairtime = False
            if pending_trx.purpose in ["buy airtime", "N/A"]:
                is_buyairtime = True
            trx = pending_trx
            wallet = member.wallet
            wallet_balance = WalletUtils().calculate_wallet_balance(
                wallet) - amount
            trx_committed = False
            if is_buyairtime:
                airtime_log = AirtimePurchaseLog.objects.get(
                    originator_conversation_id=trx.originator_conversation_id)
                if not airtime_log.is_purchased:
                    sms_instance = Sms()
                    recipient = airtime_log.recipient
                    response = sms_instance.buyairtime(recipient, amount)
                    if response:
                        trx_desc = "{} confirmed. You bought airtime worth {} {} for {}. " \
                                   "New wallet balance is {} {}".format(trx_code, member.currency,
                                                                        amount, recipient, member.currency,
                                                                        wallet_balance)
                        trx_committed = True
                        airtime_log.is_purchased = True
                        airtime_log.save()
                    else:
                        return False
            else:
                charges = trx.charges
                if charges == 0:
                    charges = 1
                wallet_balance = wallet_balance - charges
                trx_desc = "{} confirmed. {} {} has been sent to {} for account {} " \
                                   "from your wallet at {}.Transaction cost {} {}." \
                                   " New wallet balance is {} {}.".format(trx_code,
                                                                          member.currency,
                                                                          amount,
                                                                          paybill_dict["ReceiverPartyPublicName"],
                                                                          acc_no,
                                                                          datetime.datetime.now(),
                                                                          member.currency,
                                                                          charges,
                                                                          member.currency,
                                                                          wallet_balance)
                amount = amount + charges
                RevenueStreams.objects.create(
                    stream_amount=charges,
                    stream_type="SMS CHARGES",
                    stream_code=trx_code,
                    time_of_transaction=datetime.datetime.now())
                trx_committed = True
            if trx_committed:
                wallet_trx = Transactions.objects.create(
                    wallet=wallet,
                    transaction_type="DEBIT",
                    transaction_desc=trx_desc,
                    recipient="{} for {}".format(
                        b2b_trx.Recipient_PayBillNumber,
                        b2b_trx.AccountNumber),
                    transacted_by=wallet.acc_no,
                    transaction_amount=amount,
                    transaction_code=trx_code,
                    source="MPESA B2B")
                fcm_instance = fcm_utils.Fcm()
                registration_id = member.device_token
                trx_serializer = WalletTransactionsSerializer(wallet_trx)
                fcm_data = {
                    "request_type": "WALLET_TO_PAYBILL_TRANSACTION",
                    "transaction": trx_serializer.data
                }
                print(fcm_data)
                fcm_instance.data_push('single', registration_id, fcm_data)
            if is_buyairtime:
                airtime_log.originator_conversation_id = originator_conversation_id
                airtime_log.is_committed = True
                airtime_log.save()
        else:
            charges = pending_trx.charges
            if charges == 0:
                charges = 1
            amount += charges
            wallet = member.wallet
            wallet_balance = WalletUtils().calculate_wallet_balance(
                wallet) - amount
            amount_sent = amount - charges
            trx_desc = "{} confirmed. {} {} has been sent to {} for account {} " \
                               "from your wallet at {}.Transaction cost {} {}." \
                               " New wallet balance is {} {}.".format(trx_code,
                                                                      member.currency,
                                                                      amount_sent,
                                                                      paybill_dict["ReceiverPartyPublicName"],
                                                                      acc_no,
                                                                      datetime.datetime.now(),
                                                                      member.currency,
                                                                      charges,
                                                                      member.currency,
                                                                      wallet_balance)
            RevenueStreams.objects.create(
                stream_amount=1,
                stream_type="SMS CHARGES",
                stream_code=trx_code,
                time_of_transaction=datetime.datetime.now())
            wallet_trx = Transactions.objects.create(
                wallet=wallet,
                transaction_type="DEBIT",
                transaction_desc=trx_desc,
                recipient="{} for {}".format(b2b_trx.Recipient_PayBillNumber,
                                             b2b_trx.AccountNumber),
                transacted_by=wallet.acc_no,
                transaction_amount=amount,
                transaction_code=trx_code,
                source="MPESA B2B")
            fcm_instance = fcm_utils.Fcm()
            registration_id = member.device_token
            trx_serializer = WalletTransactionsSerializer(wallet_trx)
            fcm_data = {
                "request_type": "WALLET_TO_PAYBILL_TRANSACTION",
                "transaction": trx_serializer.data
            }
            fcm_instance.data_push('single', registration_id, fcm_data)
        pending_trx.originator_conversation_id = originator_conversation_id
        pending_trx.is_valid = False
        pending_trx.save()
        b2b_trx.OriginatorConversationID = originator_conversation_id
        b2b_trx.save()
        mpesa_trx_obj.is_committed = True
        mpesa_trx_obj.save()
    def commit_mpesa_b2c_transaction(mpesa_transaction):
        trx_code = mpesa_transaction['transaction_code']
        amount = mpesa_transaction['amount']
        trx_time = mpesa_transaction['time']

        response_json = json.loads(mpesa_transaction['response'])
        originator_conversation_id = response_json['Result'][
            'OriginatorConversationID']
        result_code = int(response_json['Result']['ResultCode'])

        b2c_log = B2CTransaction_log.objects.get(
            OriginatorConversationID=originator_conversation_id)
        member_phone_number = b2c_log.Recipient_PhoneNumber

        mpesa_trx_obj = AdminMpesaTransaction_logs.objects.get(
            TransactioID=trx_code.strip())
        if Member.objects.filter(phone_number=member_phone_number).exists() \
                and mpesa_trx_obj.is_committed is False and result_code == 0:
            member = Member.objects.get(phone_number=member_phone_number)
            wallet = Wallet.objects.get(member=member)

            # Get M-PESA recipient
            result_params = response_json['Result']['ResultParameters'][
                'ResultParameter']
            recipient = ''
            for result_param_obj in result_params:
                if result_param_obj['Key'] == 'ReceiverPartyPublicName':
                    recipient = result_param_obj['Value']

            # Get transaction charges
            charges = 0
            if amount >= 100 and amount <= 1000:
                charges = 16
            elif amount >= 1001 and amount <= 70000:
                charges = 30

            try:
                wallet_utils = WalletUtils()
                new_balance = wallet_utils.calculate_wallet_balance() - (
                    amount + charges)

                # Save transactions Objects
                trx_obj = Transactions()
                trx_obj.transaction_type = 'DEBIT'
                trx_obj.transaction_time = trx_time
                trx_obj.transaction_desc = """
                    {} confirmed. You have sent KES {} to {} via M-PESA at {}.
                    Transaction cost is KES {}. New wallet balance is KES {}
                """.format(trx_code, amount, recipient,
                           trx_time.strftime('%Y-%m-%d %H-%M-%s'), charges,
                           new_balance).strip()
                trx_obj.transaction_amount = amount + charges
                trx_obj.transacted_by = 'SELF'
                trx_obj.recipient = recipient
                trx_obj.transaction_code = trx_code
                trx_obj.wallet = wallet
                trx_obj.source = 'MPESA B2C'
                trx_obj.save()

                # Update mpesa log
                mpesa_trx_obj.is_committed = True
                mpesa_trx_obj.save()

                # Send FCM message
                serializer = WalletTransactionsSerializer(trx_obj)
                instance = fcm_utils.Fcm()
                registration_id = member.device_token
                fcm_data = {
                    "request_type": "MPESA_TO_WALLET_TRANSACTION",
                    "transaction": serializer.data
                }
                instance.data_push("single", registration_id, fcm_data)
                return True
            except Exception as e:
                return False
        else:
            return False
Beispiel #15
0
 def post(self, request):
     serializer = AllowedGuaranteeSerializer(data=request.data)
     if serializer.is_valid():
         instance = sms_utils.Sms()
         circle, guarantee_phone, member = Circle.objects.get(
             circle_acc_number=serializer.
             validated_data['circle_acc_number']
         ), instance.format_phone_number(
             serializer.validated_data['guarantee']), request.user.member
         if guarantee_phone == member.phone_number:
             data = {
                 "status": 0,
                 "message":
                 "Unable to add yourself to guarantee request list"
             }
             return Response(data, status=status.HTTP_200_OK)
         user_circle_member = CircleMember.objects.get(circle=circle,
                                                       member=member)
         guarantee_member = Member.objects.get(phone_number=guarantee_phone)
         allowed_guarantee = CircleMember.objects.get(
             circle=circle, member=guarantee_member)
         try:
             AllowedGuarantorRequest.objects.create(
                 circle_member=user_circle_member,
                 allows_request_from=allowed_guarantee)
             guarantee_serializer = CircleMemberSerializer(guarantee_member,
                                                           context={
                                                               "request":
                                                               request,
                                                               "circle":
                                                               circle
                                                           })
             ms = "{} {} added to guarantee request list".format(
                 guarantee_member.user.first_name,
                 guarantee_member.user.last_name)
             data = {
                 "status": 1,
                 'guarantee': guarantee_serializer.data,
                 'message': ms
             }
         except Exception as e:
             print(str(e))
             ms = "Unable to add {} {} to guarantee request list".format(
                 guarantee_member.user.first_name,
                 guarantee_member.user.last_name)
             data = {"status": 0, "message": ms}
             return Response(data, status=status.HTTP_200_OK)
         fcm_instance = fcm_utils.Fcm()
         registration_id = guarantee_member.device_token
         fcm_data = {
             "request_type": "UPDATE_ALLOW_GUARANTOR_REQUEST",
             "circle_acc_number": circle.circle_acc_number,
             "phone_number": member.phone_number,
             "allow_guarantor_request": True
         }
         fcm_instance.data_push("single", registration_id, fcm_data)
         print(fcm_data)
         updating_loan_limit.delay(circle.id, member.id)
         return Response(data, status=status.HTTP_201_CREATED)
     data = {"status": 0, "errors": serializer.errors}
     return Response(data, status=status.HTTP_200_OK)
Beispiel #16
0
def commit_c2b_mpesa_transaction(request):
    if request.method != 'POST':
        # context = {
        #     'circles': circles_utils.CircleUtils.get_all_circles(),
        #     'members': members_utils.MemberUtils.get_all_members()
        # }
        return render(request, 'app_admin/c2b_transaction.html')

    else:
        print(request.POST)
        sms_instance = sms_utils.Sms()
        admins = ['+254712388212', '+254795891656', '+254714642293']
        admin_phone_number = sms_instance.format_phone_number(
            request.POST.get('admin_phone_number'))
        if admin_phone_number not in admins:
            return_data = {'status': 0, 'message': 'Unauthorized access.'}
            print(return_data)
            return HttpResponse(json.dumps(return_data))

        pin = request.POST.get('pin')
        user = authenticate(username=admin_phone_number, password=pin)
        if user is not None:
            code = request.POST.get('transaction_code')
            amount = int(request.POST.get('amount'))
            recipient_phone_number = sms_instance.format_phone_number(
                request.POST.get('recipient_phone_number'))
            try:
                member = Member.objects.get(
                    phone_number=recipient_phone_number)
            except Member.DoesNotExist:
                return_data = {
                    'status': 0,
                    'message': 'Member with phone number does not exist'
                }
                return HttpResponse(json.dumps(return_data))

            transacted_by = request.POST.get('sender_phone_number')
            if len(transacted_by):
                transacted_by = sms_instance.format_phone_number(transacted_by)
            else:
                transacted_by = recipient_phone_number
            created_objects = []
            try:
                response_data = "Mpesa transaction was manually committed by {} {} {}".format(
                    user.first_name, user.last_name, admin_phone_number)
                admin_mpesa_transaction = AdminMpesaTransaction_logs.objects.create(
                    TransactioID=code,
                    TransactionType='C2B',
                    Response=response_data,
                    is_committed=False)
                created_objects.append(admin_mpesa_transaction)
                wallet_instance = wallet_utils.Wallet()
                wallet = member.wallet
                wallet_balance = wallet_instance.calculate_wallet_balance(
                    wallet) + amount
                transaction_desc = "{} confirmed.You have received {} {} from {} via mpesa. " \
                "New wallet balance is {} {}".format(code, member.currency, amount,
                                                     transacted_by, member.currency, wallet_balance)
                mpesa_transactions = Transactions.objects.create(
                    wallet=wallet,
                    transaction_type="CREDIT",
                    transaction_desc=transaction_desc,
                    transacted_by=transacted_by,
                    transaction_amount=amount,
                    transaction_code=code,
                    source="MPESA C2B")
                created_objects.append(mpesa_transactions)
                admin_mpesa_transaction.is_committed = True
                admin_mpesa_transaction.is_manually_committed = True
                admin_mpesa_transaction.save()
                message = "{} {} {} has successfully committed {} mpesa transaction {} of {} {}.".format(
                    user.first_name, user.last_name, admin_phone_number,
                    recipient_phone_number, code, member.currency, amount)
                try:
                    sms_instance.sendsms("0755564433", message)
                except Exception as e:
                    print(str(e))
                    return_data = {
                        'status':
                        0,
                        'message':
                        'Transaction unsuccessful.Unable to notify admins.'
                    }
                    return HttpResponse(json.dumps(return_data))
            except Exception as e:
                print(str(e))
                general_utils.General().delete_created_objects(created_objects)
                return_data = {
                    'status': 0,
                    'message': 'Unable to commit transaction'
                }
                return HttpResponse(json.dumps(return_data))
            serializer = WalletTransactionsSerializer(mpesa_transactions)
            instance = fcm_utils.Fcm()
            registration_id = member.device_token
            fcm_data = {
                "request_type": "MPESA_TO_WALLET_TRANSACTION",
                "transaction": serializer.data
            }
            instance.data_push("single", registration_id, fcm_data)
            return_data = {
                'status': 0,
                'message': 'Transaction successfully committed.'
            }
            return HttpResponse(json.dumps(return_data))
        else:
            return_data = {'status': 0, 'message': 'Invalid admin credentials'}
            return HttpResponse(json.dumps(return_data))
Beispiel #17
0
    def deactivate_circle_member(self):
        loans = LoanApplication.objects.filter(
            is_approved=True, is_disbursed=True,
            is_fully_repaid=False).exclude(loan_tariff=None)
        for loan in loans:
            member = loan.circle_member.member
            circle = loan.circle_member.circle
            loan_tariff = loan.loan_tariff
            if loan_tariff is None:
                loan_tariff = LoanTariff.objects.get(
                    max_amount__gte=loan.amount,
                    min_amount__lte=loan.amount,
                    circle=circle)
            num_of_months = loan_tariff.num_of_months
            date_of_payment = loan.time_of_application.date() + relativedelta(
                months=num_of_months)
            today = datetime.datetime.now().date()
            if today > date_of_payment:
                print("defaulted loan")
                print(loan.loan_code)
                diff = datetime.datetime.now().date() - date_of_payment
                delta = diff.days
                amortize_loan = loan.loan_amortization.filter().latest('id')
                if delta == 1:
                    CircleMember.objects.filter(
                        circle=circle, member=member).update(is_active=False)
                    title = "Circle {} account deactivation".format(
                        circle.circle_name)

                    message = "Your account has been deactivated due to late repayment of loan {} of" \
                              " KES {} in circle {}. Kindly repay your loan to continue saving, " \
                              "borrowing and earning interests from other circle members' loans.".format(loan.loan_code,
                                                                                                         amortize_loan.total_repayment,
                                                                                                         circle.circle_name)
                    fcm_instance = fcm_utils.Fcm()
                    registration_id = member.device_token
                    if len(registration_id):
                        curr_time = datetime.datetime.now().strftime(
                            "%Y-%m-%d %H:%M:%S")
                        fcm_data = {
                            "request_type": "SYSTEM_WARNING_MSG",
                            "title": title,
                            "message": message,
                            "time": curr_time
                        }
                        fcm_instance.data_push("single", registration_id,
                                               fcm_data)
                        fcm_data = {
                            "request_type": "UPDATE_CIRCLE_MEMBER_STATUS",
                            "phone_number": member.phone_number,
                            "circle_acc_number": circle.circle_acc_number,
                            'is_active': False
                        }
                        registration_ids = fcm_instance.get_circle_members_token(
                            circle, None)
                        fcm_instance.data_push("multiple", registration_ids,
                                               fcm_data)
                    else:
                        sms_instance = sms_utils.Sms()
                        message = "Your {} account has been deactivated due to late repayment of loan {}." \
                                  "Kindly repay your loan to reactivate the account and to continue saving, " \
                                  "borrowing and earning interests from other circle members' loans.".format(
                                                                                                        circle.circle_name,
                                                                                                        loan.loan_code)
                        sms_instance.sendsms(member.phone_number, message)
                else:
                    title = "Circle {} loan repayment".format(
                        circle.circle_name)
                    message = "Kindly repay your loan {} of KES {} in circle {} to continue saving, " \
                              "borrowing and earning interests from other " \
                              "circle members' loans.".format(loan.loan_code,
                                                              amortize_loan.total_repayment, circle.circle_name)
                    fcm_instance = fcm_utils.Fcm()
                    registration_id = member.device_token
                    if len(registration_id):
                        curr_time = datetime.datetime.now().strftime(
                            "%Y-%m-%d %H:%M:%S")
                        fcm_data = {
                            "request_type": "SYSTEM_WARNING_MSG",
                            "title": title,
                            "message": message,
                            "time": curr_time
                        }
                        fcm_instance.data_push("single", registration_id,
                                               fcm_data)
                    else:
                        sms_instance = sms_utils.Sms()
                        message = "Kindly repay your loan {} of KES {} in circle {} to continue saving, borrowing and earning " \
                                  "interests from other circle members' loans.".format(loan.loan_code,
                                                                                       amortize_loan.total_repayment,
                                                                                       circle.circle_name)
                        sms_instance.sendsms(member.phone_number, message)