def handle(self, *args, **options): #faster and less likely to mess stuff up. klasses = [] kl_paths = api_func('environment', 'variable_list', 'BMO_MODULES') # find all the BMO classes for path in kl_paths: for name, kl in inspect.getmembers(importlib.import_module(path), inspect.isclass): if BusinessModelObject in kl.__bases__: klasses.append(kl) with transaction.atomic(): Transaction.objects.all().delete() for cmpny in [c['id'] for c in api_func('gl', 'company')]: QueryManagerStrategyFactory().erase(cmpny) print "deleted all transactions" QueryManagerStrategyFactory().set_fast_inserts('*', True) for klass in klasses: print 'working on', klass qs =klass.objects.all() for obj in qs: obj.update_gl() print 'finished with', klass QueryManagerStrategyFactory().set_fast_inserts('*', False) QueryManagerStrategyFactory().take_snapshot('*') print "updated %d transactions" % qs.count()
def handle(self, *args, **options): #faster and less likely to mess stuff up. klasses = [] #kl_paths = accountifie.environment.api.variable({'name':'BMO_MODULES'}).split(',') kl_paths = api_func('environment', 'variable_list', 'BMO_MODULES') # find all the BMO classes for path in kl_paths: for name, kl in inspect.getmembers(importlib.import_module(path), inspect.isclass): if BusinessModelObject in kl.__bases__: klasses.append(kl) with transaction.atomic(): Transaction.objects.all().delete() for cmpny in [c['id'] for c in api_func('gl', 'company')]: QueryManagerStrategyFactory().erase(cmpny) print "deleted all transactions" QueryManagerStrategyFactory().set_fast_inserts('*', True) for klass in klasses: print 'working on', klass qs = klass.objects.all() for obj in qs: obj.update_gl() print 'finished with', klass QueryManagerStrategyFactory().set_fast_inserts('*', False) QueryManagerStrategyFactory().take_snapshot('*') print "updated %d transactions" % qs.count()
def pd_acct_balances(self, company_id, dates, paths=None, acct_list=None, excl_contra=None, excl_interco=False, cp=None, with_tags=None, excl_tags=None): if not acct_list: if paths: accts = list(itertools.chain(*[api_func('gl', 'path_accounts', p) for p in paths])) acct_list = [x['id'] for x in accts] else: acct_list = [x['id'] for x in api_func('gl', 'path_accounts', '')] dates_dict = dict((dt, utils.get_dates_dict(dates[dt])) for dt in dates) with_counterparties = [cp.id] if cp else None date_indexed_account_balances = self.gl_strategy.account_balances_for_dates(company_id, acct_list, dates_dict, with_counterparties, excl_interco, excl_contra, with_tags, excl_tags) # filter empties for dt in date_indexed_account_balances: d = date_indexed_account_balances[dt] date_indexed_account_balances[dt] = {k:d[k] for k in d if d[k] != 0.0} output = pd.DataFrame(date_indexed_account_balances) if paths: a = [[x['id'] for x in api_func('gl', 'path_accounts', path)] for path in paths] accts_list = list(itertools.chain(*a)) return output[output.index.isin(acct_list)] elif acct_list: filtered_output = output[output.index.isin(acct_list)] return filtered_output return output
def history(id, qstring={}): start_cutoff = qstring.get('from_date', None) start_date = settings.DATE_EARLY end_date = qstring.get('to_date', datetime.datetime.now().date()) cp = qstring.get('cp', None) excl = qstring.get('excl', None) incl = qstring.get('incl', None) if not start_cutoff: start_cutoff = start_of_year(end_date.year) company_ID = qstring.get( 'company_id', api_func('environment', 'variable', 'DEFAULT_COMPANY_ID')) if api_func('gl', 'account', str(id)) is not None: hist = _account_history(id, company_ID, start_date, end_date, cp) return _cutoff(start_cutoff, hist).to_dict(orient='records') elif api_func('gl', 'counterparty', id) is not None: hist = _cp_history(id, company_ID, start_date, end_date) return _cutoff(start_cutoff, hist).to_dict(orient='records') elif _is_path(id): hist = _path_history(id, company_ID, start_date, end_date, excl, incl) return _cutoff(start_cutoff, hist).to_dict(orient='records') else: return "ID %s not recognized as an account or counterparty" % id
def history(id, qstring={}): start_cutoff = qstring.get('from_date', None) start_date = settings.DATE_EARLY end_date = qstring.get('to_date', datetime.datetime.now().date()) cp = qstring.get('cp', None) excl = qstring.get('excl', None) incl = qstring.get('incl', None) if not start_cutoff: start_cutoff = start_of_year(end_date.year) company_ID = qstring.get('company_id', api_func('environment', 'variable', 'DEFAULT_COMPANY_ID')) if api_func('gl', 'account', str(id)) is not None: hist = _account_history(id, company_ID, start_date, end_date, cp) return _cutoff(start_cutoff, hist).to_dict(orient='records') elif api_func('gl', 'counterparty', id) is not None: hist = _cp_history(id, company_ID, start_date, end_date) return _cutoff(start_cutoff, hist).to_dict(orient='records') elif _is_path(id): hist = _path_history(id, company_ID, start_date, end_date, excl, incl) return _cutoff(start_cutoff, hist).to_dict(orient='records') else: return "ID %s not recognized as an account or counterparty" %id
def _recalculate(): klasses = [] kl_paths = api_func('environment', 'variable_list', 'BMO_MODULES') # find all the BMO classes for path in kl_paths: for name, kl in inspect.getmembers(importlib.import_module(path), inspect.isclass): if BusinessModelObject in kl.__bases__: klasses.append(kl) with transaction.atomic(): Transaction.objects.all().delete() for cmpny in [c['id'] for c in api_func('gl', 'company')]: QueryManagerStrategyFactory().erase(cmpny) logger.info("Recalculate -- deleted all transactions") QueryManagerStrategyFactory().set_fast_inserts('*', True) for klass in klasses: logger.info('Recalculate -- working on %s' % klass) qs =klass.objects.all() for obj in qs: obj.update_gl() logger.info('Recalculate -- finished %s' % klass) QueryManagerStrategyFactory().set_fast_inserts('*', False) QueryManagerStrategyFactory().take_snapshot('*') logger.info("Recalculate -- updated %d transactions" % qs.count()) return
def account_balances_for_dates(self, company_id, account_ids, dates, with_counterparties, excl_interco, excl_contra, with_tags, excl_tags): interco_exempt_accounts = api_func('gl', 'externalaccounts') if api_func('gl', 'company', company_id)['cmpy_type'] == 'CON': company_list = api_func('gl', 'company_list', company_id) balances = [ self.account_balances_for_dates(cmpny, account_ids, dates, with_counterparties, True, excl_contra, with_tags, excl_tags) for cmpny in company_list ] return self.__merge_account_balances_for_dates_results(balances) client = accountifieSvcClient(company_id) date_indexed_account_balances = {} interco_counterparties = self.get_interco_counterparties_for( company_id) if excl_interco else [] accounts_with_interco_exclusion = [ id for id in account_ids if id not in interco_exempt_accounts ] if excl_interco else [] accounts_without_interco_exclusion = [ id for id in account_ids if id in interco_exempt_accounts ] if excl_interco else account_ids for dt in dates: start = dates[dt]['start'] end = dates[dt]['end'] interco_excluded_balances = client.balances( accounts=accounts_with_interco_exclusion, from_date=start, to_date=end, with_counterparties=with_counterparties, excluding_counterparties=interco_counterparties, excluding_contra_accounts=excl_contra, with_tags=with_tags, excluding_tags=excl_tags ) if len(accounts_with_interco_exclusion) > 0 else [] interco_included_balances = client.balances( accounts=accounts_without_interco_exclusion, from_date=start, to_date=end, with_counterparties=with_counterparties, excluding_contra_accounts=excl_contra, with_tags=with_tags, excluding_tags=excl_tags ) if len(accounts_without_interco_exclusion) > 0 else [] balances = interco_excluded_balances + interco_included_balances date_indexed_account_balances[dt] = dict( (balance['id'], float(balance['shift'])) for balance in balances) return date_indexed_account_balances
def fulfill_requested(self): fulfillment_labels = [x['order'] for x in api_func('inventory', 'fulfillment')] order_label = api_func('base', 'sale', unicode(order_id))['label'] if order_label in fulfillment_labels: return True else: return False
def balance_history(request, type, id): from_date, to_date = utils.extractDateRange(request) company_ID = utils.get_company(request) if type == 'account': cp = request.GET.get('cp',None) acct = api_func('gl', 'account', id) display_name = '%s: %s' %(acct['id'], acct['display_name']) history = accountifie.query.query_manager.QueryManager().pd_history(company_ID, 'account', acct['id'], from_date=from_date, to_date=to_date, cp=cp) if cp and not history.empty: history = history[history['counterparty']==cp] display_name += ' -- %s' % cp balance_history = history[['amount','date']].groupby('date').sum().cumsum().reset_index() column_titles = ['date', 'amount'] elif type == 'path': ref = id.replace('_','.') display_name = 'path: %s' % ref excl = request.GET['excl'].split(',') if request.GET.has_key('excl') else None incl = request.GET['incl'].split(',') if request.GET.has_key('incl') else None if excl: excl = [x.replace('_','.') for x in excl] display_name += ' -- excl %s' % ','.join(excl) if incl: incl = [x.replace('_','.') for x in incl] display_name += ' -- incl %s' % ','.join(incl) history = accountifie.query.query_manager.QueryManager().pd_history(company_ID, type, ref, from_date=from_date, to_date=to_date, excl_contra=excl, incl=incl) balance_history = history[['amount','date']].groupby('date').sum().cumsum().reset_index() column_titles = ['date', 'amount'] elif type == 'creditor': cp = request.GET.get('cp',None) cp_info = api_func('gl', 'counterparty', id) display_name = '%s: %s' %(cp_info['id'], cp_info['name']) history = accountifie.query.query_manager.QueryManager().pd_history(company_ID, 'account', '3000', from_date=from_date, to_date=to_date, cp=id) history = history[history['counterparty']==id] balance_history = history[['amount','date']].groupby('date').sum().cumsum().reset_index() column_titles = ['date', 'amount'] else: raise ValueError('This type of history is not supported') years = Year.objects.all() entries = [] if balance_history is not None: for i in balance_history.index: entries.append(create_row(balance_history.loc[i], column_titles)) context = {} context['display_name'] = display_name context['column_titles'] = column_titles context['history'] = entries context['years'] = years context['by_date_cleared'] = False context['from_date'] = from_date context['to_date'] = to_date return render_to_response('bal_history.html', RequestContext(request, context))
def _get_calcs(url): path, qs = _get_model_call(url) if path == 'BAD_PATH_URL': return if len(path) == 3: return api_func(path[1], path[2], qstring=qs) elif len(path) == 4: return api_func(path[1], path[2], path[3], qstring=qs)
def __inter_co(row): ext_accts = api_func('gl', 'externalaccounts') companies = [cmpy['id'] for cmpy in api_func('gl', 'company')] if row['account_id'] in ext_accts: return False if row['counterparty'] in companies: return True else: return False
def __inter_co(row): ext_accts = api_func('gl', 'externalaccounts') companies = [cmpy['id'] for cmpy in api_func('gl', 'company') if cmpy['id']!=company] if row['account_id'] in ext_accts: return False if row['counterparty'] in companies: return True else: return False
def transactions(self, company_id, account_ids, from_date, to_date, chunk_frequency, with_counterparties, excl_interco, excl_contra): interco_exempt_accounts = api_func('gl', 'externalaccounts') if api_func('gl', 'company', company_id)['cmpy_type'] == 'CON': company_list = api_func('gl', 'company_list', company_id) balances = [self.transactions(cmpny, account_ids, from_date, to_date, chunk_frequency, with_counterparties, True, excl_contra) for cmpny in company_list] return self.__merge_transactions_results(balances) client = accountifieSvcClient(company_id) interco_counterparties = self.get_interco_counterparties_for(company_id) if excl_interco else [] accounts_with_interco_exclusion = [id for id in account_ids if id not in interco_exempt_accounts] if excl_interco else [] accounts_without_interco_exclusion = [id for id in account_ids if id in interco_exempt_accounts] if excl_interco else account_ids interco_excluded_transactions = client.transactions( accounts=accounts_with_interco_exclusion, from_date=from_date, to_date=to_date, chunk_frequency=chunk_frequency, excluding_counterparties=interco_counterparties, with_counterparties=with_counterparties, excluding_contra_accounts=excl_contra ) if len(accounts_with_interco_exclusion) > 0 else {} interco_included_transactions = client.transactions( accounts=accounts_without_interco_exclusion, from_date=from_date, to_date=to_date, chunk_frequency=chunk_frequency, with_counterparties=with_counterparties, excluding_contra_accounts=excl_contra ) if len(accounts_without_interco_exclusion) > 0 else {} # merge the two dictionaries transactions = interco_excluded_transactions.copy() transactions.update(interco_included_transactions) make_contras = lambda x: 'more than two' if len(x)>2 else '.'.join(x) formatted_transactions = [] for account in transactions: for transaction in transactions[account]: if transaction['amount'] != '0.00': formatted_transactions.append({ 'date': parse(transaction['dateEnd'] if ('dateEnd' in transaction and transaction['dateEnd']) else transaction['date']).date(), 'id': transaction['id'], 'comment': transaction['comment'], 'account_id': account, 'contra_accts': make_contras(transaction['contraAccounts']), 'counterparty': transaction['counterparty'], 'amount': float(transaction['amount']) }) return formatted_transactions
def inventory_counts(request): context = {} inventory_count = api_func('inventory', 'inventorycount') context = dict(('%s_count' % k, v) for k, v in inventory_count.iteritems()) sales_counts = api_func('sales', 'sales_counts') for sku in sales_counts: context['%s_percent_sold' % sku] = int(100.0 * float(sales_counts[sku]) / float(inventory_count[sku])) context['%s_sold' % sku] = sales_counts[sku] context['location_counts'] = api_func('inventory', 'locationinventory') return render(request, 'inventory.html', context)
def pd_acct_balances(self, company_id, dates, paths=None, acct_list=None, excl_contra=None, excl_interco=False, cp=None, with_tags=None, excl_tags=None): if not acct_list: if paths: accts = list( itertools.chain( *[api_func('gl', 'path_accounts', p) for p in paths])) acct_list = [x['id'] for x in accts] else: acct_list = [ x['id'] for x in api_func('gl', 'path_accounts', '') ] dates_dict = dict( (dt, utils.get_dates_dict(dates[dt])) for dt in dates) with_counterparties = [cp.id] if cp else None date_indexed_account_balances = self.gl_strategy.account_balances_for_dates( company_id, acct_list, dates_dict, with_counterparties, excl_interco, excl_contra, with_tags, excl_tags) # filter empties for dt in date_indexed_account_balances: d = date_indexed_account_balances[dt] date_indexed_account_balances[dt] = { k: d[k] for k in d if d[k] != 0.0 } output = pd.DataFrame(date_indexed_account_balances) if paths: a = [[x['id'] for x in api_func('gl', 'path_accounts', path)] for path in paths] accts_list = list(itertools.chain(*a)) return output[output.index.isin(acct_list)] elif acct_list: filtered_output = output[output.index.isin(acct_list)] return filtered_output return output
def download_ledger(request): from_date, to_date = utils.extractDateRange(request) company_ID = utils.get_company(request) accts = api_func('gl', 'accounts') response = HttpResponse(content_type='text/csv') response['Content-Disposition'] = 'attachment; filename="ledger.csv"' writer = csv.writer(response) header_row = [ 'id', 'date', 'comment', 'contra_accts', 'counterparty', 'amount', 'balance' ] for acct in accts: history = accountifie.reporting.api.history({ 'type': 'account', 'from_date': from_date, 'to_date': to_date, 'company_ID': company_ID, 'id': acct['id'] }) if len(history) > 0: writer.writerow([]) writer.writerow([acct['id'], acct['display_name'], acct['path']]) writer.writerow([]) writer.writerow(header_row) for idx in history.index: writer.writerow([history.loc[idx, col] for col in header_row]) return response
def get_gl_transactions(self): """ Make transfers to inventory accounts. Inventory costs are booked to the 'omnibus'. inventory account. This function books transfers to the inventory accounts specific to each SKU. """ product_line = self.inventory_item.product_line.label inv_item = self.inventory_item.label inv_acct_path = 'assets.curr.inventory.%s.%s' % (product_line, inv_item) inv_acct = accountifie.gl.models.Account.objects.filter(path=inv_acct_path).first() GEN_INVENTORY = api_func('environment', 'variable', 'GL_INVENTORY') gen_inv_acct = accountifie.gl.models.Account.objects.get(id=GEN_INVENTORY) counterparty = self.shipment.sent_by amount = Decimal(self.cost) * Decimal(self.quantity) tran = [] tran = dict(company=self.company, date=self.shipment.arrival_date, comment="%s" % str(self), trans_id='%s.%s.LINE' % (self.short_code, self.id), bmo_id='%s.%s' % (self.short_code, self.id), lines=[(inv_acct, amount, counterparty, []), (gen_inv_acct, -amount, counterparty, [])] ) return [tran]
def __pd_balances_prep(self, company_id, account_ids, excl_contra=None, excl_interco=False, with_counterparties=None): if api_func('gl', 'company', company_id)['cmpy_type'] == 'CON': excl_interco = True entries = self.get_gl_entries(company_id, account_ids) if entries is None or entries.empty: return None if excl_contra: for contra in excl_contra: entries = entries[entries.contra_accts.map(lambda x: contra not in x.split(','))] if excl_interco: entries = entries[~entries.apply(self.__inter_co, axis=1)] if with_counterparties: entries = entries[entries['counterparty'] in with_counterparties] if entries.empty: return None clean_end = lambda row: row['date_end'] if row['date_end'] else row['date'] entries['date_end'] = entries.apply(clean_end, axis=1) return entries
def __pd_balances_prep(self, company_id, account_ids, excl_contra=None, excl_interco=False, with_counterparties=None): if api_func('gl', 'company', company_id)['cmpy_type'] == 'CON': excl_interco = True entries = self.get_gl_entries(company_id, account_ids) if entries is None or entries.empty: return None if excl_contra: for contra in excl_contra: entries = entries[entries.contra_accts.map( lambda x: contra not in x.split(','))] if excl_interco: entries = entries[~entries.apply(self.__inter_co, axis=1)] if with_counterparties: entries = entries[entries['counterparty'] in with_counterparties] if entries.empty: return None clean_end = lambda row: row['date_end'] if row['date_end'] else row[ 'date'] entries['date_end'] = entries.apply(clean_end, axis=1) return entries
def lpq(): base_url = api_func('environment', 'variable', 'ACCOUNTIFIE_SVC_URL') url = '%s/lpq/stats' % base_url request = urllib2.Request(url) response = urllib2.urlopen(request) json_result = json.load(response) return json_result
def pd_path_balances(self, company_id, dates, paths, filter_zeros=True, assets=False, excl_contra=None, excl_interco=False, with_tags=None, excl_tags=None): path_accts = dict((p, [x['id'] for x in api_func('gl', 'path_accounts', p)]) for p in paths) acct_list = list(itertools.chain(*[path_accts[p] for p in paths])) dates_dict = dict((dt, utils.get_dates_dict(dates[dt])) for dt in dates) date_indexed_account_balances = self.gl_strategy.account_balances_for_dates(company_id, acct_list, dates_dict, None, excl_interco, excl_contra, with_tags, excl_tags) data = {} for dt in date_indexed_account_balances: account_balances = date_indexed_account_balances[dt] tuples = [] for path in paths: path_sum = 0 for account_id in path_accts[path]: if account_id in account_balances: path_sum -= account_balances[account_id] tuples.append((path, path_sum)) data[dt] = dict(tuples) output = pd.DataFrame(data) if filter_zeros: output['empty'] = output.apply(lambda row: np.all(row.values == 0.0), axis=1) output = output[output['empty']==False] output.drop('empty', axis=1, inplace=True) # adjust assets sign if assets: asset_factor = output.index.map(lambda x: -1.0 if x[:6] == 'assets' else 1.0) for col in output.columns: output[col] = output[col] * asset_factor return output
def get_company_name(company_id): company_names = dict( (entry['id'], entry['name']) for entry in api_func('gl', 'company')) try: return company_names[company_id] except: return 'Unknown Company'
def balance_trends(params): dt = parse(params['date']) accounts = api_func('gl', 'account') if 'accts_path' in params: acct_list = [x['id'] for x in accounts if params['accts_path'] in x['path']] else: acct_list = params['acct_list'].split('.') gl_strategy = params.get('gl_strategy', None) company_id = params.get('company_id', utils.get_default_company()) # 3 months for now report = get_report('AccountActivity', company_id, version='v1') report.set_gl_strategy(gl_strategy) M_1 = utils.end_of_prev_month(dt.month, dt.year) M_2 = utils.end_of_prev_month(M_1.month, M_1.year) three_mth = {} three_mth['M_0'] = '%dM%s' % (dt.year, '{:02d}'.format(dt.month)) three_mth['M_1'] = '%dM%s' % (M_1.year, '{:02d}'.format(M_1.month)) three_mth['M_2'] = '%dM%s' % (M_2.year, '{:02d}'.format(M_2.month)) three_mth_order = ['M_2','M_1','M_0'] col_tag = '%dM%s' % (dt.year, '{:02d}'.format(dt.month)) report.configure(col_tag=col_tag) report.columns = three_mth report.column_order = three_mth_order report.acct_list = acct_list return [x for x in report.calcs() if x['fmt_tag']!='header']
def get_interco_counterparties_for(company): output = [ cmpy['id'] for cmpy in api_func('gl', 'company') if cmpy['id'] != company and cmpy['cmpy_type'] == 'ALO' ] output += [x.lower() for x in output] return output
def calcs(self): data = {} idx = {} self.link_map = lambda x: '/snapshot/glsnapshots/reconcile/%s/%s?date=%s' % (self.snapshot.id, x, self.snapshot.closing_date.isoformat()) snapshot_strategy = QueryManager(gl_strategy=self.qm_strategy) if self.qm_strategy else self.query_manager snap_bals = snapshot_strategy.pd_acct_balances(self.company_id,{'snapshot': self.date}).fillna(DZERO) curr_bals = self.query_manager.pd_acct_balances(self.company_id,{'current': self.date}).fillna(DZERO) self.column_order = ['snapshot', 'current','diff'] bals = pd.concat([snap_bals, curr_bals], axis=1).fillna(0.0) bals['diff'] = bals['current'] - bals['snapshot'] bals.loc['Total'] = bals.apply(sum, axis=0) accts = api_func('gl', 'account') acct_map = dict((a['id'], a['display_name']) for a in accts) label_map = lambda x: x + ': ' + acct_map[x] if x in acct_map else x bals['fmt_tag'] = 'item' bals['label'] = bals.index.map(label_map) bals['link'] = bals.index.map(self.link_map) bals.loc['Total', 'fmt_tag'] = 'major_total' table_data = bals.to_dict(orient='records') for row in table_data: if row['fmt_tag'] != 'header': for col in self.column_order: row[col] = {'text': row[col], 'link': row['link']} return table_data
def gl_stats(company_id): base_url = api_func('environment', 'variable', 'ACCOUNTIFIE_SVC_URL') url = '%s/gl/%s/stats' % (base_url, company_id) request = urllib2.Request(url) response = urllib2.urlopen(request) json_result = json.load(response) return json_result
def calcs(self): bals = self.query_manager.pd_acct_balances(self.company_id, {'balance': self.date}) accts = api_func('gl', 'account') accts_map = dict((a['id'], a) for a in accts) # dataframe.apply won't work until v0.17 for lambda returning dict... so have to do in roundabout way till then debits_map = lambda x: x['balance'] if accts_map[x.name]['role'] in ['asset', 'expense'] else 0 credits_map = lambda x: -x['balance'] if accts_map[x.name]['role'] in ['liability', 'income', 'capital'] else 0 bals['Debits'] = bals.apply(debits_map, axis=1) bals['Credits'] = bals.apply(credits_map, axis=1) del bals['balance'] bals['fmt_tag'] = 'item' label_map = lambda x: x + ': ' + accts_map[x]['display_name'] bals['label'] = bals.index.map(label_map) totals = bals[self.column_order].sum(axis=0) totals['fmt_tag'] = 'major_total' totals['label'] = 'Totals' bals.loc['Total'] = totals bals['index'] = bals.index data = bals.to_dict(orient='records') credits_link_map = lambda x: utils.acct_history_link(x['index']) if x['index'] != 'Total' and x['Credits'] != '' else '' debits_link_map = lambda x: utils.acct_history_link(x['index']) if x['index'] != 'Total' and x['Debits'] != '' else '' for row in data: row['Credits'] = {'text': row['Credits'], 'link':credits_link_map(row)} row['Debits'] = {'text': row['Debits'], 'link': debits_link_map(row)} return data
def __default_strategy(self): if self.force_default_strategy: return self.force_default_strategy try: return api_func('environment', 'variable', 'DEFAULT_GL_STRATEGY') except: return settings.DEFAULT_GL_STRATEGY
def save(self): models.Model.save(self) logger.info('saving snapshot with snapshot time %s' % self.snapped_at) # now create snapshot for company_id in [c['id'] for c in api_func('gl', 'company') if c['cmpy_type']=='ALO']: fmt = '%Y-%m-%dT%H:%M:%SZ' snapshot_time = self.snapped_at.astimezone(UTC).strftime(fmt) QueryManagerStrategyFactory().get().take_snapshot(company_id, snapshot_time=snapshot_time)
def history(params): from_date = params['from_date'] to_date = params['to_date'] company_ID = params['company_ID'] cp = params.get('cp', None) type = params.get('type', None) id = params.get('id', None) if type == 'account': acct = api_func('gl', 'account', id) display_name = '%s: %s' %(acct['id'], acct['display_name']) history = accountifie.query.query_manager.QueryManager().pd_history(company_ID, 'account', acct['id'], from_date=from_date, to_date=to_date, cp=cp) if cp and not history.empty: history = history[history['counterparty']==cp] history['balance'] = history['amount'].cumsum() display_name += ' -- %s' % cp column_titles = ['id', 'date', 'comment', 'contra_accts', 'counterparty', 'amount', 'balance'] elif type == 'path': ref = id.replace('_','.') display_name = 'path: %s' % ref excl = request.GET['excl'].split(',') if request.GET.has_key('excl') else None incl = request.GET['incl'].split(',') if request.GET.has_key('incl') else None if excl: excl = [x.replace('_','.') for x in excl] display_name += ' -- excl %s' % ','.join(excl) if incl: incl = [x.replace('_','.') for x in incl] display_name += ' -- incl %s' % ','.join(incl) history = accountifie.query.query_manager.QueryManager().pd_history(company_ID, type, ref, from_date=from_date, to_date=to_date, excl_contra=excl, incl=incl) column_titles = ['id', 'date', 'comment', 'account_id', 'contra_accts', 'counterparty', 'amount', 'balance'] elif type == 'creditor': cp_info = api_func('gl', 'counterparty', id) display_name = '%s: %s' %(cp_info['id'], cp_info['name']) history = accountifie.query.query_manager.QueryManager().pd_history(company_ID, 'account', '3000', from_date=from_date, to_date=to_date, cp=id) history = history[history['counterparty']==id] history['balance'] = history['amount'].cumsum() column_titles = ['id', 'date', 'comment', 'contra_accts', 'amount', 'balance'] else: raise ValueError('This type of history is not supported') return history
def account_balances_for_dates(self, company_id, account_ids, dates, with_counterparties, excl_interco, excl_contra, with_tags, excl_tags): interco_exempt_accounts = api_func('gl', 'externalaccounts') if api_func('gl', 'company', company_id)['cmpy_type'] == 'CON': company_list = api_func('gl', 'company_list', company_id) balances = [self.account_balances_for_dates(cmpny, account_ids, dates, with_counterparties, True, excl_contra, with_tags, excl_tags) for cmpny in company_list] return self.__merge_account_balances_for_dates_results(balances) client = accountifieSvcClient(company_id) date_indexed_account_balances = {} interco_counterparties = self.get_interco_counterparties_for(company_id) if excl_interco else [] accounts_with_interco_exclusion = [id for id in account_ids if id not in interco_exempt_accounts] if excl_interco else [] accounts_without_interco_exclusion = [id for id in account_ids if id in interco_exempt_accounts] if excl_interco else account_ids for dt in dates: start = dates[dt]['start'] end = dates[dt]['end'] interco_excluded_balances = client.balances( accounts=accounts_with_interco_exclusion, from_date=start, to_date=end, with_counterparties=with_counterparties, excluding_counterparties=interco_counterparties, excluding_contra_accounts=excl_contra, with_tags=with_tags, excluding_tags=excl_tags ) if len(accounts_with_interco_exclusion) > 0 else [] interco_included_balances = client.balances( accounts=accounts_without_interco_exclusion, from_date=start, to_date=end, with_counterparties=with_counterparties, excluding_contra_accounts=excl_contra, with_tags=with_tags, excluding_tags=excl_tags ) if len(accounts_without_interco_exclusion) > 0 else [] balances = interco_excluded_balances + interco_included_balances date_indexed_account_balances[dt] = dict((balance['id'], float(balance['shift'])) for balance in balances) return date_indexed_account_balances
def company_context(request): """Context processor referenced in settings. This puts the current company ID into any request context, thus allowing templates to refer to it This is not a view. """ company_id = utils.get_company(request) data = {"company_id": company_id, "logo": settings.LOGO, "site_title": settings.SITE_TITLE} data["admin_site_title"] = settings.SITE_TITLE data["DJANGO_18"] = settings.DJANGO_18 data["DJANGO_19"] = settings.DJANGO_19 data["company_color"] = api_func("gl", "company", company_id)["color_code"] data["menu_items"] = OrderedDict( [ ("Reports", "/reports/"), ("Daily", "/daily/"), ("Inventory", "/inventory"), ("Snapshots", "/snapshot/glsnapshots"), ] ) data["power_menu_items"] = OrderedDict( [ ("Admin", "/admin/"), ("Maintenance", "/maintenance/"), ("Dashboard", "/dashboard/"), ("Logs", "/dashboard/logs/"), ] ) data["company_list"] = [x["id"] for x in api_func("gl", "company")] if company_id: try: company = Company.objects.get(pk=company_id) data.update({"company": company}) except Company.DoesNotExist: pass return data
def transaction_info(params): trans_id = params['id'] # no way right now to know whether which company it is in companies = [cmpy['id'] for cmpy in api_func('gl', 'companies') if cmpy['cmpy_type']=='ALO'] for cmpny in companies: info = QM.QueryManager().transaction_info(cmpny, trans_id) if len(info)>0: return info return None
def pd_history(self, company_id, q_type, id, from_date=settings.DATE_EARLY, to_date=settings.DATE_LATE, excl_interco=None, excl_contra=None, incl=None, cp=None): if api_func('gl', 'company', company_id)['cmpy_type'] == 'CON': excl_interco = True if q_type == 'account': acct_list = [id] elif q_type == 'account_list': acct_list = incl elif q_type=='path': acct_list = [x['id'] for x in api_func('gl', 'path_accounts', id, qstring={'excl': excl_contra, 'incl': incl})] else: raise ValueError('History not implemented for this type') with_counterparties = [cp] if cp else None all_entries = self.gl_strategy.transactions(company_id, acct_list, from_date, to_date, 'end-of-month', with_counterparties, excl_interco, excl_contra) if all_entries is None or len(all_entries) == 0: return pd.DataFrame() clean_end = lambda row: row['date_end'] if row['date_end'] else row['date'] period_entries = [] all_entries_pd = pd.DataFrame(all_entries) all_entries_pd.sort(['date', 'id'], ascending=[1, 0], inplace=True) cols = ['date', 'id', 'comment', 'account_id', 'contra_accts', 'counterparty', 'amount'] top_line = pd.Series(dict((col, None) for col in cols)) top_line['date'] = utils.day_before(all_entries_pd.iloc[0]['date']) top_line['amount'] = 0.0 top_line['comment'] = 'Opening Balance' all_entries_pd.reset_index(drop=True, inplace=True) all_entries_pd.loc['starting'] = top_line all_entries_pd.sort_index(by='date', axis=0, inplace=True) all_entries_pd['balance'] = all_entries_pd['amount'].cumsum() return all_entries_pd[cols + ['balance']]
def balance_history(id, qstring={}): start_cutoff = qstring.get('from_date', None) start_date = settings.DATE_EARLY end_date = qstring.get('to_date', datetime.datetime.now().date()) cp = qstring.get('cp', None) excl = qstring.get('excl', None) incl = qstring.get('incl', None) if not start_cutoff: start_cutoff = start_of_year(end_date.year) company_ID = qstring.get( 'company_id', api_func('environment', 'variable', 'DEFAULT_COMPANY_ID')) if api_func('gl', 'account', str(id)) is not None: hist = _account_history(id, company_ID, start_date, end_date, cp) hist = _cutoff(start_cutoff, hist) elif api_func('gl', 'counterparty', id) is not None: hist = _cp_history(id, company_ID, start_date, end_date) hist = _cutoff(start_cutoff, hist) elif _is_path(id): hist = _path_history(id, company_ID, start_date, end_date, excl, incl) hist = _cutoff(start_cutoff, hist) else: return "ID %s not recognized as an account or counterparty" % id hist['idx'] = hist.index date_indices = hist[['date', 'idx']].groupby('date').max() balances = hist.loc[date_indices['idx']][['date', 'balance']] balances.index = balances['date'] del balances['date'] dates = daterange(balances.index[0], balances.index[-1], bus_days_only=True) filled_balances = pd.DataFrame(index=dates) filled_balances['balance'] = balances['balance'] filled_balances.fillna(method='ffill', inplace=True) filled_balances.index = filled_balances.index.map(lambda x: x.isoformat()) return filled_balances['balance'].to_dict()
def __init__(self): self.force_default_strategy = None self.strategy_singletons = { 'remote': QueryManagerRemoteStrategy(), 'local': QueryManagerLocalStrategy() } try: self.noop_mutating_functions = api_func('environment', 'variable', 'DISABLE_ACCOUNTIFIE_SVC_MUTATES') == 'true' except: self.noop_mutating_functions = False
def transactions(self, company_id, from_date=settings.DATE_EARLY, to_date=settings.DATE_LATE): acct_list = [x['id'] for x in api_func('gl', 'account')] all_entries = self.gl_strategy.transactions(company_id, acct_list, from_date, to_date, 'end-of-month', None, None, None) return all_entries
def download_transactions(request): company_ID = utils.get_company(request) snapshot_time = datetime.datetime.now() strategy = QueryManagerStrategyFactory().get('snapshot') strategy.set_cache(None) trans = strategy.get_all_transactions(company_ID) all_accts_list = api_func('gl', 'account') all_accts = dict((r['id'], r) for r in all_accts_list) response = HttpResponse(content_type='text/csv') response['Content-Disposition'] = 'attachment; filename="transactions.csv"' writer = csv.writer(response) writer.writerow(['', '', '', '', '', '','debit', 'debit', 'debit', 'debit','credit', 'credit', 'credit', 'credit']) writer.writerow(['Id', 'dateEnd', 'date', 'type', 'comment', 'counterpartyId', 'amount', 'accountId', 'account name','counterpartyId', 'amount', 'accountId', 'account name']) for ex in trans: first_line = ex['lines'][0] acct_id = first_line['accountId'] acct = api_func('gl', 'account', acct_id) if (acct['role'] in ['asset', 'expense'] and float(first_line['amount']) >0) or \ (acct['role'] in ['liability', 'income', 'capital'] and float(first_line['amount']) < 0): debit = ex['lines'][0] credit = ex['lines'][1] else: debit = ex['lines'][1] credit = ex['lines'][0] row = [ex[k] for k in ['bmoId', 'dateEnd', 'date', 'type', 'comment']] row += [debit[k] for k in ['counterpartyId', 'amount', 'accountId']] row.append(all_accts[debit['accountId']]['display_name']) row += [credit[k] for k in ['counterpartyId', 'amount', 'accountId']] row.append(all_accts[credit['accountId']]['display_name']) writer.writerow(row) return response
def save(self): models.Model.save(self) logger.info('saving snapshot with snapshot time %s' % self.snapped_at) # now create snapshot for company_id in [ c['id'] for c in api_func('gl', 'company') if c['cmpy_type'] == 'ALO' ]: fmt = '%Y-%m-%dT%H:%M:%SZ' snapshot_time = self.snapped_at.astimezone(UTC).strftime(fmt) QueryManagerStrategyFactory().get().take_snapshot( company_id, snapshot_time=snapshot_time)
def __init__(self): self.force_default_strategy = None self.strategy_singletons = { 'remote': QueryManagerRemoteStrategy(), 'local': QueryManagerLocalStrategy() } try: self.noop_mutating_functions = api_func( 'environment', 'variable', 'DISABLE_ACCOUNTIFIE_SVC_MUTATES') == 'true' except: self.noop_mutating_functions = False
def __init__(self, company_id, date=None): self.date = date self.description = 'Trial Balance' self.title = "Trial Balance" self.company_id = company_id self.columns = {'Debits':'Debits', 'Credits': 'Credits'} self.calc_type = 'as_of' self.set_company() self.works_for = [cmpny['id'] for cmpny in api_func('gl', 'company')] self.column_order = ['Debits', 'Credits'] self.label_map = None self.link_map = lambda x: utils.acct_history_link(x.name)
def balance_history(id, qstring={}): start_cutoff = qstring.get('from_date', None) start_date = settings.DATE_EARLY end_date = qstring.get('to_date', datetime.datetime.now().date()) cp = qstring.get('cp', None) excl = qstring.get('excl', None) incl = qstring.get('incl', None) if not start_cutoff: start_cutoff = start_of_year(end_date.year) company_ID = qstring.get('company_id', api_func('environment', 'variable', 'DEFAULT_COMPANY_ID')) if api_func('gl', 'account', str(id)) is not None: hist = _account_history(id, company_ID, start_date, end_date, cp) hist = _cutoff(start_cutoff, hist) elif api_func('gl', 'counterparty', id) is not None: hist = _cp_history(id, company_ID, start_date, end_date) hist = _cutoff(start_cutoff, hist) elif _is_path(id): hist = _path_history(id, company_ID, start_date, end_date, excl, incl) hist = _cutoff(start_cutoff, hist) else: return "ID %s not recognized as an account or counterparty" %id hist['idx'] = hist.index date_indices = hist[['date','idx']].groupby('date').max() balances = hist.loc[date_indices['idx']][['date','balance']] balances.index = balances['date'] del balances['date'] dates = daterange(balances.index[0], balances.index[-1], bus_days_only=True) filled_balances = pd.DataFrame(index=dates) filled_balances['balance'] = balances['balance'] filled_balances.fillna(method='ffill', inplace=True) filled_balances.index = filled_balances.index.map(lambda x: x.isoformat()) return filled_balances['balance'].to_dict()
def path_drilldown(self, company_id, dates, path, excl_contra=None, excl_interco=None): paths = api_func('gl', 'child_paths', path) output = self.pd_path_balances(company_id, dates, paths, excl_contra=excl_contra, excl_interco=excl_interco) return output
def pd_path_balances(self, company_id, dates, paths, filter_zeros=True, assets=False, excl_contra=None, excl_interco=False, with_tags=None, excl_tags=None): path_accts = dict( (p, [x['id'] for x in api_func('gl', 'path_accounts', p)]) for p in paths) acct_list = list(itertools.chain(*[path_accts[p] for p in paths])) dates_dict = dict( (dt, utils.get_dates_dict(dates[dt])) for dt in dates) date_indexed_account_balances = self.gl_strategy.account_balances_for_dates( company_id, acct_list, dates_dict, None, excl_interco, excl_contra, with_tags, excl_tags) data = {} for dt in date_indexed_account_balances: account_balances = date_indexed_account_balances[dt] tuples = [] for path in paths: path_sum = 0 for account_id in path_accts[path]: if account_id in account_balances: path_sum -= account_balances[account_id] tuples.append((path, path_sum)) data[dt] = dict(tuples) output = pd.DataFrame(data) if filter_zeros: output['empty'] = output.apply( lambda row: np.all(row.values == 0.0), axis=1) output = output[output['empty'] == False] output.drop('empty', axis=1, inplace=True) # adjust assets sign if assets: asset_factor = output.index.map(lambda x: -1.0 if x[:6] == 'assets' else 1.0) for col in output.columns: output[col] = output[col] * asset_factor return output
def __init__(self, company_id, date=None): self.date = date self.description = 'Account Activity' self.title = None self.company_id = company_id self.columns = None self.column_order = None self.calc_type = 'as_of' self.set_company() self.label_map = None self.link_map = lambda x: utils.acct_history_link(x.name) self.equity_sign = False self.path = None self.acct_list = None self.works_for = [cmpny['id'] for cmpny in api_func('gl', 'company')]
def download_ledger(request): from_date, to_date = utils.extractDateRange(request) company_ID = utils.get_company(request) accts = api_func('gl', 'accounts') response = HttpResponse(content_type='text/csv') response['Content-Disposition'] = 'attachment; filename="ledger.csv"' writer = csv.writer(response) header_row = ['id', 'date', 'comment', 'contra_accts', 'counterparty', 'amount', 'balance'] for acct in accts: history = accountifie.reporting.api.history({'type': 'account', 'from_date': from_date, 'to_date': to_date, 'company_ID': company_ID, 'id': acct['id']}) if len(history) > 0: writer.writerow([]) writer.writerow([acct['id'], acct['display_name'], acct['path']]) writer.writerow([]) writer.writerow(header_row) for idx in history.index: writer.writerow([history.loc[idx, col] for col in header_row]) return response
def counterparty_list(request): "Show list of each account" counterparties = api_func('gl', 'counterparty') AP_acct = api_func('environment', 'variable', 'GL_ACCOUNTS_PAYABLE') return render_to_response('gl/counterparty_list.html', RequestContext(request, dict(ap_acct=AP_acct, counterparties=counterparties)))
def transactions(self, company_id, account_ids, from_date, to_date, chunk_frequency, with_counterparties, excl_interco, excl_contra): interco_exempt_accounts = api_func('gl', 'externalaccounts') if api_func('gl', 'company', company_id)['cmpy_type'] == 'CON': company_list = api_func('gl', 'company_list', company_id) balances = [ self.transactions(cmpny, account_ids, from_date, to_date, chunk_frequency, with_counterparties, True, excl_contra) for cmpny in company_list ] return self.__merge_transactions_results(balances) client = accountifieSvcClient(company_id) interco_counterparties = self.get_interco_counterparties_for( company_id) if excl_interco else [] accounts_with_interco_exclusion = [ id for id in account_ids if id not in interco_exempt_accounts ] if excl_interco else [] accounts_without_interco_exclusion = [ id for id in account_ids if id in interco_exempt_accounts ] if excl_interco else account_ids interco_excluded_transactions = client.transactions( accounts=accounts_with_interco_exclusion, from_date=from_date, to_date=to_date, chunk_frequency=chunk_frequency, excluding_counterparties=interco_counterparties, with_counterparties=with_counterparties, excluding_contra_accounts=excl_contra ) if len(accounts_with_interco_exclusion) > 0 else {} interco_included_transactions = client.transactions( accounts=accounts_without_interco_exclusion, from_date=from_date, to_date=to_date, chunk_frequency=chunk_frequency, with_counterparties=with_counterparties, excluding_contra_accounts=excl_contra ) if len(accounts_without_interco_exclusion) > 0 else {} # merge the two dictionaries transactions = interco_excluded_transactions.copy() transactions.update(interco_included_transactions) make_contras = lambda x: 'more than two' if len(x) > 2 else '.'.join(x) formatted_transactions = [] for account in transactions: for transaction in transactions[account]: if transaction['amount'] != '0.00': formatted_transactions.append({ 'date': parse(transaction['dateEnd'] if ( 'dateEnd' in transaction and transaction['dateEnd'] ) else transaction['date']).date(), 'id': transaction['id'], 'comment': transaction['comment'], 'account_id': account, 'contra_accts': make_contras(transaction['contraAccounts']), 'counterparty': transaction['counterparty'], 'amount': float(transaction['amount']) }) return formatted_transactions
def __accountifie_svc_url(): return api_func('environment', 'variable', 'ACCOUNTIFIE_SVC_URL')
def pd_history(self, company_id, q_type, id, from_date=settings.DATE_EARLY, to_date=settings.DATE_LATE, excl_interco=None, excl_contra=None, incl=None, cp=None): if api_func('gl', 'company', company_id)['cmpy_type'] == 'CON': excl_interco = True if q_type == 'account': acct_list = [id] elif q_type == 'account_list': acct_list = incl elif q_type == 'path': acct_list = [ x['id'] for x in api_func('gl', 'path_accounts', id, qstring={ 'excl': excl_contra, 'incl': incl }) ] else: raise ValueError('History not implemented for this type') with_counterparties = [cp] if cp else None all_entries = self.gl_strategy.transactions(company_id, acct_list, from_date, to_date, 'end-of-month', with_counterparties, excl_interco, excl_contra) if all_entries is None or len(all_entries) == 0: return pd.DataFrame() clean_end = lambda row: row['date_end'] if row['date_end'] else row[ 'date'] period_entries = [] all_entries_pd = pd.DataFrame(all_entries) all_entries_pd.sort(['date', 'id'], ascending=[1, 0], inplace=True) cols = [ 'date', 'id', 'comment', 'account_id', 'contra_accts', 'counterparty', 'amount' ] top_line = pd.Series(dict((col, None) for col in cols)) top_line['date'] = utils.day_before(all_entries_pd.iloc[0]['date']) top_line['amount'] = 0.0 top_line['comment'] = 'Opening Balance' all_entries_pd.reset_index(drop=True, inplace=True) all_entries_pd.loc['starting'] = top_line all_entries_pd.sort_index(by='date', axis=0, inplace=True) all_entries_pd['balance'] = all_entries_pd['amount'].cumsum() return all_entries_pd[cols + ['balance']]
def set_company(self): self.company_name = api_func('gl', 'company', self.company_id)['name']
def __init__(self, company_id=None): self.company_id = company_id self.conn = connection self.accts = {} self.company_list = api_func('gl', 'company_list', company_id)
def accounts_list(request): "Show list of each account" accounts = api_func('gl', 'account') return render_to_response('gl/accounts_list.html', RequestContext(request, dict(accounts=accounts)))