def accounting_import_step2(request, key): from accounting_main.models import AccountingLine, AccountingLineLogging from accounting_core.models import AccountingYear, CostCenter, Account (session_key, session_data) = _get_import_session_data(request, key) if not session_key: return session_data # Not very clean ^^' if not session_data['has_data']: return redirect('accounting_main-views-accounting_import_step1', key) year = get_object_or_404(AccountingYear, pk=session_data['year']) # Map line id to have lines (efficiently) line_cache = {} for line in AccountingLine.objects.filter(accounting_year=year, deleted=False): line_cache[line.pk] = line diff = session_data['data'] diff['nop'] = [line_cache[line_pk] for line_pk in diff['nop']] diff['to_delete'] = [line_cache[line_pk] for line_pk in diff['to_delete']] diff['to_update'] = [(line_cache[line_pk], arg1, arg2) for line_pk, arg1, arg2 in diff['to_update']] if request.method == 'POST': for wanted_line in diff['to_add']: # NB: Si quelqu'un modifie les trucs pendant l'import, ça pétera. # C'est ultra peu probable, donc ignoré costcenter = CostCenter.objects.get(accounting_year=year, account_number=wanted_line['costcenter']) account = Account.objects.get(accounting_year=year, account_number=wanted_line['account']) line = AccountingLine(account=account, costcenter=costcenter, date=wanted_line['date'], tva=wanted_line['tva'], text=wanted_line['text'], output=wanted_line['output'], input=wanted_line['input'], document_id=wanted_line['document_id'], deleted=False, accounting_year=year, current_sum=wanted_line['current_sum'], order=wanted_line['order']) line.save() AccountingLineLogging(object=line, who=request.user, what='created').save() for line, wanted_line, diffs in diff['to_update']: for field, (old, new) in diffs.items(): setattr(line, field, new) line.save() AccountingLineLogging(object=line, who=request.user, what='edited', extra_data=json.dumps({'added': None, 'edited': diffs, 'deleted': None})).save() for line in diff['to_delete']: for error in line.accountingerror_set.all(): error.linked_line = None error.save() line.delete() # harddelete. year.last_accounting_import = now() year.save() request.session[session_key] = {} messages.success(request, _(u"Compta importée ! Si tout est ok, n'oublie pas de notifier les gens.")) return redirect('accounting_main-views-accounting_import_step0') return render(request, "accounting_main/import/step2.html", {'key': key, 'diff': diff})
def accounting_import_step2(request, key): from accounting_main.models import AccountingLine, AccountingLineLogging from accounting_core.models import AccountingYear, CostCenter, Account (session_key, session_data) = _get_import_session_data(request, key) if not session_key: return session_data # Not very clean ^^' if not session_data['has_data']: return redirect('accounting_main.views.accounting_import_step1', key) year = get_object_or_404(AccountingYear, pk=session_data['year']) # Map line id to have lines (efficiently) line_cache = {} for line in AccountingLine.objects.filter(accounting_year=year, deleted=False): line_cache[line.pk] = line diff = session_data['data'] diff['nop'] = map(lambda line_pk: line_cache[line_pk], diff['nop']) diff['to_delete'] = map(lambda line_pk: line_cache[line_pk], diff['to_delete']) diff['to_update'] = map(lambda (line_pk, __, ___): (line_cache[line_pk], __, ___), diff['to_update']) if request.method == 'POST': for wanted_line in diff['to_add']: # NB: Si quelqu'un modifie les trucs pendant l'import, ça pétera. # C'est ultra peu probable, donc ignoré costcenter = CostCenter.objects.get(accounting_year=year, account_number=wanted_line['costcenter']) account = Account.objects.get(accounting_year=year, account_number=wanted_line['account']) line = AccountingLine(account=account, costcenter=costcenter, date=wanted_line['date'], tva=wanted_line['tva'], text=wanted_line['text'], output=wanted_line['output'], input=wanted_line['input'], document_id=wanted_line['document_id'], deleted=False, accounting_year=year, current_sum=wanted_line['current_sum'], order=wanted_line['order']) line.save() AccountingLineLogging(object=line, who=request.user, what='created').save() for line, wanted_line, diffs in diff['to_update']: for field, (old, new) in diffs.iteritems(): setattr(line, field, new) line.save() AccountingLineLogging(object=line, who=request.user, what='edited', extra_data=json.dumps({'added': None, 'edited': diffs, 'deleted': None})).save() for line in diff['to_delete']: for error in line.accountingerror_set.all(): error.linked_line = None error.save() line.delete() # harddelete. year.last_accounting_import = now() year.save() request.session[session_key] = {} messages.success(request, _(u"Compta importée ! Si tout est ok, n'oublie pas de notifier les gens.")) return redirect('accounting_main.views.accounting_import_step0') return render(request, "accounting_main/import/step2.html", {'key': key, 'diff': diff})
def accounting_import_step0(request): """Phase 0 de l'import: Crée une nouvelle session d'import""" from accounting_main.models import AccountingLine if not AccountingLine.static_rights_can('IMPORT', request.user): raise Http404 key = str(uuid.uuid4()) session_key = 'T2_ACCOUNTING_IMPORT_{}'.format(key) request.session[session_key] = {'is_valid': True, 'has_data': False} return redirect('accounting_main-views-accounting_import_step1', key)
def accounting_import_step0(request): """Phase 0 de l'import: Crée une nouvelle session d'import""" from accounting_main.models import AccountingLine if not AccountingLine.static_rights_can('IMPORT', request.user): raise Http404 key = str(uuid.uuid4()) session_key = 'T2_ACCOUNTING_IMPORT_{}'.format(key) request.session[session_key] = {'is_valid': True, 'has_data': False} return redirect('accounting_main.views.accounting_import_step1', key)
def _get_import_session_data(request, key): from accounting_main.models import AccountingLine if not AccountingLine.static_rights_can('IMPORT', request.user): raise Http404 session_key = 'T2_ACCOUNTING_IMPORT_{}'.format(key) session_data = request.session.get(session_key) if not session_data or not session_data['is_valid']: messages.warning(request, _(u'Session d\'importation invalide.')) return (None, redirect('accounting_main-views-accounting_import_step0')) return (session_key, session_data)
def _get_import_session_data(request, key): from accounting_main.models import AccountingLine if not AccountingLine.static_rights_can('IMPORT', request.user): raise Http404 session_key = 'T2_ACCOUNTING_IMPORT_{}'.format(key) session_data = request.session.get(session_key) if not session_data or not session_data['is_valid']: messages.warning(request, _(u'Session d\'importation invalide.')) return (None, redirect('accounting_main.views.accounting_import_step0')) return (session_key, session_data)
def accounting_graph(request): from accounting_core.models import CostCenter from accounting_main.models import AccountingLine costcenter = get_object_or_404(CostCenter, pk=request.GET.get('costcenter')) if not AccountingLine.static_rights_can('LIST', request.user, costcenter.unit, costcenter.accounting_year): raise Http404 data = collections.OrderedDict() for line in AccountingLine.objects.filter(costcenter=costcenter).order_by('date'): timestamp = int((time.mktime(line.date.timetuple()) + 3600) * 1000) data[timestamp] = -line.current_sum return render(request, 'accounting_main/accountingline/graph.html', {'costcenter': costcenter, 'random': str(uuid.uuid4()), 'data': data})
def accounting_budget_view(request): from accounting_core.models import CostCenter, AccountCategory from accounting_main.models import AccountingLine costcenter = get_object_or_404(CostCenter, pk=request.GET.get('costcenter')) if not AccountingLine.static_rights_can('LIST', request.user, costcenter.unit, costcenter.accounting_year): raise Http404 root_acs = AccountCategory.objects.filter(deleted=False, accounting_year=costcenter.accounting_year, parent_hierarchique=None).order_by('order') def _build_recu_list(base_list): retour = [] for elem in base_list: if elem.get_children_categories(): retour.append((elem, _build_recu_list(elem.get_children_categories()), None)) else: accouts_with_total = [] for account in elem.get_accounts(): data = costcenter.accountingline_set.filter(deleted=False, account=account).aggregate(pos=Sum('input'), neg=Sum('output')) if not data['pos']: data['pos'] = 0 if not data['neg']: data['neg'] = 0 data['total'] = data['pos'] - data['neg'] accouts_with_total.append((account, data)) retour.append((elem, None, accouts_with_total)) return retour data = _build_recu_list(root_acs) return render(request, 'accounting_main/accountingline/budget_view.html', {'costcenter': costcenter, 'random': str(uuid.uuid4()), 'data': data})
def accounting_budget_view(request): from accounting_core.models import CostCenter, AccountCategory from accounting_main.models import AccountingLine from .forms2 import BudgetFilterForm costcenter = get_object_or_404(CostCenter, pk=request.GET.get('costcenter')) start_date, end_date = None, None if request.method == 'POST': form = BudgetFilterForm(request.POST) if form.is_valid(): start_date, end_date = form.cleaned_data[ 'start'], form.cleaned_data['end'] else: form = BudgetFilterForm() form.fields[ 'start'].initial = costcenter.accounting_year.start_date.date() form.fields['end'].initial = costcenter.accounting_year.end_date.date() if not AccountingLine.static_rights_can( 'LIST', request.user, costcenter.unit, costcenter.accounting_year): raise Http404 root_acs = AccountCategory.objects.filter( deleted=False, accounting_year=costcenter.accounting_year, parent_hierarchique=None).order_by('order') def _build_recu_list(base_list): retour = [] for elem in base_list: if elem.get_children_categories(): retour.append( (elem, _build_recu_list(elem.get_children_categories()), None)) else: accouts_with_total = [] elem.show_total = False elem.total = 0 for account in elem.get_accounts(): data = costcenter.accountingline_set.filter( deleted=False, account=account) if start_date or end_date: data = data.filter(date__gte=start_date, date__lte=end_date) data = data.aggregate(pos=Sum('input'), neg=Sum('output')) if not data['pos']: data['pos'] = 0 if not data['neg']: data['neg'] = 0 data['total'] = data['pos'] - data['neg'] elem.total += data['total'] if data['pos'] or data['neg']: elem.show_total = True accouts_with_total.append((account, data)) retour.append((elem, None, accouts_with_total)) return retour data = _build_recu_list(root_acs) return render( request, 'accounting_main/accountingline/budget_view.html', { 'costcenter': costcenter, 'random': str(uuid.uuid4()), 'data': data, 'form': form, 'start': start_date, 'end': end_date })
def test_accountingline_deleted(self): from accounting_main.models import AccountingLine now = timezone.now() AccountingLine(id=20, account_id=1, date=now, tva=0.0, text='line bad', output=11.11, input=0.0, current_sum=0.0, order=1, accounting_year_id=1, costcenter_id=1, deleted=True).save() self.call_check_html('/accounting/main/accountingline/deleted', data={'upk':1}) self.call_check_redirect('/accounting/main/accountingline/deleted', method='post', data={'upk':1, 'pk':20}, redirect_url='/accounting/main/accountingline/')
def setup_testing_accounting_main(): from accounting_main.models import Budget, BudgetLine, AccountingError, AccountingLine now = timezone.now() Budget(id=1, name='my budget', unit_id=settings.ROOT_UNIT_PK, accounting_year_id=1, costcenter_id=1).save() BudgetLine(budget_id=1, account_id=1, amount=11.11, description="budget #1").save() BudgetLine(budget_id=1, account_id=2, amount=-22.22, description="budget #2").save() BudgetLine(budget_id=1, account_id=3, amount=33.33, description="budget #3").save() BudgetLine(budget_id=1, account_id=4, amount=-44.44, description="budget #4").save() BudgetLine(budget_id=1, account_id=5, amount=55.55, description="budget #5").save() BudgetLine(budget_id=1, account_id=6, amount=-66.66, description="budget #6").save() BudgetLine(budget_id=1, account_id=7, amount=77.77, description="budget #7").save() BudgetLine(budget_id=1, account_id=8, amount=-88.88, description="budget #8").save() BudgetLine(budget_id=1, account_id=9, amount=99.99, description="budget #9").save() AccountingError(id=1, accounting_year_id=1, costcenter_id=1).save() AccountingLine(account_id=1, date=now, tva=0.0, text='line #1', output=11.11, input=0.0, current_sum=0.0, order=1, accounting_year_id=1, costcenter_id=1).save() AccountingLine(account_id=2, date=now, tva=0.0, text='line #2', output=0.0, input=22.22, current_sum=0.0, order=1, accounting_year_id=1, costcenter_id=1).save() AccountingLine(account_id=3, date=now, tva=0.0, text='line #3', output=33.33, input=0.0, current_sum=0.0, order=1, accounting_year_id=1, costcenter_id=1).save() AccountingLine(account_id=4, date=now, tva=0.0, text='line #4', output=0.0, input=44.44, current_sum=0.0, order=1, accounting_year_id=1, costcenter_id=1).save() AccountingLine(account_id=5, date=now, tva=0.0, text='line #5', output=55.55, input=0.0, current_sum=0.0, order=1, accounting_year_id=1, costcenter_id=1).save() AccountingLine(account_id=6, date=now, tva=0.0, text='line #6', output=0.0, input=66.66, current_sum=0.0, order=1, accounting_year_id=1, costcenter_id=1).save() AccountingLine(account_id=7, date=now, tva=0.0, text='line #7', output=77.77, input=0.0, current_sum=0.0, order=1, accounting_year_id=1, costcenter_id=1).save() AccountingLine(account_id=8, date=now, tva=0.0, text='line #8', output=0.0, input=88.88, current_sum=0.0, order=1, accounting_year_id=1, costcenter_id=1).save() AccountingLine(account_id=9, date=now, tva=0.0, text='line #9', output=99.99, input=0.0, current_sum=0.0, order=1, accounting_year_id=1, costcenter_id=1).save()
def accounting_budget_view(request): from accounting_core.models import CostCenter, AccountCategory from accounting_main.models import AccountingLine from .forms2 import BudgetFilterForm costcenter = get_object_or_404(CostCenter, pk=request.GET.get('costcenter')) start_date, end_date = None, None if request.method == 'POST': form = BudgetFilterForm(request.POST) if form.is_valid(): start_date, end_date = form.cleaned_data['start'], form.cleaned_data['end'] else: form = BudgetFilterForm() form.fields['start'].initial = costcenter.accounting_year.start_date.date() form.fields['end'].initial = costcenter.accounting_year.end_date.date() if not AccountingLine.static_rights_can('LIST', request.user, costcenter.unit, costcenter.accounting_year): raise Http404 root_acs = AccountCategory.objects.filter(deleted=False, accounting_year=costcenter.accounting_year, parent_hierarchique=None).order_by('order') def _build_recu_list(base_list): retour = [] for elem in base_list: if elem.get_children_categories(): retour.append((elem, _build_recu_list(elem.get_children_categories()), None)) else: accouts_with_total = [] elem.show_total = False elem.total = 0 for account in elem.get_accounts(): data = costcenter.accountingline_set.filter(deleted=False, account=account) if start_date or end_date: data = data.filter(date__gte=start_date, date__lte=end_date) data = data.aggregate(pos=Sum('input'), neg=Sum('output')) if not data['pos']: data['pos'] = 0 if not data['neg']: data['neg'] = 0 data['total'] = data['pos'] - data['neg'] elem.total += data['total'] if data['pos'] or data['neg']: elem.show_total = True accouts_with_total.append((account, data)) retour.append((elem, None, accouts_with_total)) return retour data = _build_recu_list(root_acs) return render(request, 'accounting_main/accountingline/budget_view.html', {'costcenter': costcenter, 'random': str(uuid.uuid4()), 'data': data, 'form': form, 'start': start_date, 'end': end_date})