---
title: "Point of Sale"
description: "Butik och restaurang. Varje app är en modul i en gemensam datamodell."
canonical: "https://obop-platform.sliplane.app/sv/apps/pos/"
lang: "sv"
---

# Point of Sale

## Vad den är till för

Model a shop till: configuration, cash-controlled sessions, orders with lines and payment lines per method. It records what happened at the till; it is not a payment terminal integration, and card numbers must never be stored.

## Vad paketet gör och inte gör

Shop tills: a point-of-sale configuration, cash-controlled sessions that are opened and closed, orders with lines, and payment lines per method. A refund and the closing of a session need a human approval from a manager; agents may only propose them. Totals, change and cash differences are entered, not computed. Card numbers must never be stored; keep only the payment provider's reference. Needs the Products package.

## Modeller

### `pos_config`

A point of sale (a till or a shop) and its rules

Läsgrupp: `pos.user`. Skrivgrupp: `pos.manager`.

| Fält | Typ | Dataklass | Personuppgift | Grupp | Agenter ser | Beskrivning |
|---|---|---|---|---|---|---|
| `name` | text | `none` | nej | `pos.user` | i klartext | Name of the till or shop, for example Main street shop |
| `currency` | text | `none` | nej | `pos.user` | i klartext | ISO 4217 currency code, for example EUR |
| `receipt_header` | longtext | `none` | nej | `pos.user` | i klartext | Text printed at the top of receipts |
| `cash_control` | bool | `none` | nej | `pos.user` | i klartext | Whether sessions must count the cash in the drawer when they open and close |
| `default_opening_cash` | money | `none` | nej | `pos.user` | i klartext | Cash normally left in the drawer overnight (minor currency units) |
| `allow_refunds` | bool | `none` | nej | `pos.user` | i klartext | Whether cashiers may propose refunds at this point of sale |
| `active` | bool | `none` | nej | `pos.user` | i klartext | Whether the point of sale is in use |

### `pos_session`

One shift of selling at a point of sale, from opening to closing the cash drawer

Läsgrupp: `pos.user`. Skrivgrupp: `pos.user`.

| Fält | Typ | Dataklass | Personuppgift | Grupp | Agenter ser | Beskrivning |
|---|---|---|---|---|---|---|
| `config_id` | ref → pos_config | `none` | nej | `pos.user` | i klartext | The point of sale the session belongs to |
| `cashier` | text | `internal` | ja | `pos.user` | maskerad | Name of the cashier who opened the session |
| `opened_on` | date | `none` | nej | `pos.user` | i klartext | Day the session was opened (YYYY-MM-DD) |
| `closed_on` | date | `none` | nej | `pos.user` | i klartext | Day the session was closed (YYYY-MM-DD) |
| `opening_cash` | money | `financial` | nej | `pos.user` | undanhållen | Cash counted in the drawer at opening (minor currency units) |
| `expected_cash` | money | `financial` | nej | `pos.user` | undanhållen | Cash the drawer should hold at closing: opening cash plus cash payments (entered, not computed) |
| `closing_cash` | money | `financial` | nej | `pos.user` | undanhållen | Cash actually counted in the drawer at closing |
| `cash_difference` | money | `financial` | nej | `pos.user` | undanhållen | Closing cash minus expected cash; negative means money is missing |
| `note` | longtext | `none` | nej | `pos.user` | i klartext | Explanation for any cash difference |
| `state` | select (open, closed) | `none` | nej | `pos.user` | i klartext | Session status: open, closed |

### `pos_order`

A sale rung up at a point of sale

Läsgrupp: `pos.user`. Skrivgrupp: `pos.user`.

| Fält | Typ | Dataklass | Personuppgift | Grupp | Agenter ser | Beskrivning |
|---|---|---|---|---|---|---|
| `session_id` | ref → pos_session | `none` | nej | `pos.user` | i klartext | The session the sale was made in |
| `receipt_number` | text | `none` | nej | `pos.user` | i klartext | Number printed on the receipt. Free text: packages cannot generate sequences |
| `ordered_on` | date | `none` | nej | `pos.user` | i klartext | Day of the sale (YYYY-MM-DD) |
| `customer_id` | ref → party | `none` | nej | `pos.user` | i klartext | The customer, when one was identified |
| `tax_total` | money | `none` | nej | `pos.user` | i klartext | Tax included in the total (minor currency units) |
| `total` | money | `none` | nej | `pos.user` | i klartext | Total paid by the customer including tax (minor currency units, entered not computed) |
| `note` | longtext | `none` | nej | `pos.user` | i klartext | Remark about the sale |
| `state` | select (draft, paid, refunded, cancelled) | `none` | nej | `pos.user` | i klartext | Sale status: draft, paid, refunded, cancelled |

