↶ Back to Rechnungstellung

at_rechnungstellung – User and administrator manual

Version 1.7.0 · Redmine 5.1 and 6 · GPLv2

This manual covers installation, configuration and daily use of the atori invoicing plugin.


1. Overview

The plugin adds customer master data, draft-to-paid invoice workflow, ZUGFeRD 2.x-compliant PDF output and payment tracking to Redmine. Invoices are independent of Redmine's project and issue models, but individual invoice items can reference approved TimeEntry records to build billable line items straight from tracked hours.

Key concepts:


2. Requirements


3. Installation

cd /path/to/redmine
unzip at_rechnungstellung-1.7.0.zip -d plugins/
bundle install
bundle exec rake redmine:plugins:migrate NAME=at_rechnungstellung RAILS_ENV=production
# restart Redmine

bundle install is required here because the plugin brings its own Gemfile declaring prawn and prawn-table.

Verifying the install

After restart, log in as administrator and open Administration → Plugins. The Rechnungstellung plugin should appear with version 1.7.0. Invoices and Customers entries should appear in the top navigation for users with the corresponding permissions.

Updating Redmine

A Redmine update is harmless for the plugin only if the order is right. Redmine loads every plugin at start-up; if a plugin does not match the new version, the whole instance fails to start until the plugin folder is removed. The data in the plugin tables is never affected.

Rule: every plugin version supports the current and the previous Redmine line (currently 5.1 and 6). Which plugin version is tested with which Redmine version is listed in the compatibility overview on redmine-plugins.atori.de.

Order of operations:

  1. Check the compatibility overview for the plugin version that supports your target Redmine version.
  2. Upgrade the plugin to that version first (unpack the zip, redmine:plugins:migrate, restart) and verify briefly on the old Redmine version. This bridging version runs on both Redmine versions.
  3. Then update Redmine following the Redmine upgrade guide, run bundle exec rake redmine:plugins:migrate RAILS_ENV=production again and restart.
  4. Rehearse all of this on a copy of the installation first.

Fallback when no bridging version exists (for example because the new Redmine requires a newer Ruby):

cd /path/to/redmine
mv plugins/at_rechnungstellung ../at_rechnungstellung.old        # set the folder aside, do NOT migrate
# update Redmine
# unpack the new plugin version into plugins/at_rechnungstellung
bundle exec rake redmine:plugins:migrate NAME=at_rechnungstellung RAILS_ENV=production
# restart Redmine

The plugin tables stay untouched in the database; the new plugin version brings the schema up to date with its own migrations.

> Never run VERSION=0 as part of an update. Rolling the migrations back > to version 0 drops the plugin tables and with them all plugin data. It > belongs to a final uninstall only (see below).

Uninstall

> Back up your invoices first. The plugin does not store PDF or XML > files; both are generated from the database on every request. Rolling the > migrations back to version 0 drops the plugin tables and with them all > customers, invoices, items and payments for good. Invoices are subject to > statutory retention periods (eight years in Germany). Before uninstalling, > download every issued invoice as PDF (and XML where applicable) and keep > the files outside Redmine. From version 1.7.0 the bulk export in the > invoice list does this in one step. > > Deleting only the plugin folder without rolling back the migrations keeps > the tables in the database: Redmine no longer shows them, but a later > reinstall finds the data again.

cd /path/to/redmine
bundle exec rake redmine:plugins:migrate NAME=at_rechnungstellung VERSION=0 RAILS_ENV=production
rm -rf plugins/at_rechnungstellung
# restart Redmine

The rake task rolls back the plugin's migrations and drops its tables (customers, customer-project mapping, invoices, invoice items, time-entry links, payments). Core Redmine data is untouched.


4. Configuration

4.1 Plugin settings

Open Administration → Plugins → Rechnungstellung → Configure. The settings are grouped into four sections:

Issuer details – name, address, country, tax number, VAT ID, email, phone, website, bank details. These populate the header and footer of every generated PDF.

