Example #1
0
    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')
Example #2
0
    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}
Example #3
0
    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}
Example #4
0
    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'}
Example #5
0
    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)}
Example #6
0
    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'}
Example #7
0
    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}
Example #8
0
    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}
Example #9
0
    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}
Example #10
0
    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}
Example #11
0
    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'))
Example #12
0
    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}
Example #13
0
    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}
Example #14
0
    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}