2
0
mirror of https://github.com/inventree/InvenTree.git synced 2025-12-15 16:58:14 +00:00

Merge branch 'master' into generic-parameters

This commit is contained in:
Oliver
2025-11-26 23:40:57 +11:00
committed by GitHub
6 changed files with 50 additions and 7 deletions

View File

@@ -98,7 +98,7 @@ Sometimes, users may encounter unexpected error messages when updating their Inv
The most common problem here is that the correct sequence of steps has not been followed:
1. Ensure that the InvenTree web server and background worker processes are *halted*
1. Ensure that the InvenTree [web server](./start/processes.md#web-server) and [background worker](./start/processes.md#background-worker) processes are *halted*
1. Update the InvenTree software (e.g. using git or docker, depending on installation method)
1. Run the `invoke update` command
1. Restart the web server and background worker processes
@@ -150,7 +150,7 @@ or
### Background Worker "Not Running"
The background worker process must be started separately to the web-server application.
The [background worker process](./start/processes.md#background-worker) must be started separately to the web-server application.
From the top-level source directory, run the following command from a separate terminal, while the server is already running:

View File

@@ -123,11 +123,14 @@ By default, a production InvenTree installation is configured to run with [DEBUG
Running in DEBUG mode provides many handy development features, however it is strongly recommended *NOT* to run in DEBUG mode in a production environment. This recommendation is made because DEBUG mode leaks a lot of information about your installation and may pose a security risk.
So, for a production setup, you should set `INVENTREE_DEBUG=false` in the [configuration options](./config.md).
So, for a production setup, you should ensure that `INVENTREE_DEBUG=false` in the [configuration options](./config.md).
!!! warning "Security Risk"
Running InvenTree in DEBUG mode in a production environment is a significant security risk, and should be avoided at all costs.
### Turning Debug Mode off
When running in DEBUG mode, the InvenTree web server natively manages *static* and *media* files, which means that when DEBUG mode is *disabled*, the proxy setup has to be configured to handle this.
When running in DEBUG mode, the InvenTree web server natively manages *static* and *media* files, which means that when DEBUG mode is *disabled* (which is the default for a production setup), the proxy setup has to be configured to handle this.
!!! info "Read More"
Refer to the [proxy server documentation](./processes.md#proxy-server) for more details

View File

@@ -9,6 +9,12 @@ If you are struggling with an issue which is not covered in the FAQ above, pleas
Even if you cannot immediately resolve the issue, the information below will be very useful when reporting the issue on GitHub.
## Error Codes
InvenTree uses a system of error codes to help identify specific issues. Each error code is prefixed with `INVE-`, followed by a letter indicating the error type, and a number.
Refer to the [error code documentation](./settings/error_codes.md) for more information on specific error codes.
## Recent Update
If you have recently updated your InvenTree instance, please ensure that you have followed all update instructions carefully. In particular, make sure that you have run any required database migrations using the `invoke update` command.

View File

@@ -1678,6 +1678,10 @@ class StockAddSerializer(StockAdjustmentSerializer):
stock_item = item['pk']
quantity = item['quantity']
if quantity is None or quantity <= 0:
# Ignore in this case - no stock to add
continue
# Optional fields
extra = {}
@@ -1703,6 +1707,10 @@ class StockRemoveSerializer(StockAdjustmentSerializer):
stock_item = item['pk']
quantity = item['quantity']
# Ignore in this case - no stock to remove
if quantity is None or quantity <= 0:
continue
# Optional fields
extra = {}

View File

@@ -862,10 +862,17 @@ function stockRemoveFields(items: any[]): ApiFormFieldSet {
const records = Object.fromEntries(items.map((item) => [item.pk, item]));
const initialValue = mapAdjustmentItems(items).map((elem) => {
return {
...elem,
quantity: 0
};
});
const fields: ApiFormFieldSet = {
items: {
field_type: 'table',
value: mapAdjustmentItems(items),
value: initialValue,
modelRenderer: (row: TableFieldRowProps) => {
const record = records[row.item.pk];
@@ -902,10 +909,17 @@ function stockAddFields(items: any[]): ApiFormFieldSet {
const records = Object.fromEntries(items.map((item) => [item.pk, item]));
const initialValue = mapAdjustmentItems(items).map((elem) => {
return {
...elem,
quantity: 0
};
});
const fields: ApiFormFieldSet = {
items: {
field_type: 'table',
value: mapAdjustmentItems(items),
value: initialValue,
modelRenderer: (row: TableFieldRowProps) => {
const record = records[row.item.pk];
@@ -941,10 +955,12 @@ function stockCountFields(items: any[]): ApiFormFieldSet {
const records = Object.fromEntries(items.map((item) => [item.pk, item]));
const initialValue = mapAdjustmentItems(items);
const fields: ApiFormFieldSet = {
items: {
field_type: 'table',
value: mapAdjustmentItems(items),
value: initialValue,
modelRenderer: (row: TableFieldRowProps) => {
return (
<StockOperationsRow

View File

@@ -332,6 +332,11 @@ test('Stock - Stock Actions', async ({ browser }) => {
await page.getByRole('button', { name: 'Scan', exact: true }).click();
await page.getByText('Scanned stock item into location').waitFor();
// Add "zero" stock - ensure the quantity stays the same
await launchStockAction('add');
await page.getByRole('button', { name: 'Submit' }).click();
await page.getByText('Quantity: 123').first().waitFor();
// Add stock, and change status
await launchStockAction('add');
await page.getByLabel('number-field-quantity').fill('12');
@@ -342,6 +347,11 @@ test('Stock - Stock Actions', async ({ browser }) => {
await page.getByText('Unavailable').first().waitFor();
await page.getByText('135').first().waitFor();
// Remove "zero" stock - ensure the quantity stays the same
await launchStockAction('remove');
await page.getByRole('button', { name: 'Submit' }).click();
await page.getByText('Quantity: 135').first().waitFor();
// Remove stock, and change status
await launchStockAction('remove');
await page.getByLabel('number-field-quantity').fill('99');