Invoice numbering – number format as free text with placeholders: {{year}}, {{year2}}, {{month}}, {{day}}, {{seq}} (running number, length via sequence length) plus the customer placeholders {{customer_prefix}} (short code), {{customer_number}} and {{customer}}; the legacy spelling RG-{YYYY}-{NNNN} still works. The running number counts per fully expanded prefix, so a format like {{customer_prefix}}-{{year}}-{{seq}} yields a separate number range per customer and year. Also: padding for the sequential counter, default currency, default VAT rate, default payment terms (in days).

PDF layout – logo position (left or right, configurable margin and width), colours (primary, secondary, title, total gross), font, table styling (zebra, border style, padding), DIN-5008 letter-head block, margins, free-form intro / thank-you / legal text.

E-mail dispatch – default subject and body templates, optional BCC address for the issuer's archive.

Hourly rates – choose the numeric custom field (format Integer or Float) that carries an overriding hourly rate on issues and on projects. Create the fields first under Administration → Custom fields (type Issues or Projects); an issue field must be enabled for the trackers and projects concerned. (not used) switches that level off. The Create fields now button does the setup in one step: it creates a float field Hourly rate for issues (all trackers, all projects) and one for projects, makes them visible only to roles with invoicing permissions and selects both. If the chosen issue field is inactive for a tracker or a customer project, the block shows a warning with a link to the field, because time logged there would silently be billed at the project or customer rate. See section 5.1 for the rules.

Settings live in a dedicated partial and are all form fields – no YAML or environment variables.

4.2 Grant permissions

Five permissions are available under Administration → Roles and permissions → Invoicing:

PermissionScopeEffectTypical role
View invoicesper projectInvoices, PDF/XML, payments and bulk export for the customers of the user's own projectsProject lead
Manage invoicesper projectCreate, edit, issue, cancel, send, archive for the customers of the user's own projectsProject lead
View all invoicesglobalRead every invoice of every customerAccounting
Manage all invoicesglobalEdit every invoice of every customerAccounting
Manage customersglobalCreate and change customer master dataProject lead, accounting

The permissions work per customer, not per project. A customer has one or more projects in its master data. Whoever holds a role with View invoices in one of those projects sees all invoices of that customer – including invoices whose positions come from another project of the same customer, and invoices without any project reference (manual positions). An invoice is a document of the customer; it cannot be shown by halves.

Example: customer Müller GmbH has the projects "Website" (lead Anna) and "App" (lead Ben). Anna and Ben both see all invoices of Müller GmbH, including those of the other project. If the invoices must stay separate, create Müller GmbH as two customers ("Müller GmbH – Website", "Müller GmbH – App"), each with its own project.

Accounting gets the two global … all invoices permissions and then sees everything regardless of project memberships. Manage customers stays global because customers span projects.

> Upgrade note (1.6 → 1.7): View invoices and Manage invoices were > global up to 1.6. The migration gives every role that held one of them > the matching … all invoices permission automatically, so nothing > changes for existing installations. To use the customer scope, remove > the … all permission from the project-lead roles afterwards.

4.3 Verify the PDF layout with a demo invoice

At the bottom of the plugin settings page a Demo PDF section offers a download link that renders a sample invoice PDF using the current issuer details, logo, colors, number format and PDF-layout options. No real customer or invoice is created; the sample uses a fictional "Musterfirma GmbH" with three line items (two at the default VAT rate, one at 7%) to exercise typical table layout, thousands separators, and multi-rate totals.

Workflow:

  1. Change issuer details, colors, logo or layout options on the settings page.
  2. Save the settings (important — the demo uses saved values, not the current unsaved form state).
  3. Click Download demo invoice as PDF; the PDF opens in a new tab.
  4. If anything looks off, adjust the relevant settings and repeat.

The demo PDF is rendered through the same builder as real invoices, so what you see here is what customers will receive.


