# Expiry Date & Batch Manager: documentation

> Installation and upgrade The module installs like any PrestaShop module, with no dependency and no Composer. Open Modules → Module Manager. Click Upload a module and drop the ZIP file.…

- Page: <https://www.datafirefly.com/en/documentation/dfdlc/>
- Language: en
- Last updated: 2026-10-05
- Other languages: [fr](https://www.datafirefly.com/documentation/dfdlc/index.md), [es](https://www.datafirefly.com/es/documentation/dfdlc/index.md), [de](https://www.datafirefly.com/de/documentation/dfdlc/index.md), [it](https://www.datafirefly.com/it/documentation/dfdlc/index.md), [pl](https://www.datafirefly.com/pl/documentation/dfdlc/index.md), [pt](https://www.datafirefly.com/pt/documentation/dfdlc/index.md), [nl](https://www.datafirefly.com/nl/documentation/dfdlc/index.md)
- Index: <https://www.datafirefly.com/en/documentation/llms.txt>

## Installation and upgrade

The module installs like any PrestaShop module, with no dependency and no Composer.

1. Open **Modules → Module Manager**.
2. Click **Upload a module** and drop the ZIP file.
3. Then click **Configure**.

The module creates three tables (lots, movements, supplier packaging) and two tabs in the Catalog menu: **DLC/DLUO Lots** and **Supplier packaging**.

From a previous version, simply upload the new ZIP. Your lots and their history are kept. If you used the single discount of version 1.0.0, it becomes the first discount tier.

If the tabs do not show up right away, clear the cache from Advanced Parameters → Performance and log in again.

## Use-by and best-before: what the module does

A **use-by date** (DLC) applies to perishable goods: past it, the product must no longer be sold. A **best-before date** (DLUO / DDM) signals a loss of quality: the product remains sellable if the customer is informed.

- An expired use-by lot is never allocated to an order, even if the cron has not run yet that day.
- Automatic actions on expiry (stock removal, product deactivation) only apply to use-by lots.
- An expired best-before lot is only deactivated; it can still be allocated to orders while it is active.

Choose the date type carefully when creating a lot: it decides whether automatic actions apply.

## Configuring the module

The configuration page shows the cron URL, a quick status of your lots and four groups of settings.

### Product page display

- **Display expiry date on product page**: date of the closest lot in stock for the combination selected by the customer.
- **Short-dated badge threshold**: below this number of days, a "Short-dated" badge is shown. Default: 10 days.

### Automatic short-date discounts

- **Enable automatic discounts**: turning it off removes every discount created by the module.
- **Discount tiers**: up to 10 rows "when the lot expires within X days" / "discount Y %". See Discount tiers below.

### Stock and costs

- **When a use-by (DLC) lot expires**: deactivate the lot only, deactivate it and deduct its remaining quantity from stock (recommended), or deduct stock and disable the product if no valid lot remains.
- **Add received quantity to PrestaShop stock by default**: value suggested when a lot is created. Leave it on No while you register lots for stock already counted in PrestaShop.
- **Write the lot cost into each order line**: see Purchase cost and margins.
- **Put units back into their lots when an order is cancelled**: see Cancellation and reactivation.
- **Print lot numbers on delivery slips** (on by default) and **on invoices** (off by default).

### Email alerts

- **Alert threshold before expiry**: window watched by the summary email. Default: 30 days.
- **Alert recipient email**: leave empty to use the shop address.

## Supplier packaging

If you buy by the box and sell by the unit, declare the packaging once in **Catalog → Supplier packaging**:

- product and, if needed, combination;
- label (for example "Box of 12");
- supplier box reference and box EAN;
- units per box and usual box cost (tax excluded);
- reference and EAN of the unit sold. Left empty, they are taken from the product or combination.

The resulting unit cost is shown live. A product can have several packagings.

## Creating and receiving a lot

In **Catalog → DLC/DLUO Lots**, click **Add new lot**, or use the same button in the Lots panel of the product page.

### Reception by unit

1. Search the product (2 characters minimum) and pick the combination, or keep "All combinations".
2. Keep **Received in units**.
3. Fill in lot number, date type, expiry date, quantity received and purchase cost per unit (tax excluded).
4. Set **Add this quantity to PrestaShop stock**: Yes for a new delivery, No for stock already counted.

### Reception in boxes

1. After the product, choose **Received in supplier boxes**.
2. Select the packaging, enter the **boxes received** and the **cost per box (tax excl.)**, pre-filled with the usual cost.
3. Quantity and unit cost are calculated and locked: 3 boxes of 12 at 30 EUR give 36 units at 2.50 EUR.

The lot supplier reference is pre-filled with the box reference. You can replace it with your supplier delivery note number.

### Editing, deactivating, deleting

- The product of a lot cannot be changed after creation.
- Changing the quantity records an adjustment movement without touching PrestaShop stock.
- A lot number can exist only once per product.
- A lot already sold cannot be deleted: deactivate it instead.

## Importing lots from CSV

Use the **Import lots (CSV)** button in the lot list. A sample file can be downloaded from that page.

- Semicolon, comma or tab separator; first row = column names; 5,000 rows and 5 MB maximum.
- The product is found by `reference`, `ean13` or `id_product`. A combination reference also works in `reference`.
- `combination_reference` or `combination_ean13` attaches the lot to a combination.
- Required: `lot_number` and `expiry_date` (YYYY-MM-DD or DD/MM/YYYY).
- `date_type`: dlc or dluo (dlc by default).
- `quantity` and `unit_cost` for a reception by unit.
- `boxes`, `box_reference` and `box_cost` for a reception in boxes: quantity and unit cost are calculated from the packaging.
- `supplier_ref` and `note` are optional.

```
reference;lot_number;date_type;expiry_date;quantity;unit_cost
CROQ-2KG;L2026-118;dluo;2027-03-31;24;6.40
PATE-12;L2026-204;dlc;15/01/2027;;
```

A lot number that already exists for the product is skipped. The report lists every failing row with its reason; the other rows are imported.

## Dashboard and filtered views

At the top of the list, the cards are clickable and filter the list: expired lots still active, lots nearing expiry, lots with a running discount, purchase value at risk and purchase value of stock in lots. The filter stays active while paging; **Show all lots** removes it.

## FEFO stock deduction

When an order is validated, for each product:

1. lots of the ordered combination come first, then product-level lots;
2. lots are consumed from the closest date to the furthest;
3. expired use-by lots are excluded.

An order of 10 units facing a lot of 4 and a lot of 8 takes the first 4, then 6 from the next lot. Each deduction is recorded with the order.

## Purchase cost and margins

With **Write the lot cost into each order line** enabled, the module calculates the weighted cost of the lots consumed and stores it as the purchase price of the order line. PrestaShop margin statistics then use the real cost. Lots without a cost are ignored in that calculation.

## Discount tiers

Example: 10 percent at 90 days, 20 percent at 60 days, 30 percent at 30 days.

- The discount applied is the highest percentage among the tiers reached: it never goes down as the date gets closer.
- It only applies to the lot that ships next, per product or per combination.
- It is a standard PrestaShop catalog price rule ending on the expiry date.
- When the lot sells out, the discount moves to the next lot or disappears.
- Discounts are recalculated when settings or a lot are saved, then every day by the cron.

These rules follow the usual PrestaShop priorities. If you already run broad catalog discounts, check priorities before enabling the tiers.

## Picking: order page and delivery slip

On the back-office order page, the **Lots shipped (FEFO)** block shows for each product the lot, date, quantity and cost. The same lots are printed on the delivery slip, and on the invoice if that option is on.

## Cancellation and reactivation

When an order moves to Cancelled, its units go back into their original lots. If it later returns to a valid status, its units are taken again in FEFO order. The cycle can repeat with no double counting.

Partial returns with restocking are not assigned to a lot automatically. They show up in the Stock check, where you create the matching lot.

## Stock check

The **Stock check** button compares units in lots with PrestaShop stock:

- a positive difference means some units have no lot: **Create a lot for the missing units** opens a pre-filled form;
- a negative difference means the lots hold more than the stock: correct the lots or the stock.

Products with product-level lots are compared on their total stock; products whose lots are all attached to combinations are compared combination by combination.

## Lots panel on the product page

The back-office product page lists the product's lots with their status, cost and discount, and compares the total with PrestaShop stock. Its Add new lot button pre-selects the product. On PrestaShop 8.1 and 9, the panel sits in the Modules tab of the product page.

## Cron task

Deduction, traceability and import work without cron. Discount tiers, expired lot handling and the email alert need one daily call to the URL shown in the configuration:

```
https://your-shop.com/index.php?fc=module&module=dfdlc&controller=cron&token=YOUR_TOKEN
```

The JSON response lists lots deactivated, units removed, products disabled, discounts created, updated or removed, and alerts sent.

## Email alerts

On each cron run, a summary email lists the lots whose date enters the alert window: number, product, type, date and quantity. Each lot is reported only once. Templates are provided in 8 languages in the `mails/` folder.

## Product page display

Through the `displayProductAdditionalInfo` hook, the page shows "Use by" or "Best before" with the date of the closest lot for the selected combination. Below the threshold, the "Short-dated" badge appears with the discount. A tier discount outside that threshold is labelled "expiry date offer". The template `views/templates/hook/product-expiry.tpl` can be overridden in your theme.

## Traceability and recalls

The lot form shows its history: reception, orders, cancellations, adjustments, removal on expiry, with a link to each order. **Export CSV** exports the lot history; **Export movements** in the list exports the full history. This data is the basis of a recall procedure.

## Frequently asked questions

### Does the module replace PrestaShop stock?

No. PrestaShop stock remains the reference for selling; the module splits it into dated lots and reports differences.

### What if my lots do not cover all of the stock?

The order goes through normally: the module takes what is available in the lots. The Stock check shows units without a lot.

### Is the module multistore compatible?

Yes. Each lot belongs to the shop where it was created.

### What happens on uninstall?

The three tables are dropped with their content. Back up your database if you plan to reinstall.
