def amount_to_string(self): """ Return self.amount converted to a suitable string for display. """ return utils.formatDecimalAsMoney(self.amount)
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))
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})