Exemplo n.º 1
0
 def test_add_credit(self):
     """ We can add credit to a subscriber's balance. """
     increment = randrange(1, 1000)
     prior = subscriber.get_account_balance(self.TEST_IMSI)
     subscriber.add_credit(self.TEST_IMSI, increment)
     after = subscriber.get_account_balance(self.TEST_IMSI)
     self.assertEqual(prior + increment, after)
def process_confirm(from_imsi, code):
    """Process a confirmation request.

    Args:
      from_imsi: sender's IMSI
      code: the input confirmation code string
    """
    # Step one: delete all the confirm codes older than some time.
    db = sqlite3.connect(config_db['pending_transfer_db_path'])
    db.execute("DELETE FROM pending_transfers"
               " WHERE time - ? > 600", (time.time(),))
    db.commit()

    # Step two: check if this (from_imsi, code) combo is valid.
    r = db.execute("SELECT from_acct, to_acct, amount FROM pending_transfers"
                   " WHERE code=? AND from_acct=?", (code, from_imsi))
    res = r.fetchone()
    if res and len(res) == 3:
        from_imsi, to_imsi, amount = res
        from_num = subscriber.get_numbers_from_imsi(from_imsi)[0]
        to_num = subscriber.get_numbers_from_imsi(to_imsi)[0]
        reason = "SMS transfer from %s to %s" % (from_num, to_num)
        # Deduct credit from the sender.
        from_imsi_old_credit = subscriber.get_account_balance(from_imsi)
        from_imsi_new_credit = int(from_imsi_old_credit) - int(amount)
        events.create_transfer_event(from_imsi, from_imsi_old_credit,
                                     from_imsi_new_credit, reason,
                                     from_number=from_num, to_number=to_num)
        subscriber.subtract_credit(from_imsi, str(int(amount)))
        # Add credit to the recipient.
        to_imsi_old_credit = subscriber.get_account_balance(to_imsi)
        to_imsi_new_credit = int(to_imsi_old_credit) + int(amount)
        events.create_transfer_event(to_imsi, to_imsi_old_credit,
                                     to_imsi_new_credit, reason,
                                     from_number=from_num, to_number=to_num)
        subscriber.add_credit(to_imsi, str(int(amount)))
        # Humanize credit strings
        amount_str = freeswitch_strings.humanize_credits(amount)
        to_balance_str = freeswitch_strings.humanize_credits(
                to_imsi_new_credit)
        from_balance_str = freeswitch_strings.humanize_credits(
                from_imsi_new_credit)
        # Let the recipient know they got credit.
        message = gt("You've received %(amount)s credits from %(from_num)s!"
                     " Your new balance is %(new_balance)s.") % {
                     'amount': amount_str, 'from_num': from_num,
                     'new_balance': to_balance_str}
        sms.send(str(to_num), str(config_db['app_number']), str(message))
        # Remove this particular the transfer as it's no longer pending.
        db.execute("DELETE FROM pending_transfers WHERE code=?"
                   " AND from_acct=?", (code, from_imsi))
        db.commit()
        # Tell the sender that the operation succeeded.
        return True, gt("You've transferred %(amount)s to %(to_num)s. "
                        "Your new balance is %(new_balance)s.") % {
                                'amount': amount_str, 'to_num': to_num,
                                'new_balance': from_balance_str}
    return False, gt("That transfer confirmation code doesn't exist"
                     " or has expired.")
Exemplo n.º 3
0
 def test_subtract_credit(self):
     """ We can subtract credit from a subscriber's balance. """
     prior = randrange(1, 1000)  # add some credit first
     subscriber.add_credit(self.TEST_IMSI, prior)
     decrement = randrange(0, prior)
     subscriber.subtract_credit(self.TEST_IMSI, decrement)
     after = subscriber.get_account_balance(self.TEST_IMSI)
     self.assertEqual(prior - int(decrement), after)
Exemplo n.º 4
0
    def adjust_credits(self, data):
        required_fields = ["imsi", "change"]
        if not all([_ in data for _ in required_fields]):
            return web.BadRequest()
        imsi = data["imsi"]
        try:
            change = int(data["change"])
        except ValueError:
            return web.BadRequest()
        old_credit = subscriber.get_account_balance(imsi)
        if change > 0:
            subscriber.add_credit(imsi, str(abs(change)))
        elif change < 0:
            subscriber.subtract_credit(imsi, str(abs(change)))

        new_credit = subscriber.get_account_balance(imsi)

        # Codeship is stupid. These imports break CI and this is an untested
        # method :)
        from core import freeswitch_interconnect, freeswitch_strings

        # Send a confirmation to the subscriber
        number = subscriber.get_caller_id(imsi)
        change_frmt = freeswitch_strings.humanize_credits(change)
        balance_frmt = freeswitch_strings.humanize_credits(new_credit)

        fs_ic = freeswitch_interconnect.freeswitch_ic(self.conf)
        fs_ic.send_to_number(
            number, '000',
            freeswitch_strings.gt(
                "The network operator adjusted your credit by %(change)s. "
                "Your balance is now %(balance)s.") % {
                    'change': change_frmt,
                    'balance': balance_frmt
                })

        # TODO(matt): all credit adjustments are of the kind "add_money," even
        #             if they actually subtract credit.
        reason = 'Update from web UI (add_money)'
        events.create_add_money_event(imsi,
                                      old_credit,
                                      new_credit,
                                      reason,
                                      to_number=number)
        return web.ok()
Exemplo n.º 5
0
    def test_credit_delta_type_enforcement(self):
        """The convention is to pass credit changes as a string.

        It should be possible to convert the string to an int and the value
        should be greater than zero in all cases, even when subtracting credit.
        """
        # Each of these values should cause a TypeError.
        invalid_values = ['one thousand', '93f']
        for value in invalid_values:
            with self.assertRaises(ValueError):
                subscriber.add_credit(self.TEST_IMSI, value)
            with self.assertRaises(ValueError):
                subscriber.subtract_credit(self.TEST_IMSI, value)
        # These increments should be allowed.
        valid_values = ['0', '2', '1000', 1000, 0.1, 999.9, -1000.4]
        for value in valid_values:
            subscriber.add_credit(self.TEST_IMSI, value)
            subscriber.subtract_credit(self.TEST_IMSI, value)