Example #1
0
 def amount_to_string(self):
     """ Return self.amount converted to a suitable string for display.
     """
     return utils.formatDecimalAsMoney(self.amount)
Example #2
0
def enter_transaction(request):
    """ Respond to the "/admin/account/transaction" URL.

        We let the user enter a transaction into the system.
    """
    if request.method == "GET":

        # We're displaying the form for the first time -> set up the default
        # values.

        err_msg                  = None
        type                     = "P"
        user_id                  = ""
        associated_user_id       = ""
        suffix                   = ""
        other_user_id            = ""
        other_associated_user_id = ""
        other_suffix             = ""
        amount                   = ""
        description              = ""

    elif request.method == "POST":

        # Respond to the user submitting our form.

        if request.POST.get("cancel") == "Cancel":
            return HttpResponseRedirect(reverse("tahua.admin_interface." +
                                                "views.main.main"))

        err_msg = None # initially.

        type                     = request.POST['type']
        user_id                  = request.POST['user_id']
        associated_user_id       = request.POST['associated_user_id']
        suffix                   = request.POST['suffix']
        other_user_id            = request.POST['other_user_id']
        other_associated_user_id = request.POST['other_associated_user_id']
        other_suffix             = request.POST['other_suffix']
        amount                   = request.POST['amount']
        description              = request.POST['description']

        account_id = account_helper.make_account_id(user_id,
                                                    associated_user_id,
                                                    suffix)
        if not account_helper.is_valid_account_id(account_id):
            err_msg = "You must enter a valid account identifier."

        if user_id not in ["", None]:
            try:
                user = User.objects.get(user_id=user_id)
            except User.DoesNotExist:
                err_msg = "There is no user with ID " + user_id

        if associated_user_id not in ["", None]:
            try:
                user = User.objects.get(user_id=associated_user_id)
            except User.DoesNotExist:
                err_msg = "There is no user with ID " + associated_user_id

        if err_msg == None:
            try:
                dec_amount = decimal.Decimal(amount)
            except decimal.InvalidOperation:
                err_msg = "Invalid amount."

        if err_msg == None:
            if type not in [Transaction.TYPE_DEPOSIT,
                            Transaction.TYPE_WITHDRAWAL,
                            Transaction.TYPE_PAYMENT,
                            Transaction.TYPE_REVERSAL,
                            Transaction.TYPE_ADJUSTMENT]:
                err_msg = "Please select a valid transaction type."

        if err_msg == None:
            if type == Transaction.TYPE_PAYMENT:
                other_account_id = \
                    account_helper.make_account_id(other_user_id,
                                                   other_associated_user_id,
                                                   other_suffix)
                if not account_helper.is_valid_account_id(other_account_id):
                    err_msg = "You must enter a valid other account identifier."

        # If the entered data was accepted, enter the transaction into the
        # system.

        if err_msg == None:
            account = account_helper.get_or_create_account(account_id)
            if type == Transaction.TYPE_PAYMENT:
                other_account = \
                    account_helper.get_or_create_account(other_account_id)
            else:
                other_account = None

            meta_data = {}
            if description != "":
                meta_data['description'] = description

            if type == Transaction.TYPE_PAYMENT:
                dec_amount = -dec_amount # Deduct amount from source account.

            transaction = Transaction()
            transaction.account       = account
            transaction.other_account = other_account
            transaction.timestamp     = datetime.datetime.now()
            transaction.type          = type
            transaction.amount        = dec_amount
            transaction.metadata      = json.dumps(meta_data)
            transaction.save()

            # If the user is entering a payment, enter the reverse transaction
            # at the same time.

            if type == Transaction.TYPE_PAYMENT:
                transaction = Transaction()
                transaction.account       = other_account
                transaction.other_account = account
                transaction.timestamp     = datetime.datetime.now()
                transaction.type          = type
                transaction.amount        = -dec_amount
                transaction.metadata      = json.dumps(meta_data)
                transaction.save()

            # Finally, tell the user about the entered transaction.

            if type == Transaction.TYPE_PAYMENT:
                msg = utils.formatDecimalAsMoney(-dec_amount) \
                    + " has been transferred from " + account.describe() \
                    + " to " + other_account.describe() + "."
            else:
                msg = 'A transaction of type "' + transaction.type_to_string() \
                    + '" to the value of ' \
                    + utils.formatDecimalAsMoney(dec_amount) \
                    + ' has been entered against the ' \
                    + account.describe()

            return render_to_response("admin_interface/" +
                                      "transaction_entered.html",
                                      {'msg' : msg},
                                      context_instance=RequestContext(request))

    # If we get here, display the form to the user.

    return render_to_response("admin_interface/enter_transaction.html",
                              {'err_msg'                  : err_msg,
                               'type'                     : type,
                               'user_id'                  : user_id,
                               'associated_user_id'       : associated_user_id,
                               'suffix'                   : suffix,
                               'other_user_id'            : other_user_id,
                               'other_associated_user_id' :
                                                       other_associated_user_id,
                               'other_suffix'             : other_suffix,
                               'amount'                   : amount,
                               'description'              : description},
                              context_instance=RequestContext(request))
Example #3
0
    def generate(self, params):
        """ Implement Report.generate().
        """
        # Start by calculating the time periods we are interested in.

        periods = [] # List of time periods.  Each list item is a dictionary
                     # with the following entries:
                     #
                     #    'start'
                     #
                     #        The start of this time period, as a datetime
                     #        object.
                     #
                     #    'end'
                     #
                     #        The end of the time period, as a datetime object.
                     #
                     #    'tot_num'
                     #
                     #        The total number of transactions in this time
                     #        period.
                     #
                     #    'tot_value'
                     #
                     #        The total value of the transactions in this time
                     #        period.

        period_size  = params['period_size']
        period_start = params['period_start']
        period_end   = params['period_end']

        if period_size == "hourly":
            period_delta = datetime.timedelta(hours=1)
        elif period_size == "daily":
            period_delta = datetime.timedelta(days=1)
        elif period_size == "weekly":
            period_delta = datetime.timedelta(days=7)
        elif period_size == "monthly":
            period_delta = datetime.timedelta(months=1)
        else:
            period_delta = datetime.timedelta(hours=1)

        while period_start < period_end:
            periods.append({'start'     : period_start,
                            'end'       : period_start + period_delta,
                            'tot_num'   : 0,
                            'tot_value' : Decimal("0.00")})
            period_start = period_start + period_delta

        # Now calculate the total value and number of transactions in each time
        # period.

        for period in periods:
            start = period['start']
            end   = period['end']
            results = Transaction.objects.filter(timestamp__gte=start,
                                                 timestamp__lt=end) \
                                 .aggregate(Count('amount'), Sum('amount'))
            period['tot_num']   = results['amount__count']
            period['tot_value'] = results['amount__sum']

        # Convert the raw data into a format suitable for display.

        for period in periods:
            period['start_label'] = period['start'].strftime(
                                                         "%d-%b-%Y %I:%M %p")
            period['end_label'] = period['end'].strftime("%d-%b-%Y %I:%M %p")
            period['tot_num_label'] = str(period['tot_num'])
            if period['tot_value'] == None:
                period['tot_value_label'] = "$0.00"
            else:
                period['tot_value_label'] = \
                    utils.formatDecimalAsMoney(period['tot_value'])

        # Finally, pass the calculated period data through our HTML template to
        # get the report in HTML format.

        return render_to_string("reporting/reports/transactionSummary.html",
                                {'params'  : params,
                                 'periods' : periods})