5. Usage

5.1 Creating a customer

Customers → New customer. Fill in name, address, country code (ISO 3166-1 alpha-2), optionally VAT ID, tax number and banking data. The contact is captured as separate Salutation, First name and Last name fields. Assign one or more Redmine projects to enable their time entries to be pulled into invoices for this customer; projects and their mapping can be set in a single step already when creating the customer.

Number range per customer. The Invoice number prefix field is the short code the {{customer_prefix}} placeholder inserts into the number format (e.g. ACME). The Start invoice number sets the running number the next invoice of this customer is counted from; it acts as a floor until the running sequence overtakes it.

Approval per project. In the customer's project list, each project also carries a Bill without approval option. It is off by default, i.e. that project's hours must be approved via at_zeiterfassung before they can be invoiced. When set, the project's hours can be billed without an explicit approval.

Minimum granularity. The Minimum granularity (min) field is the unit at_zeiterfassung rounds the logged time up to when a timer is stopped (e.g. 15 minutes). Empty = no rounding.

Overriding hourly rates per project or issue. The customer's hourly rate is the default. To bill a project or a single issue at a different rate (e.g. remote work cheaper than on-site visits), enter the rate in the custom field selected under Hourly rates in the plugin settings. Each time entry is then priced with the issue's rate, otherwise the project's rate, otherwise the customer's rate. Blank or 0 means "not set" and falls through to the next level. Subtasks inherit the rate of the nearest parent issue that has one. Who may see and edit the field is governed by the roles, as with any custom field; fields created via Create fields now are visible only to roles with invoicing permissions, so rates stay hidden from other project members. When building an invoice from time, the hours picker shows the rate actually applied per entry, and hours with different rates become separate invoice items. The currency is always the customer's.

Choose the customer's e-invoice format: ZUGFeRD (default, B2B), XRechnung (for German public-sector recipients) or none (plain PDF only). For XRechnung customers, enter the Leitweg-ID – this is mandatory per the XRechnung specification and is validated on save.

5.2 Creating a draft invoice

Invoices → New invoice. Pick a customer; the issuer data is taken from the plugin settings. Add line items manually, or use From time entries to pull hours for a date range. Items can mix sources freely – tracked hours alongside flat-fee manual lines.

In the time picker, entries are grouped by project. Each project group has a header checkbox that selects or deselects all of that project's entries at once. Which entries are offered depends on the project's approval setting for the customer: projects that require approval show only approved hours; projects marked Bill without approval show all hours in the range.

Each item carries its own unit, unit price and VAT rate so mixed-rate invoices (e.g. 19% + 7% in Germany) produce correct totals without manual reconciliation.

5.3 Preview the PDF

Preview renders the PDF on the fly from the current draft without persisting. Useful for visual checks during editing. The preview is not numbered – number assignment happens only at issuance (see next).

5.4 Issue the invoice

Issue assigns the next invoice number according to the configured format, sets the state to issued, and finalises the document. Issued invoices are read-only: the underlying PDF and the invoice number become the commercial record. Changes require cancellation (see §5.7) and a new draft.

The e-invoice output matches the customer's configured format: ZUGFeRD customers receive a hybrid PDF plus a downloadable {number}-factur-x.xml; XRechnung customers receive a plain PDF plus a separate {number}-xrechnung.xml; none customers receive a plain PDF without any XML.

5.5 Email the invoice

Send by email opens a composer with the default subject and body pre-filled from settings. The PDF is attached automatically. An optional BCC to the issuer's archive mailbox is honoured. After sending, the sent_at timestamp is recorded.

5.6 Record a payment

New payment on the invoice page takes a date, amount and optional reference (bank transaction ID, cheque number). Partial payments move the invoice to partially_paid and reduce the open amount displayed on the invoice. A payment that closes the full amount transitions the invoice to paid.

Payments can be deleted to correct mistakes; the state is recalculated from the remaining payments.

