Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,9 @@ docker build -t invoiceshelf/docs .

## Deployment

Documentation is automatically built and published to GitHub Container Registry on every push to master.
Every push builds and publishes a commit-SHA image. Pushes to `master` also publish the
`latest` image.

Images are available at:
- `ghcr.io/invoiceshelf/docs:latest` - Latest master branch
- `ghcr.io/invoiceshelf/docs:<commit-sha>` - Specific commit builds
- `ghcr.io/invoiceshelf/docs:latest` - Latest `master` build
- `ghcr.io/invoiceshelf/docs:<commit-sha>` - A specific commit build
1 change: 1 addition & 0 deletions docs/.vitepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ export default defineConfig({
{ text: 'Items', link: '/guide/items.md' },
{ text: 'Estimates', link: '/guide/estimates.md' },
{ text: 'Invoices', link: '/guide/invoices.md' },
{ text: 'Credit Notes', link: '/guide/credit-notes.md' },
{ text: 'Recurring Invoices', link: '/guide/recurring-invoices.md' },
{ text: 'Payments', link: '/guide/payments.md' },
{ text: 'Expenses', link: '/guide/expenses.md' },
Expand Down
11 changes: 7 additions & 4 deletions docs/developer-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,15 @@ lang: en-US
# Developer Guide

This guide will help you set up your development environment and get started with InvoiceShelf.
There are three primary ways to install and set up InvoiceShelf for development: Docker, NGINX/PHP-FPM, and Laravel Herd.
There are three primary ways to set up InvoiceShelf for development: Docker,
NGINX/PHP-FPM, and Laravel Herd. The application currently uses Laravel 13, PHP 8.4,
Node.js 24, and pnpm.


## Docker Environment

If you want to use the pre-configured Docker dev environment
Use the application's `./devenv` wrapper to choose and start the pre-configured Docker
development environment.

[[Read more]](./developer/docker.md)

Expand All @@ -24,7 +27,7 @@ If you want to use Laravel Herd on your Windows/Mac machine

## Manual Nginx/php-fpm

If you want to install InvoiceShelf on plain Linux Debian/Ubuntu
Use this when you want to run the application directly on a Linux host.

[[Read more]](./developer/manual.md)

Expand All @@ -36,4 +39,4 @@ Hopefully one of those guides will help you get started with InvoiceShelf develo

If you have any questions or run into issues, feel free to open an issue on [GitHub](https://github.com/InvoiceShelf/InvoiceShelf/issues).

Happy coding! 🧑‍💻
Happy coding! 🧑‍💻
81 changes: 43 additions & 38 deletions docs/developer/docker.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,57 +5,60 @@ lang: en-US

# Setting Up with Docker

Using Docker is one of the easiest ways to set up InvoiceShelf for development. The necessary Docker configuration files are located in the `.dev` folder of the repository.
Using Docker is one of the easiest ways to set up InvoiceShelf for development. The
repository provides a `./devenv` wrapper that selects the supported Compose configuration,
adds the local hostname when needed, and starts the stack. The Compose files live in
`docker/development/`; `.dev` is no longer used.

## Step 1 : Clone the Repository

If you forked the project, you can use the fork url instead.

```bash
git clone https://github.com/InvoiceShelf/InvoiceShelf.git
git clone --branch 3.x https://github.com/InvoiceShelf/InvoiceShelf.git
cd InvoiceShelf
cp .env.example .env
```

If you are using Linux/macOS, you need to setup the correct permissions:
```bash
chmod 775 storage/framework storage/logs bootstrap/cache
```

## Step 2 : Set up DNS host

The dockerized development environment uses `invoiceshelf.test` local domain.

This domain needs to be set up on your machine to access the default configuration.

### a.) Linux/MacOS

If you are using Linux or macOS, edit `/etc/hosts` as root/sudo.

### b.) Windows
## Step 2 : Start the development environment

If you are using Windows, run Notepad as administrator and File > Open the `hosts` file in `C:Windows\System32\drivers\etc`
Run the wrapper with no arguments. It verifies Docker, adds `invoiceshelf.test` to the
hosts file when necessary (requesting sudo on Linux/macOS), then asks you to choose MySQL,
PostgreSQL, or SQLite and whether to enable Gotenberg.

### Finalize
```bash
./devenv
```

Add the following line at the end of the hosts file to make the invoiceshelf.test available:
Your selected Compose file is saved in `.devenvconfig`. Later sessions can use:

```
127.0.0.1 invoiceshelf.test
```bash
./devenv start
./devenv stop
./devenv logs
./devenv shell
./devenv run php artisan migrate
./devenv test
./devenv format
```

## Step 3 : Spin up Docker
## Step 3 : Install application dependencies

To spin up the Docker environment, run:
Install PHP dependencies and generate an application key inside the running PHP container:

```bash
docker compose -f docker/development/docker-compose.mysql.yml up --build
./devenv run composer install
./devenv run php artisan key:generate
```

Once the environment is up and running you have the following containers:
The frontend runs on the host. Install Node.js 24, enable Corepack, install the locked
dependencies, and keep the Vite development server running while you work:

- invoiceshelf-dev-php
- invoiceshelf-dev-mysql (or pgsql for sqlite)
- invoiceshelf-dev-nginx
```bash
corepack enable
pnpm install --frozen-lockfile
pnpm dev
```

## Step 4 : Access the Application

Expand All @@ -64,34 +67,36 @@ Once the containers are up and running, you can access the InvoiceShelf applicat

## Useful details

### a.) Working with composer/npm/phpunit
### a.) Working with Composer, pnpm, and tests

To access `composser`, `npm`, `vendor/bin/pint`, `vendor/bin/pest`, you need to SSH into the `invoiceshelf-dev-php` container as follows:
Use `./devenv run` to run a command in the PHP container, or use `./devenv shell` for an
interactive shell:

```bash
docker exec -it --user invoiceshelf invoiceshelf-dev-php /bin/bash
./devenv run php artisan migrate
./devenv test
./devenv format
```

### b.) Previewing the database

To see the database we use a tool called Adminer.

You can open it at http://invoiceshelf.test:8080

You can log in with the database details as [explained here](https://github.com/InvoiceShelf/InvoiceShelf/blob/develop/.dev/README.md#2-databases).
You can open it at `http://localhost:8080`.


### c.) Previewing Mail

To see the mail we use a tool called Mailpit.

You can open it at http://invoiceshelf.test:8025
You can open it at `http://localhost:8025`.

---

&nbsp;

For more details, refer to the [Docker setup README](https://github.com/InvoiceShelf/InvoiceShelf/blob/develop/.dev/README.md).
For implementation details, refer to
[docker/development](https://github.com/InvoiceShelf/InvoiceShelf/tree/3.x/docker/development).

&nbsp;

Expand Down
31 changes: 18 additions & 13 deletions docs/developer/manual.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ lang: en-US

# Setting Up with NGINX/PHP-FPM

Setting up InvoiceShelf with NGINX and PHP-FPM is ideal for Linux systems. Follow the Laravel deployment guide for NGINX to set up your environment.
Setting up InvoiceShelf with NGINX and PHP-FPM is ideal for Linux systems. Follow the
[Laravel 13 NGINX deployment guide](https://laravel.com/docs/13.x/deployment#nginx) for the
web-server configuration.

## Step 1 : Install Dependencies

Expand All @@ -23,21 +25,22 @@ sudo apt install nginx
# Install required tools
sudo apt install git curl zip unzip sqlite3

# Install PHP/PHP-FPM
sudo apt install php8.3-fpm php8.3-gd php8.3-exif php8.3-mbstring php8.3-zip php8.3-curl php8.3-bcmath
# Install PHP 8.4/PHP-FPM and the extensions InvoiceShelf uses
sudo apt install php8.4-fpm php8.4-gd php8.4-exif php8.4-mbstring php8.4-zip php8.4-curl php8.4-bcmath php8.4-xml php8.4-intl

# Install NPM
# Install Node.js 24 and enable pnpm through Corepack
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.5/install.sh | bash
nvm install 20
nvm use 20
nvm install 24
nvm use 24
corepack enable
```

## Step 2 : Clone the Repository

If you forked the project, you can use the fork url instead.

```bash
git clone https://github.com/InvoiceShelf/InvoiceShelf.git
git clone --branch 3.x https://github.com/InvoiceShelf/InvoiceShelf.git
cd InvoiceShelf
```

Expand All @@ -58,11 +61,11 @@ cp .env.example .env

```bash
composer install
npm install
# If you want one-time build run:
npm run prod
pnpm install
# For a one-time production build:
pnpm build
# If you want dev builds run:
npm run dev
pnpm dev
```

## Step 5 : Generate Application Key
Expand All @@ -79,7 +82,9 @@ php artisan migrate

## Step 7 : Configure NGINX

Follow the Laravel guide to create NGINX server block configuration at [Laravel NGINX Deployment Guide](https://laravel.com/docs/11.x/deployment#nginx)
Follow the [Laravel 13 NGINX deployment guide](https://laravel.com/docs/13.x/deployment#nginx)
to create the NGINX server block configuration. Point the document root at the project's
`public` directory.

Finally, you need to restart NGINX.

Expand All @@ -93,4 +98,4 @@ Once the server is running, you can access the InvoiceShelf application in your

This guide should help you get started with InvoiceShelf development. If you have any questions or run into issues, feel free to open an issue on [GitHub](https://github.com/InvoiceShelf/InvoiceShelf/issues).

Happy coding! 🧑‍💻
Happy coding! 🧑‍💻
72 changes: 72 additions & 0 deletions docs/guide/credit-notes.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
# Credit Notes

A credit note reverses an invoice you have already sent. Once an invoice is out, its number is spent: correcting it by editing the original leaves a gap in your books, so accounting practice is to issue a second document that cancels the first (a *Stornorechnung*, in German bookkeeping). InvoiceShelf does exactly that.

A credit note is a document of its own, with its own number, and it carries negated amounts. Reverse the whole invoice and the two documents sum to zero, which is what makes the reversal complete and auditable. Reverse part of it and the credit note carries only the part you credited.

## Creating one

Open the invoice and choose **Create Credit Note** from its action menu. A form opens listing every line of the invoice: what was invoiced, how much of it has already been credited, how much is left, and an editable quantity to credit.

Everything still creditable is filled in for you, so accepting the form as it opens reverses the invoice in full. That is what most credits are, and it stays a two-click job.

To credit less, lower a quantity or clear a line's checkbox. Only the line subtotals are shown, because discounts and taxes are not yours to apportion: InvoiceShelf credits them in proportion to the lines and quantities you chose, so the credit note always agrees with the document it reverses, down to the cent.

A **Reason** can be given and is optional. It is stored on the credit note and printed on the document, which is where an auditor will look for it.

The result is saved as a new credit note in **Draft**.

## Crediting an invoice more than once

An invoice can carry several credit notes. Each one credits some of what is still left, and the quantities already credited by earlier notes are shown in the form so you always know where you stand. Crediting a line in instalments adds up to exactly what crediting it in one go would have produced.

Once every line has been credited in full there is nothing left to reverse, and the invoice will not accept another credit note.

## What can be credited

| Rule | Why |
|---|---|
| A line can be credited only down to the quantity that is left of it | Anything more would reverse goods that were never invoiced |
| A credit cannot exceed the amount still outstanding on the invoice | Payments have already settled part of it, and only the unpaid remainder can be reversed. A fully paid invoice cannot be credited at all; refund it instead |
| An invoice with nothing left to credit cannot be credited again | The reversal is already complete |
| A credit note cannot itself be credited | It is the reversal, not the thing being reversed |
| Draft invoices cannot be credited | An invoice that was never issued has nothing to reverse. Edit or delete it instead |
| A credited invoice can no longer be edited | Its line items anchor the lines of every credit note that reverses it, so changing them would falsify documents already issued |

Credit notes cannot be edited after they are created. If you credited the wrong thing, delete the credit note: the original invoice gets back exactly what that note took off it, balance included, and any other credit notes on the invoice stay as they are.

Deleting the invoice while a credit note still reverses it is blocked. Delete both together, or delete the credit note first.

## What it does to the original invoice

A credit note reduces the invoice's outstanding balance by the amount credited.

Credit part of the invoice and it stays open for the remainder. Its detail page shows a **Partially credited** badge with the amount credited so far, next to its real paid status: a credit is not a payment, and an invoice that was half credited and never paid is still unpaid, just for less.

Credit all of it and the invoice is settled. It drops out of the unpaid and awaiting-payment views, since nothing is owed on it any more, and shows a **Cancelled** badge instead.

Both badges link through to the credit notes involved, and each credit note carries a matching banner linking back to the invoice it reverses.

## Sending it

A credit note starts as a draft and goes to the customer through the normal Send flow, the same one you use for invoices. Its email uses a credit-note template rather than the invoice one.

The PDF renders through whichever invoice template the company uses (`invoice1`, `invoice2`, `invoice3` or a custom design), so a credit note looks like the invoice it reverses. On top of that it carries a credit-note banner, a reference line naming the original invoice and its date, the reason if you gave one, and negative amounts throughout.

The original invoice's PDF says what happened to it too. A partly credited invoice carries a **Partially Credited** banner naming the amount and the credit notes it came from; a fully credited one carries the **Cancelled** banner, listing every credit note that reversed it. Its totals block reports **Amount Credited** separately from **Amount Paid**, so a document settled by a credit note never claims money that was never received.

::: tip Custom templates
A custom invoice template needs one include to display those banners. See [custom templates](/guide/custom-templates.md#credit-notes).
:::

## Numbering

Credit notes have their own sequence, independent of invoices. The default format is `CN-000001`, and creating a credit note never advances the invoice counter.

You can change the format under **Settings → Customization → Invoices**, where a **Credit Notes** number customizer sits beside the invoice one. It works the same way: prefix, series and sequence are yours to arrange.

## Dashboard and reports

Credit note totals are negative, so they subtract from your sales figures automatically. A reversed invoice and its credit note cancel out, and revenue for the period reflects that.

Invoice counts do not include credit notes, so the number of invoices you see is still the number of invoices you issued.
Loading
Loading