def update_flash(self): """ Since so many methods in this class did the exact same thing, a function was created. This updated the session invoice counter, used in many places (eg. sidebar). """ shared_unpaid_invoices = 0 shared_categories = Category.all_active(self.request).all() for c in shared_categories: unpaid_invoices = Invoice.with_category_all_unpaid(c.id) if unpaid_invoices: shared_unpaid_invoices += len(unpaid_invoices) self.request.session.pop_flash('shared_unpaid_invoices') self.request.session.flash(shared_unpaid_invoices, 'shared_unpaid_invoices') private_unpaid_invoices = 0 private_categories = Category.all_private(self.request).all() for c in private_categories: unpaid_invoices = Invoice.with_category_all_unpaid(c.id) if unpaid_invoices: private_unpaid_invoices += len(unpaid_invoices) self.request.session.pop_flash('private_unpaid_invoices') self.request.session.flash(private_unpaid_invoices, 'private_unpaid_invoices')
def login(self): """ Login view, used for both get and post method. This view also checks and authenicated the user by request. """ form = LoginForm(self.request.POST, csrf_context=self.request.session) if self.request.method == 'POST' and form.validate(): user = User.by_email(self.request.POST.get('email')) if (user and user.verify_password(self.request.POST.get('password')) and user.blocked is not True and user.archived is not True): headers = remember(self.request, user.id) shared_unpaid_invoices = 0 shared_categories = Category.all_shared() for c in shared_categories: unpaid_invoices = Invoice.with_category_all_unpaid(c.id) if unpaid_invoices: shared_unpaid_invoices += len(unpaid_invoices) self.request.session.pop_flash('shared_unpaid_invoices') self.request.session.flash(shared_unpaid_invoices, 'shared_unpaid_invoices') private_unpaid_invoices = 0 private_categories = Category.all_private(self.request, id=user.id)\ .all() for c in private_categories: unpaid_invoices = Invoice.with_category_all_unpaid(c.id) if unpaid_invoices: private_unpaid_invoices += len(unpaid_invoices) self.request.session.pop_flash('private_unpaid_invoices') self.request.session.flash(private_unpaid_invoices, 'private_unpaid_invoices') self.request.session.flash('Welcome back %s' % (user.email), 'success') return HTTPFound(location=self.request.route_url('index'), headers=headers) headers = forget(self.request) self.request.session.flash('Login failed', 'error') return {'title': 'Login', 'form': form} if authenticated_userid(self.request): self.request.session.flash('You are already logged in', 'status') return HTTPFound(location=self.request.route_url('index')) return {'title': 'Login', 'form': form}
def expenditure_edit(self): """ Edit expenditure. Method for both post and get request. """ id = int(self.request.matchdict.get('id')) e = Expenditure.by_id(id) if not e: return HTTPNotFound() """ Authorization check. """ if (e.category.private and e.category.user_id is not authenticated_userid(self.request)): return HTTPForbidden() form = ExpenditureEditForm(self.request.POST, e, csrf_context=self.request.session) private = self.request.params.get('private') if private: """ Check if there exists any categories. """ if not Category.first_private(self.request): self.request.session.flash(self.missing_priv_cat, 'error') return HTTPFound(location=self.request .route_url('expenditures')) form.category_id.query = Category.all_private(self.request) else: """ Check if there exists any categories. """ if not Category.first_active(): self.request.session.flash(self.missing_shared_cat, 'error') return HTTPFound(location=self.request .route_url('expenditures')) form.category_id.query = Category.all_active(self.request) if self.request.method == 'POST' and form.validate(): form.populate_obj(e) e.category_id = form.category_id.data.id self.request.session.flash('Expenditure %s updated' % (e.title), 'status') """ A bit ugly, but redirect the user based on private or not. """ if private: return HTTPFound(location= self.request .route_url('expenditures', _query={'private': 1})) return HTTPFound(location=self.request.route_url('expenditures')) form.category_id.data = e.category return {'title': 'Edit private expenditure' if private else 'Edit expenditure', 'form': form, 'id': id, 'action': 'expenditure_edit', 'private': private}
def category_edit(self): """ Edit category view. """ id = int(self.request.matchdict.get('id')) c = Category.by_id(id) if not c: return HTTPNotFound() """ Authorization check. """ if c.private and c.user_id is not authenticated_userid(self.request): return HTTPForbidden() form = CategoryEditForm(self.request.POST, c, csrf_context=self.request.session) if self.request.method == 'POST' and form.validate(): form.populate_obj(c) self.request.session.flash('Category %s updated' % (c.title), 'status') return HTTPFound(location=self.request.route_url('categories')) return {'title': 'Edit category', 'form': form, 'id': id, 'action': 'category_edit'}
def invoices(self): """ Get a paginated list of active invoices for current or given month.""" paid_result = {} unpaid_result = {} year = int(self.request.params.get('year', datetime.now().strftime('%Y'))) month = int(self.request.params.get('month', datetime.now().strftime('%m'))) categories = Category.all_active(self.request).all() for c in categories: paid_invoices = Invoice.with_category_paid(c.id, year, month) if paid_invoices: total = Invoice.with_category_paid(c.id, year, month, total_only=True) paid_result[c.title] = [paid_invoices, total] unpaid_invoices = Invoice.with_category_all_unpaid(c.id) if unpaid_invoices: total = Invoice.with_category_all_unpaid(c.id, total_only=True) unpaid_result[c.title] = [unpaid_invoices, total] return {'paiditems': paid_result, 'unpaiditems': unpaid_result, 'title': 'Invoices', 'month': month, 'year': year, 'nextmonth': self.month_switcher(year, month, next=True), 'prevmonth': self.month_switcher(year, month)}
def category_create(self): """ New category view. """ form = CategoryCreateForm(self.request.POST, csrf_context=self.request.session) if self.request.method == 'POST' and form.validate(): c = Category() form.populate_obj(c) c.user_id = authenticated_userid(self.request) DBSession.add(c) self.request.session.flash('Category %s created' % (c.title), 'success') return HTTPFound(location=self.request.route_url('categories')) return {'title': 'New category', 'form': form, 'action': 'category_new'}
def categories_archived(self): """ Get a paginated list of archived categories. """ page = int(self.request.params.get('page', 1)) categories = Category.page(self.request, page, archived=True) return {'paginator': categories, 'title': 'Archived categories', 'archived': True}
def categories(self): """ Get a paginated list of active categories. """ page = int(self.request.params.get('page', 1)) categories = Category.page(self.request, page) return {'paginator': categories, 'title': 'Categories', 'archived': False}
def expenditure_create(self): """ New expenditure. Method for both post and get request. """ form = ExpenditureCreateForm(self.request.POST, csrf_context=self.request.session) private = self.request.params.get('private') if private: """ Check if there exists any private categories. """ if not Category.first_private(self.request): self.request.session.flash(self.missing_priv_cat, 'error') return HTTPFound(location=self.request .route_url('expenditures')) form.category_id.query = Category.all_private(self.request) else: """ Check if there exists any categories. """ if not Category.first_active(): self.request.session.flash(self.missing_shared_cat, 'error') return HTTPFound(location=self.request .route_url('expenditures')) form.category_id.query = Category.all_active(self.request) if self.request.method == 'POST' and form.validate(): e = Expenditure() form.populate_obj(e) e.user_id = authenticated_userid(self.request) e.category_id = form.category_id.data.id DBSession.add(e) self.request.session.flash('Expenditure %s created' % (e.title), 'success') """ A bit ugly, but redirect the user based on private or not. """ if private: return HTTPFound(location= self.request .route_url('expenditures', _query={'private': 1})) return HTTPFound(location=self.request.route_url('expenditures')) return {'title': 'New private expenditure' if private else 'New expenditure', 'form': form, 'action': 'expenditure_new', 'private': private}
def expenditures(self): """ Return a paginated list of active expenditures. Handles both private and shared expenditures. """ result = {} private = self.request.params.get('private') if private: categories = Category.all_private(self.request).all() else: categories = Category.all_active(self.request).all() for c in categories: e = Expenditure.with_category(c.id) if e: s = Expenditure.with_category(c.id, total_only=True) result[c.title] = [e, s] return {'items': result, 'title': 'Private expenditures' if private else 'Shared expenditures', 'private': private}
def category_archive(self): """ Archive category, returns redirect. """ id = int(self.request.matchdict.get('id')) c = Category.by_id(id) if not c: return HTTPNotFound() """ Authorization check. """ if c.private and c.user_id is not authenticated_userid(self.request): return HTTPForbidden() c.archived = True DBSession.add(c) self.request.session.flash('Category %s archived' % (c.title), 'status') return HTTPFound(location=self.request.route_url('categories'))
def invoices_search(self): """ Get a list of invoices based on search arguments. """ page = int(self.request.params.get('page', 1)) form = InvoiceSearchForm(self.request.GET, csrf_context=self.request.session) form.categories.query = Category.all_active(self.request) form.creditors.query = Creditor.all_active(self.request) if self.request.method == 'GET' and form.validate(): q = form.query.data categories = form.categories.data creditors = form.creditors.data fromdate = form.fromdate.data todate = form.todate.data invoices = Invoice.searchpage(self.request, page, qry=q, categories=categories, creditors=creditors, fromdate=fromdate, todate=todate, ) total = Invoice.searchpage(self.request, page, qry=q, categories=categories, creditors=creditors, fromdate=fromdate, todate=todate, total_only=True, ) else: invoices = Invoice.searchpage(self.request, page) total = Invoice.searchpage(self.request, page, total_only=True) return {'paginator': invoices, 'form': form, 'title': 'Search', 'searchpage': True, 'total': total}
def invoice_edit(self): """ Edit invoice view. This method handles both post, and get requests. """ id = int(self.request.matchdict.get('id')) i = Invoice.by_id(id) if not i: return HTTPNotFound() """ Authorization check. """ if (i.category.private and i.category.user_id is not authenticated_userid(self.request)): return HTTPForbidden() """ Authorization check. """ if (i.creditor.private and i.creditor.user_id is not authenticated_userid(self.request)): return HTTPForbidden() form = InvoiceEditForm(self.request.POST, i, csrf_context=self.request.session) if not i.files: del form.files else: form.files.query = i.files private = self.request.params.get('private') if private: """ Check if the necessary object exists. """ if not Category.first_private(self.request): self.request.session.flash(self.missing_priv_cat, 'error') return HTTPFound(location=self.request.route_url('invoices')) if not Creditor.first_private(self.request): self.request.session.flash(self.missing_priv_cred, 'error') return HTTPFound(location=self.request.route_url('invoices')) form.category_id.query = Category.all_private(self.request) form.creditor_id.query = Creditor.all_private(self.request) else: """ Check if the necessary object exists. """ if not Category.first_active(): self.request.session.flash(self.missing_shared_cat, 'error') return HTTPFound(location=self.request.route_url('invoices')) if not Creditor.first_active(): self.request.session.flash(self.missing_shared_cred, 'error') return HTTPFound(location=self.request.route_url('invoices')) form.category_id.query = Category.all_shared() form.creditor_id.query = Creditor.all_shared() if self.request.method == 'POST' and form.validate(): form.populate_obj(i) i.category_id = form.category_id.data.id i.creditor_id = form.creditor_id.data.id if form.files: i.files = form.files.data """ If file, make file object and save/create file. """ upload = self.request.POST.get('attachment') try: f = File() f.filename = f.make_filename(upload.filename) f.filemime = f.guess_mime(upload.filename) f.write_file(upload.file) f.title = 'Invoice.' +\ form.title.data + '.' +\ self.randomstr(6) + '.' +\ form.category_id.data.title + '.' +\ form.creditor_id.data.title + '.' +\ str(i.due) if private: f.private = True f.user_id = authenticated_userid(self.request) DBSession.add(f) i.files.append(f) except Exception: self.request.session.flash('No file added.', 'status') self.request.session.flash('Invoice %s updated' % (i.title), 'status') self.update_flash() if private: return HTTPFound(location= self.request .route_url('invoices', _query={'private': 1})) return HTTPFound(location=self.request.route_url('invoices')) form.category_id.data = i.category form.creditor_id.data = i.creditor return {'title': 'Edit private invoice' if private else 'Edit invoice', 'form': form, 'id': id, 'action': 'invoice_edit', 'private': private, 'invoice': i}
def invoice_create(self): """ New invoice view. This method handles both post, and get requests. """ form = InvoiceCreateForm(self.request.POST, csrf_context=self.request.session) private = self.request.params.get('private') if private: """ Check if the necessary object exists. """ if not Category.first_private(self.request): self.request.session.flash(self.missing_priv_cat) return HTTPFound(location=self.request.route_url('invoices')) if not Creditor.first_private(self.request): self.request.session.flash(self.missing_priv_cred) return HTTPFound(location=self.request.route_url('invoices')) form.category_id.query = Category.all_private(self.request) form.creditor_id.query = Creditor.all_private(self.request) else: """ Check if the necessary object exists. """ if not Category.first_active(): self.request.session.flash(self.missing_shared_cat, 'error') return HTTPFound(location=self.request.route_url('invoices')) if not Creditor.first_active(): self.request.session.flash(self.missing_shared_cred, 'error') return HTTPFound(location=self.request.route_url('invoices')) form.category_id.query = Category.all_shared() form.creditor_id.query = Creditor.all_shared() if self.request.method == 'POST' and form.validate(): i = Invoice() form.populate_obj(i) i.user_id = authenticated_userid(self.request) i.category_id = form.category_id.data.id i.creditor_id = form.creditor_id.data.id """ If file, make file object and save/create file. """ upload = self.request.POST.get('attachment') try: f = File() f.filename = f.make_filename(upload.filename) f.filemime = f.guess_mime(upload.filename) f.write_file(upload.file) f.title = 'Invoice.' +\ form.title.data + '.' +\ self.randomstr(6) + '.' +\ form.category_id.data.title + '.' +\ form.creditor_id.data.title + '.' +\ str(i.due) if private: f.private = True f.user_id = authenticated_userid(self.request) DBSession.add(f) i.files = [f] except Exception: self.request.session.flash('No file added.', 'status') DBSession.add(i) self.request.session.flash('Invoice %s created' % (i.title), 'success') self.update_flash() if private: return HTTPFound(location= self.request .route_url('invoices', _query={'private': 1})) return HTTPFound(location=self.request.route_url('invoices')) return {'title': 'New private invoice' if private else 'New invoice', 'form': form, 'action': 'invoice_new', 'private': private, 'invoice': False}