5.7 Cancel an invoice

An issued invoice that turns out to be wrong is cancelled, not deleted. Cancel creates a reverse cancellation invoice with a new number and links it to the original. Both the original and the cancellation are preserved for the audit trail, and payment tracking reflects the zero balance after cancellation.

5.8 Overdue and reporting

The Invoices list has filters for open, overdue, paid, cancelled and date ranges. Overdue is computed from the invoice's due date relative to today. Export to CSV via the standard Redmine list export.

Archiving. Issued, paid and cancelled invoices can be archived: they disappear from the default list view and from the figures in the list head (open, overdue, paid) but are kept in full – number, PDF, XML, payments and the link to the cancellation invoice. The Archive filter switches between Hide archived (default), Archived only and Show all. Archive a single invoice on its page or several at once through the checkboxes in the list; both require the Manage invoices permission. Drafts are deleted, not archived. Cancelling an archived invoice brings it back out of the archive automatically, because the case is open again. Archiving is not deletion: for retention purposes archived invoices count like all others.

Bulk export. Invoices → Bulk export delivers all issued invoices of a period (issue date) as one ZIP file: per invoice the PDF and, where the customer has an e-invoice format, the XML file (NUMBER-factur-x.xml or NUMBER-xrechnung.xml), in folders per year, plus rechnungen.csv with number, customer, date, due date, net, gross, state, open amount, archive date and cancellation reference. Drafts are left out; cancellation invoices and archived invoices are included, since the export serves retention. Optionally narrow by customer and state. The View invoices permission is enough. The export is built on request; above the limit set in the plugin settings (default 200 invoices) it asks for a shorter period. Before an uninstall this is the way to secure the records (see section 3).


6. Troubleshooting

PDF rendering fails with "prawn not found" or similar. The plugin's Gemfile declares prawn and prawn-table. Run bundle install in the Redmine directory after installing the plugin, then restart the Redmine process.

Time entries don't appear when building from time. Verify that (1) the selected customer has the source project assigned under its master record, (2) the date range covers the entries, and (3) the entries are flagged as approved via the at_zeiterfassung plugin if approval is required for that project. If Bill without approval is set for the project on the customer, all hours in the range appear; otherwise unapproved entries are excluded by design.

Invoice number not assigned. Invoice numbers are assigned at the issued transition, not on draft save. Check the state of the invoice – a draft shows "no number yet" and remains fully editable.

The recipient doesn't accept the e-invoice XML. Check the customer's e-invoice format first. Public-sector recipients in Germany typically require XRechnung (pure XML, Leitweg-ID validated) – not ZUGFeRD. Private recipients generally accept ZUGFeRD (hybrid PDF/A-3 with embedded EN-16931 XML). Switch the customer's format to match the recipient's requirement and re-issue. If a specific profile variant is demanded (Factur-X Basic, EN 16931 Comfort, XRechnung-CII) and the output is rejected, report back with the recipient's exact specification – we will verify profile conformance.

XRechnung customer refuses to save: "Leitweg-ID can't be blank". The Leitweg-ID is mandatory for customers whose e-invoice format is set to XRechnung. Enter the Leitweg-ID as communicated by the public-sector recipient, or change the format to ZUGFeRD or none if XRechnung is not actually required.

Logo placement or colours don't apply. Plugin settings are cached. Restart the Redmine process or clear the Rails cache after changing PDF-layout settings. Logo paths are resolved relative to the Redmine root; symlink or copy the image into a stable location before referencing it.

Email dispatch fails. Redmine's standard mailer settings are used (config/configuration.yml → email_delivery). If Redmine's issue notifications work but invoice emails don't, check for attachment size limits on the outbound SMTP server – invoice PDFs with rich layouts can exceed a few hundred KB.


7. Support

Support is included for twelve months from the date of purchase.

E-mail: support@atori.de Initial response: within 48 hours on business days.

When reporting issues, please include: