### New Feature: Custom entities / objects / lists

- Custom entities are based on Userfields and can be used to add any custom lists you want to have in Grocy
- They can have an own menu entry in the sidebar
- => See "Manage master data" -> "Userentities" or try it on the demo: https://demo.grocy.info/userobjects/exampleuserentity

### New Feature: Use the device camera for barcode scanning
- Available on any barcode-enabled field (so currently only for picking products) - a new camera button at the right of side the text field
- Implemented using [QuaggaJS](https://github.com/serratus/quaggaJS) - camera stream processing happens totally offline / client-side
- Please note due to browser security restrictions, this only works when serving Grocy via a secure connection (`https://`)
- There is also a `config.php` setting `DISABLE_BROWSER_BARCODE_CAMERA_SCANNING` to disable this, if you don't need it at all (defaults to `false`)
- If you have problems that barcodes are not recognized properly, there is a little "barcode scanner testing page" at [/barcodescannertesting](https://demo.grocy.info/barcodescannertesting)
- => Quick video demo: https://www.youtube.com/watch?v=Y5YH6IJFnfc

### Stock improvements/fixes
- Products can now have variations (nested products)
  - Define the parent product for a product on the product edit page (only one level is possible, means a product which is used as a parent product in another product, cannot have a parent product itself)
  - Parent and sub products can have stock (both are regular products, no difference from that side)
  - On the stock overview page, the aggregated amount is displayed next to the amount (sigma sign)
  - When a recipe needs a parent product, the need is also fulfilled when enough sub product(s) are in stock
- Quantity units can now be linked (related measurements / unit conversion)
  - On the quantity unit edit page default conversion can be defined for each unit
  - Products "inherit" the default conversion and additionally can have their own / override the default ones
- It's now possible to print a "Location Content Sheet" with the current stock per location - new button at the top of the stock overview page (thought to hang it at the location, note used amounts on paper and track it in Grocy later)
- Stock overview page improvements
  - Options in the more/context-menu to directly open the purchase/consume/inventory pages prefilled with the current product in a popup/dialog
  - Option in the more/context-menu to add the current product directly to a shopping list
  - Option in the more/context-menu to search for recipes containing the current product
  - It's now possible to undo stock bookings ("Undo"-button in the success message, like it was already possible on the purchase/consume/inventory pages)
  - Improved that on any stock changes the corresponding product table row is properly refreshed
- New `config.php` setting `FEATURE_SETTING_STOCK_COUNT_OPENED_PRODUCTS_AGAINST_MINIMUM_STOCK_AMOUNT` to configure if opened products should be considered for minimum stock amounts (defaults to `true`, so opened products will now be considered missing by default - please change this setting if you want the old behavior)
- The product description now can have formattings (HTML/WYSIWYG editor like for recipes)
- Products now have a new field for calories (kcal, per stock quantity unit)
- "Factor purchase to stock quantity unit" (product option) can now also be a decimal number when "Allow partial units in stock" is enabled
- New "Sub feature flags" in `config.php` to disable some sub-features (hide the corresponding UI elements) if you don't need them (all new feature flags default to `true`, so no changed behavior when not configured)
  - `FEATURE_FLAG_STOCK_PRICE_TRACKING` to disable product price tracking
  - `FEATURE_FLAG_STOCK_LOCATION_TRACKING` to disable product location tracking
  - `FEATURE_FLAG_STOCK_BEST_BEFORE_DATE_TRACKING` to disable product best before date tracking
  - `FEATURE_FLAG_STOCK_PRODUCT_OPENED_TRACKING` to disable product opened tracking
- Fixed/refined some things regarding purchase/consume/inventory of products with enabled tare weight handling (nothing was broken, but the success popups may not displayed the correct amount that was posted)
- Fixed that "Spoil rate" and "Average shelf life" on the product card was wrong in most cases
- When going to the product edit page, after saving the product, it will now always return to the previous page

### Shopping list improvements
- Shopping lists now have a notes field (HTML/WYSIWYG editor, just to save some notes per shopping list)
- Shopping lists can now be printed (new button next to the add/delete shopping list button)

### Recipe improvements
- Based on the new linked quantity units, recipe ingredients can now use any product related unit, the amount is calculated according to the conversion factor of the unit relation
- Based on the new calories field per product, the calories per recipe are now shown based on the selected servings (in the header, next to the costs)
- New option "price factor" per recipe ingredient (defaults to `1`) - the resulting costs of the recipe ingredient will be multiplied by that factor
  - Use this for example for spices in combination with "Only check if a single unit is in stock" to not take the full price of a pack of pepper into account for a recipe
- The search field on the recipe overview page now also searches for product names of recipe ingredients (means it's possible to search a recipe by a product name)
- Fixed a problem where the meal plan did not load when a recipe, which was already added to the meal plan, was deleted

### Chores improvements
- Chores can now be assigned to users
  - Option per chore, different "assignment types" like "Random", "Who least did first", etc.
  - On the chores overview page, the list can be filtered to only show chores assigned to the currently logged in user (or to any other user)
- New option "Due date rollover" per chore which means the chore can never be overdue, the due date will shift forward each day when due
- New option "Consume product on chore execution" per chore to automatically consume a product when a chore execution is tracked
- When tracking an execution from the chores overview page, filters are re-applied afterwards (means when you have filtered the page to only show overdue chores and after the execution the chore is not overdue anymore, it will now be immediately hidden)

### Equipment improvements/fixes
- Fixed that the delete button not always deleted the currently selected equipment item

### Userfield improvements/fixes
- New Userfield type "Select list" for a list of predefined values where a single or also multiple values can then be selected on the entity object
- New Userfield type "Link" - a single-line-textbox where the content will be rendered as a clickable link
- Userfields of type "Checkbox" are rendered as a checkmark in tables when checked (instead of "1" as till now)
- Product Userfields are now also rendered on the shopping list (for items which have a product referenced)
- Fixed that the Userfield type "Preset list" had always the caption "Product group" instead of the configured one (thanks @oncleben31)

### General & other improvements/fixes
- Added a new `config.php` setting `CALENDAR_SHOW_WEEK_OF_YEAR` to configure if calendars should show week numbers (defaults to `true`)
- Fixed that date time pickers not considered the `config.php` setting `CALENDAR_FIRST_DAY_OF_WEEK`
- Improved the handling which entry page to use with disabled feature flags (thanks @nielstholenaar)
- Boolean settings provided via environment variables (so the strings `true` and `false`) are now parsed correctly (thanks @mduret)
- All uploaded pictures (currently for products and recipes) are now automatically downscaled to the appropriate size when serving them to improve page load times (this requires the `php-gd` extension, if not installed, images will not be downscaled)
- It's now possible to test plural forms of quantity units (button on the quantity unit edit page, only visible if the current language requires more than 2 plural forms)
- On the login page the sidebar an all top-navbar menus is now hidden
- New translations: (thanks all the translators)
  - Danish (demo available at https://da.demo.grocy.info)
  - Dutch (demo available at https://nl.demo.grocy.info)
- Internal change for how the localizations for the demo instances are handled
  - For the pre-release demo now all currently supported languages are available (was already the case for the stable demo)
    - Additionally all language files which reached the completion limit of 80 % will now be automatically pulled from Transifex 10 minutes past every hour (to have a kind of instant preview of changed translations)
  - The URLs have changed, I'll try to keep all existing URLs redirecting properly for a long time
    - If you want to link to the demo, please only use https://demo.grocy.info (stable demo) or https://demo-prerelease.grocy.info (current master branch demo)

### API improvements & non-breaking changes
- New endpoint `/objects/{entity}/search/{searchString}` to search for objects by name (contains search)
- New endpoint `/stock/shoppinglist/add-product` to add a product to a shopping list (thanks @Forceu)
- New endpoint `/stock/shoppinglist/remove-product` to remove a product from a shopping list (thanks @Forceu)
- New endpoint `/chores/executions/calculate-next-assignments` to (re)calculate next user assignments for a single or all chores
- New endpoint `/stock/products/by-barcode/{barcode}/add` to add a product to stock by its barcode
- New endpoint `/stock/products/by-barcode/{barcode}/consume` to remove a product to stock by its barcode
- New endpoint `/stock/products/by-barcode/{barcode}/inventory` to inventory a product by its barcode
- New endpoint `/stock/products/by-barcode/{barcode}/open` to mark a product as opened by its barcode
- New endpoint `/stock/bookings/{bookingId}` to retrieve a single stock booking
- Endpoint `GET /files/{group}/{fileName}` can now also downscale pictures (see API documentation on [/api](https://demo.grocy.info/api))
- When adding a product (through `stock/product/{productId}/add` or `stock/product/{productId}/inventory`) with omitted best before date and if the given product has "Default best before days" set, the best before date is calculated based on that (so far always today was used which is still the case when no date is supplied and also the product has no "Default best before days set) (thanks @Forceu)
- Field `stock_amount` of endpoint `/stock/products/{productId}` now returns `0` instead of `null` when the given product is not in stock (thanks @Forceu)
- Fixed that `/system/db-changed-time` always returned the current time (more or less) due to that that time is the database file modification time and the database is effectively changed on each request because of session information tracking - which now explicitly does not change the database file modification time, so this should work again to determine if any data changes happened
- It's now also possible to provide the API key via a query parameter (same name as the header, so `GROCY-API-KEY`)

#### Say thanks
Because there were some questions about that in the past: If Grocy is useful for you, [say thanks](https://grocy.info/#say-thanks)!
