def bank_accounts_import_manual(): form = BankAccountActivitiesImportManualForm() form.account.query = BankAccount.q.all() if form.validate_on_submit(): bank_account = form.account.data if form.file.data: mt940 = form.file.data.read().decode() mt940_entry = MT940Error(mt940=mt940, exception="manual import", author=current_user, bank_account=bank_account) session.add(mt940_entry) session.commit() flash( u'Datensatz wurde importiert. Buchungen können jetzt importiert werden.' ) return redirect( url_for(".fix_import_error", error_id=mt940_entry.id)) else: flash(u"Kein MT940 hochgeladen.", 'error') return render_template('finance/bank_accounts_import_manual.html', form=form)
def bank_account_activities_edit(activity_id): activity = BankAccountActivity.q.get(activity_id) if activity is None: flash(u"Bankbewegung mit ID {} existiert nicht!".format(activity_id), 'error') abort(404) form = BankAccountActivityEditForm( obj=activity, bank_account_name=activity.bank_account.name) if form.validate(): debit_account = Account.q.filter( Account.id == form.account_id.data ).one() credit_account = activity.bank_account.account transaction = finance.simple_transaction( description=form.description.data, debit_account=debit_account, credit_account=credit_account, amount=activity.amount, author=current_user, valid_on=activity.valid_on) activity.split = next(split for split in transaction.splits if split.account_id == credit_account.id) session.add(activity) session.commit() end_payment_in_default_memberships() return redirect(url_for('.bank_accounts_list')) return render_template('finance/bank_account_activities_edit.html', form=form)
def test_mail_deletion(self): users_with_mail = [ u for u in self.users_to_sync if u.User.email is not None ] if not users_with_mail: raise RuntimeError( "Fixtures do not provide a syncable user with a mail address") modified_user = users_with_mail[0].User mod_dn = Record.from_db_user(modified_user, self.base_dn).dn modified_user.email = '*****@*****.**' session.add(modified_user) session.commit() self.users_to_sync = fetch_users_to_sync(session, self.config.required_property) self.sync_all() newest_users = fetch_current_ldap_users(self.conn, base_dn=self.base_dn) newest_users_correct_dn = [ u for u in newest_users if u['dn'] == mod_dn ] self.assertEqual(len(newest_users_correct_dn), 1) modified_record = newest_users_correct_dn[0] self.assertNotIn('mail', modified_record)
def test_mail_creation(self): users_without_mail = [ u for u in self.users_to_sync if u.User.email is None ] if not users_without_mail: raise RuntimeError( "Fixtures do not provide a syncable user without a mail address" ) mod_user = users_without_mail[0].User mod_dn = UserRecord.from_db_user(mod_user, self.user_base_dn).dn mod_user.email = '*****@*****.**' session.add(mod_user) session.commit() users_to_sync = fetch_users_to_sync(session, self.config.required_property) exporter = self.build_user_exporter(current_users=self.new_ldap_users, desired_users=users_to_sync) exporter.compile_actions() relevant_actions = [ a for a in exporter.actions if not isinstance(a, IdleAction) ] print(relevant_actions) self.assertEqual(len(relevant_actions), 1) self.assertEqual(type(relevant_actions[0]), ModifyAction) exporter.execute_all(self.conn) newest_users = fetch_current_ldap_users(self.conn, base_dn=self.user_base_dn) modified_ldap_record = self.get_by_dn(newest_users, mod_dn) self.assertIn('mail', modified_ldap_record['attributes']) self.assertEqual(modified_ldap_record['attributes']['mail'], [mod_user.email])
def newDorm(): """Make a new dormitory""" street = u_input("street: ") number = u_input("number: ") short_name = u_input("short_name: ") try: new_dormitory = Dormitory(number=number, short_name=short_name, street=street) except: print("could not create dormitory") print new_dormitory confirm = raw_input("do you want to save? (y/n): ") if confirm == "y": try: session.add(new_dormitory) session.commit() except: session.rollback() raise
def interface_create(host, name, mac, ips, processor): interface = Interface(host=host, mac=mac, name=name) session.add(interface) subnets = get_subnets_for_room(interface.host.room) if ips is None: ip, _ = get_free_ip(subnets) ips = {ip} # IP added for ip in ips: subnet = next( iter([subnet for subnet in subnets if (ip in subnet.address)]), None) if subnet is not None: session.add(IP(interface=interface, address=ip, subnet=subnet)) message = deferred_gettext( u"Created interface ({}, {}) with name '{}' for host '{}'.".format( interface.mac, ', '.join(str(ip.address) for ip in interface.ips), interface.name, interface.host.name)) log_user_event(author=processor, user=host.owner, message=message.to_json()) return interface
def bank_account_activities_edit(activity_id): activity = BankAccountActivity.q.get(activity_id) if activity is None: flash(u"Bankbewegung mit ID {} existiert nicht!".format(activity_id), 'error') abort(404) form = BankAccountActivityEditForm( obj=activity, bank_account_name=activity.bank_account.name) if form.validate(): debit_account = Account.q.filter( Account.id == form.account_id.data).one() credit_account = activity.bank_account.account transaction = finance.simple_transaction( description=form.description.data, debit_account=debit_account, credit_account=credit_account, amount=activity.amount, author=current_user, valid_on=activity.valid_on) activity.split = next(split for split in transaction.splits if split.account_id == credit_account.id) session.add(activity) session.commit() end_payment_in_default_memberships() return redirect(url_for('.bank_accounts_list')) return render_template('finance/bank_account_activities_edit.html', form=form)
def create_switch(name, management_ip, room, processor): switch = Switch(management_ip=management_ip, host=Host(room=room, owner=User.q.get(0), name=name)) session.add(switch) log_room_event("Created switch '{}' with management IP {}.".format(switch.host.name, switch.management_ip), processor, switch.host.room) return switch
def create_switch_port(switch, name, default_vlans, processor): switch_port = SwitchPort(name=name, switch=switch, default_vlans=default_vlans) session.add(switch_port) default_vlans_str = ', '.join(str(vlan.vid) for vlan in switch_port.default_vlans) message = deferred_gettext("Created switch-port {} on {} with default VLANs {}.")\ .format(switch_port.name, switch_port.switch.host.name, default_vlans_str) log_room_event(message.to_json(), processor, switch_port.switch.host.room) return switch_port
def create_switch_port(switch, name, default_vlans, processor): switch_port = SwitchPort(name=name, switch=switch, default_vlans=default_vlans) session.add(switch_port) log_room_event("Created switch-port {} on {} with default VLANs {}." .format(switch_port.name, switch_port.switch.host.name, ', '.join(str(vlan.vid) for vlan in switch_port.default_vlans)), processor, switch_port.switch.host.room) return switch_port
def accounts_create(): form = FinanceAccountCreateForm() if form.validate_on_submit(): new_account = FinanceAccount(name=form.name.data, type=form.type.data) session.add(new_account) session.commit() return redirect(url_for('.accounts')) return render_template('finance/accounts_create.html', form=form, page_title=u"Konto erstellen")
def create_switch(name, management_ip, room, processor): switch = Switch(management_ip=management_ip, host=Host(room=room, owner=User.get(0), name=name)) session.add(switch) message = deferred_gettext("Created switch '{}' with management IP {}.")\ .format(switch.host.name, switch.management_ip) log_room_event(message.to_json(), processor, switch.host.room) return switch
def create_patch_port(name, room, switch_room, processor): # This check can be removed as soon as the unique constraint exists if PatchPort.q.filter_by(name=name, switch_room=switch_room).first(): raise PatchPortAlreadyExistsException() patch_port = PatchPort(name=name, room=room, switch_room=switch_room) session.add(patch_port) log_room_event("Created patch-port {} to {}.".format(patch_port.name, room.short_name), processor, switch_room) return patch_port
def accounts_create(): form = AccountCreateForm() if form.validate_on_submit(): new_account = Account(name=form.name.data, type=form.type.data) session.add(new_account) session.commit() return redirect(url_for('.accounts_list')) return render_template('finance/accounts_create.html', form=form, page_title=u"Konto erstellen")
def create_task_and_execute(task_type: TaskType, user: User, params) -> Task: task = UserTaskFactory( type=task_type, user=user, parameters_json=params, due_yesterday=True, ) with session.begin_nested(): session.add(task) assert Task.q.all() execute_scheduled_tasks() return task
def bank_account_activities_do_match(): # Generate form again matching = match_activities() matched = [] FieldList = [] for activity, user in matching.items(): FieldList.append((str(activity.id), BooleanField('{} ({}€) -> {} ({}, {})'.format( activity.reference, activity.amount, user.name, user.id, user.login)))) class F(forms.ActivityMatchForm): pass for (name, field) in FieldList: setattr(F, name, field) form = F() # parse data if form.validate_on_submit(): # look for all matches which were checked for activity, user in matching.items(): if form._fields[str( activity.id )].data is True and activity.transaction_id is None: debit_account = user.account credit_account = activity.bank_account.account transaction = finance.simple_transaction( description=activity.reference, debit_account=debit_account, credit_account=credit_account, amount=activity.amount, author=current_user, valid_on=activity.valid_on) activity.split = next(split for split in transaction.splits if split.account_id == credit_account.id) session.add(activity) matched.append((activity, user)) end_payment_in_default_memberships() session.flush() session.commit() return render_template('finance/bank_accounts_matched.html', matched=matched)
def interface_edit(interface, name, mac, ips, processor): message = u"Edited interface ({}, {}) of host '{}'." \ .format(interface.mac, ', '.join(str(ip.address) for ip in interface.ips), interface.host.name) if interface.name != name: interface.name = name message += " New name: '{}'.".format(interface.name) if interface.mac != mac: interface.mac = mac message += " New MAC: {}.".format(interface.mac) ips_changed = False current_ips = list(ip.address for ip in interface.ips) subnets = get_subnets_for_room(interface.host.room) new_ips = set(current_ips) # IP removed for ip in current_ips: if ip not in ips: session.delete(IP.q.filter_by(address=ip).first()) ips_changed = True new_ips.remove(ip) # IP added for ip in ips: if ip not in current_ips: subnet = next( iter([subnet for subnet in subnets if (ip in subnet.address)]), None) if subnet is not None: session.add(IP(interface=interface, address=ip, subnet=subnet)) ips_changed = True new_ips.add(str(ip)) if ips_changed: message += " New IPs: {}.".format(', '.join(str(ip) for ip in new_ips)) log_user_event(author=processor, user=interface.host.owner, message=deferred_gettext(message).to_json())
def host_create(owner, room, name, processor): host = Host(name=name, owner_id=owner.id, room=room) session.add(host) message = deferred_gettext( u"Created host '{name}' in {dorm} {level}-{room}.".format( name=host.name, dorm=room.building.short_name, level=room.level, room=room.number)) log_user_event(author=processor, user=owner, message=message.to_json())\ return host
def journals_create(): form = JournalCreateForm() if form.validate_on_submit(): new_journal = Journal( name=form.name.data, bank=form.bank.data, account_number=form.account_number.data, routing_number=form.routing_number.data, iban=form.iban.data, bic=form.bic.data, hbci_url=form.hbci_url.data) session.add(new_journal) session.commit() return redirect(url_for('.journals')) return render_template('finance/journals_create.html', form=form, page_title=u"Journal erstellen")
def journals_create(): form = JournalCreateForm() if form.validate_on_submit(): new_journal = Journal(name=form.name.data, bank=form.bank.data, account_number=form.account_number.data, routing_number=form.routing_number.data, iban=form.iban.data, bic=form.bic.data, hbci_url=form.hbci_url.data) session.add(new_journal) session.commit() return redirect(url_for('.journals')) return render_template('finance/journals_create.html', form=form, page_title=u"Journal erstellen")
def test_mail_deletion(self): users_with_mail = [u for u in self.users_to_sync if u.User.email is not None] if not users_with_mail: raise RuntimeError("Fixtures do not provide a syncable user with a mail address") modified_user = users_with_mail[0].User mod_dn = Record.from_db_user(modified_user, self.base_dn).dn modified_user.email = '*****@*****.**' session.add(modified_user) session.commit() self.users_to_sync = fetch_users_to_sync(session, self.config.required_property) self.sync_all() newest_users = fetch_current_ldap_users(self.conn, base_dn=self.base_dn) newest_users_correct_dn = [u for u in newest_users if u['dn'] == mod_dn] self.assertEqual(len(newest_users_correct_dn), 1) modified_record = newest_users_correct_dn[0] self.assertNotIn('mail', modified_record)
def get_or_create_address( street: str, number: str, addition: str | None, zip_code: str, city: str | None = None, state: str | None = None, country: str | None = None, ) -> Address: """Returns an existing address or creates a new one. If the address is to be used for some other update operation, make sure to wrap this call and the next one in a `Session.no_autoflush` block, because else the address cleanup trigger may fire. """ query = session.query(Address).filter_by( street=street, number=number, addition=addition, zip_code=zip_code, city=city, state=state, country=country, ) num_matching = query.count() if num_matching == 1: return query.one() if num_matching > 1: raise RuntimeError("Found more than one address") # create new_address = Address( street=street, number=number, addition=addition, zip_code=zip_code, city=city, state=state, country=country, ) session.add(new_address) return new_address
def bank_accounts_create(): form = BankAccountCreateForm() if form.validate_on_submit(): new_bank_account = BankAccount( name=form.name.data, bank=form.bank.data, account_number=form.account_number.data, routing_number=form.routing_number.data, iban=form.iban.data, bic=form.bic.data, fints_endpoint=form.fints.data, account=Account(name=form.name.data, type='BANK_ASSET'), ) session.add(new_bank_account) session.commit() return redirect(url_for('.bank_accounts_list')) return render_template('finance/bank_accounts_create.html', form=form, page_title=u"Bankkonto erstellen")
def membership_fee_create(): previous_fee = MembershipFee.q.order_by(MembershipFee.id.desc()).first() if previous_fee: begins_on_default = previous_fee.ends_on + timedelta(1) next_month = begins_on_default.replace(day=28) + timedelta(4) ends_on_default = begins_on_default.replace( day=(next_month - timedelta(days=next_month.day)).day) name_default = str(begins_on_default.year) \ + "-" + "%02d" % begins_on_default.month form = MembershipFeeCreateForm( name=name_default, regular_fee=previous_fee.regular_fee, booking_begin=previous_fee.booking_begin.days, booking_end=previous_fee.booking_end.days, payment_deadline=previous_fee.payment_deadline.days, payment_deadline_final=previous_fee.payment_deadline_final.days, begins_on=begins_on_default, ends_on=ends_on_default, ) else: form = MembershipFeeCreateForm() if form.validate_on_submit(): mfee = MembershipFee( name=form.name.data, regular_fee=form.regular_fee.data, booking_begin=timedelta(days=form.booking_begin.data), booking_end=timedelta(days=form.booking_end.data), payment_deadline=timedelta(days=form.payment_deadline.data), payment_deadline_final=timedelta( days=form.payment_deadline_final.data), begins_on=form.begins_on.data, ends_on=form.ends_on.data, ) session.add(mfee) session.commit() flash("Beitrag erfolgreich erstellt.", "success") return redirect(url_for(".membership_fees")) return render_template('finance/membership_fee_create.html', form=form)
def test_mail_deletion(self): users_with_mail = [ u for u in self.users_to_sync if u.User.email is not None ] if not users_with_mail: raise RuntimeError( "Fixtures do not provide a syncable user with a mail address") modified_user = users_with_mail[0].User mod_dn = UserRecord.from_db_user(modified_user, self.user_base_dn).dn modified_user.email = '*****@*****.**' session.add(modified_user) session.commit() self.users_to_sync = fetch_users_to_sync(session, self.config.required_property) self.sync_all() newest_users = fetch_current_ldap_users(self.conn, base_dn=self.user_base_dn) modified_record = self.get_by_dn(newest_users, mod_dn) assert 'mail' not in modified_record
def _apply_checked_matches(matching, subform): # look for all matches which were checked matched = [] for activity, entity in matching.items(): if subform[str(activity.id)].data and activity.transaction_id is None: debit_account = entity if type( entity) is Account else entity.account credit_account = activity.bank_account.account transaction = finance.simple_transaction( description=activity.reference, debit_account=debit_account, credit_account=credit_account, amount=activity.amount, author=current_user, valid_on=activity.valid_on) activity.split = next(split for split in transaction.splits if split.account_id == credit_account.id) session.add(activity) matched.append((activity, entity)) return matched
def membership_fee_create(): previous_fee = MembershipFee.q.order_by(MembershipFee.id.desc()).first() if previous_fee: begins_on_default = previous_fee.ends_on + timedelta(1) next_month = begins_on_default.replace(day=28) + timedelta(4) ends_on_default = begins_on_default.replace( day=(next_month - timedelta(days=next_month.day)).day ) name_default = str(begins_on_default.year) \ + "-" + "%02d" % begins_on_default.month form = MembershipFeeCreateForm( name=name_default, regular_fee=previous_fee.regular_fee, grace_period=previous_fee.grace_period.days, payment_deadline=previous_fee.payment_deadline.days, payment_deadline_final=previous_fee.payment_deadline_final.days, begins_on=begins_on_default, ends_on=ends_on_default, ) else: form = MembershipFeeCreateForm() if form.validate_on_submit(): mfee = MembershipFee( name=form.name.data, regular_fee=form.regular_fee.data, grace_period=timedelta(days=form.grace_period.data), payment_deadline=timedelta(days=form.payment_deadline.data), payment_deadline_final=timedelta(days=form.payment_deadline_final.data), begins_on=form.begins_on.data, ends_on=form.ends_on.data, ) session.add(mfee) session.commit() flash("Beitrag erfolgreich erstellt.", "success") return redirect(url_for(".membership_fees")) return render_template('finance/membership_fee_create.html', form=form)
def journals_entries_edit(journal_id, entry_id): entry = JournalEntry.q.get(entry_id) form = JournalEntryEditForm(obj=entry, journal_name=entry.journal.name) if form.validate(): debit_account = entry.journal.finance_account credit_account = FinanceAccount.q.filter( FinanceAccount.id == form.finance_account_id.data ).one() entry.transaction = finance.simple_transaction( description=entry.description, debit_account=debit_account, credit_account=credit_account, amount=entry.amount, author=current_user, valid_date=entry.valid_date) entry.description = form.description.data session.add(entry) session.commit() return redirect(url_for('.journals')) return render_template( 'finance/journals_entries_edit.html', entry=entry, form=form )
def journals_entries_edit(journal_id, entry_id): entry = JournalEntry.q.get(entry_id) form = JournalEntryEditForm(obj=entry, journal_name=entry.journal.name) if form.validate(): debit_account = entry.journal.finance_account credit_account = FinanceAccount.q.filter( FinanceAccount.id == form.finance_account_id.data).one() entry.transaction = finance.simple_transaction( description=entry.description, debit_account=debit_account, credit_account=credit_account, amount=entry.amount, author=current_user, valid_date=entry.valid_date) entry.description = form.description.data session.add(entry) session.commit() return redirect(url_for('.journals')) return render_template('finance/journals_entries_edit.html', entry=entry, form=form)
def test_mail_creation(self): users_without_mail = [u for u in self.users_to_sync if u.User.email is None] if not users_without_mail: raise RuntimeError("Fixtures do not provide a syncable user without a mail address") mod_user = users_without_mail[0].User mod_dn = Record.from_db_user(mod_user, self.base_dn).dn mod_user.email = '*****@*****.**' session.add(mod_user) session.commit() users_to_sync = fetch_users_to_sync(session, self.config.required_property) exporter = self.build_exporter(current=self.new_ldap_users, desired=users_to_sync) exporter.compile_actions() relevant_actions = [a for a in exporter.actions if not isinstance(a, IdleAction)] print(relevant_actions) self.assertEqual(len(relevant_actions), 1) self.assertEqual(type(relevant_actions[0]), ModifyAction) exporter.execute_all(self.conn) newest_users = fetch_current_ldap_users(self.conn, base_dn=self.base_dn) modified_ldap_record = [u for u in newest_users if u['dn'] == mod_dn][0] self.assertIn('mail', modified_ldap_record['attributes']) self.assertEqual(modified_ldap_record['attributes']['mail'], [mod_user.email])
def bank_account_activities_edit(activity_id): activity = BankAccountActivity.q.get(activity_id) if activity is None: flash(u"Bankbewegung mit ID {} existiert nicht!".format(activity_id), 'error') abort(404) if activity.transaction_id is not None: form = BankAccountActivityReadForm( obj=activity, bank_account_name=activity.bank_account.name) if activity.transaction_id: flash(u"Bankbewegung ist bereits zugewiesen!".format(activity_id), 'warning') form_args = { 'form': form, 'show_submit': False, 'show_cancel': False, } return render_template('generic_form.html', page_title="Bankbewegung", form_args=form_args, form=form) else: form = BankAccountActivityEditForm( obj=activity, bank_account_name=activity.bank_account.name, description=activity.reference) if form.validate_on_submit(): debit_account = Account.q.filter( Account.id == form.account_id.data).one() credit_account = activity.bank_account.account transaction = finance.simple_transaction( description=form.description.data, debit_account=debit_account, credit_account=credit_account, amount=activity.amount, author=current_user, valid_on=activity.valid_on, confirmed=current_user.member_of(config.treasurer_group)) activity.split = next(split for split in transaction.splits if split.account_id == credit_account.id) session.add(activity) end_payment_in_default_memberships() session.commit() flash(u"Transaktion erfolgreich erstellt.", 'success') return redirect(url_for('.bank_accounts_list')) form_args = { 'form': form, 'cancel_to': url_for('.bank_accounts_list'), 'submit_text': 'Zuweisen', } return render_template('generic_form.html', page_title="Bankbewegung zuweisen", form_args=form_args, form=form)
def bank_accounts_import(): form = BankAccountActivitiesImportForm() form.account.choices = [(acc.id, acc.name) for acc in BankAccount.q.all()] (transactions, old_transactions) = ([], []) if request.method != 'POST': del (form.start_date) form.end_date.data = date.today() - timedelta(days=1) if form.validate_on_submit(): bank_account = BankAccount.q.get(form.account.data) # set start_date, end_date if form.start_date.data is None: form.start_date.data = map_or_default( bank_account.last_imported_at, datetime.date, date(2018, 1, 1)) if form.end_date.data is None: form.end_date.data = date.today() # login with fints process = True try: fints = FinTS3Client(bank_account.routing_number, form.user.data, form.pin.data, bank_account.fints_endpoint) acc = next((a for a in fints.get_sepa_accounts() if a.iban == bank_account.iban), None) if acc is None: raise KeyError('BankAccount with IBAN {} not found.'.format( bank_account.iban)) start_date = form.start_date.data end_date = form.end_date.data statement, with_error = fints.get_filtered_transactions( acc, start_date, end_date) flash("Transaktionen vom {} bis {}.".format(start_date, end_date)) if len(with_error) > 0: flash( "{} Statements enthielten fehlerhafte Daten und müssen " "vor dem Import manuell korrigiert werden.".format( len(with_error)), 'error') except (FinTSDialogError, FinTSClientPINError): flash(u"Ungültige FinTS-Logindaten.", 'error') process = False except KeyError: flash( u'Das gewünschte Konto kann mit diesem Online-Banking-Zugang\ nicht erreicht werden.', 'error') process = False if process: (transactions, old_transactions) = finance.process_transactions( bank_account, statement) else: (transactions, old_transactions) = ([], []) if process and form.do_import.data is True: # save errors to database for error in with_error: session.add( MT940Error(mt940=error[0], exception=error[1], author=current_user, bank_account=bank_account)) # save transactions to database session.add_all(transactions) session.commit() flash(u'Bankkontobewegungen wurden importiert.') return redirect( url_for(".accounts_show", account_id=bank_account.account_id)) return render_template('finance/bank_accounts_import.html', form=form, transactions=transactions, old_transactions=old_transactions)