### `pos_order_line`

One product line of a sale

Läsgrupp: `pos.user`. Skrivgrupp: `pos.user`.

| Fält | Typ | Dataklass | Personuppgift | Grupp | Agenter ser | Beskrivning |
|---|---|---|---|---|---|---|
| `order_id` | ref → pos_order | `none` | nej | `pos.user` | i klartext | The sale the line belongs to |
| `product_id` | ref → product | `none` | nej | `pos.user` | i klartext | The product sold |
| `description` | text | `none` | nej | `pos.user` | i klartext | Text shown on the receipt |
| `quantity` | number | `none` | nej | `pos.user` | i klartext | Units sold |
| `unit_price` | money | `none` | nej | `pos.user` | i klartext | Price per unit including tax (minor currency units) |
| `discount_bp` | number | `none` | nej | `pos.user` | i klartext | Discount in basis points: 1000 means 10.00 percent |
| `subtotal` | money | `none` | nej | `pos.user` | i klartext | Line total after discount (minor currency units, entered not computed) |

### `pos_payment`

A payment received against a sale; a sale may be paid with several methods

Läsgrupp: `pos.user`. Skrivgrupp: `pos.user`.

| Fält | Typ | Dataklass | Personuppgift | Grupp | Agenter ser | Beskrivning |
|---|---|---|---|---|---|---|
| `order_id` | ref → pos_order | `none` | nej | `pos.user` | i klartext | The sale the payment is for |
| `method` | select (cash, card, bank_transfer, voucher, other) | `none` | nej | `pos.user` | i klartext | How the customer paid: cash, card, bank_transfer, voucher, other |
| `amount` | money | `financial` | nej | `pos.user` | undanhållen | Amount paid with this method (minor currency units) |
| `paid_on` | date | `none` | nej | `pos.user` | i klartext | Day of the payment (YYYY-MM-DD) |
| `provider_reference` | text | `financial` | ja | `pos.user` | undanhållen | Reference from the card terminal or payment provider; never a card number |

## Arbetsflöden

### `pos_session`

| Åtgärd | Flyttar | Vem får köra den | Godkännande |
|---|---|---|---|
| `pos_session.close` | state: open → closed | `pos.manager` | ja |

### `pos_order`

| Åtgärd | Flyttar | Vem får köra den | Godkännande |
|---|---|---|---|
| `pos_order.pay` | state: draft → paid | `pos.user` | nej |
| `pos_order.cancel` | state: draft → cancelled | `pos.user` | nej |
| `pos_order.refund` | state: paid → refunded | `pos.manager` | ja |

## Behörighetsgrupper

Grupper som den här appen använder:

- `pos.manager`
- `pos.user`

## Steg som kräver godkännande

Steg som en agent bara kan föreslå:

- `pos_session.close`
- `pos_order.refund`

## Vad agenter kan och inte kan göra

En agent kan läsa, söka, skapa och uppdatera poster i den här appen, och köra de åtgärder som inte kräver godkännande, inom behörighetsgrupperna för sin token.

Den kan bara föreslå de här stegen, och en person måste godkänna dem: `pos_session.close`, `pos_order.refund`, `pos_config.delete`, `pos_session.delete`, `pos_order.delete`, `pos_order_line.delete`, `pos_payment.delete`.

Personuppgifter maskeras som platshållare: `pos_session.cashier`.

De här fälten undanhålls helt från agenter: `pos_session.opening_cash`, `pos_session.expected_cash`, `pos_session.closing_cash`, `pos_session.cash_difference`, `pos_payment.amount`, `pos_payment.provider_reference`.

## Beroenden

- `base`
- `product`

## Installera

Installera den från appen Customize (Marknadsplats), eller från kommandoraden:

```bash
obop modules install-from pos
```

Kräver en databas och administratörsbehörighet.

## Bygg din egen

[Modulguiden visar hur appar som den här skrivs](/sv/docs/reference/module-manifest/)
