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

Barcode scan tweaks (#10992)

* Remove duplicate tooltip

* Adjust default value

* docs update

* Tweak unit test

* Fix playwright tests
This commit is contained in:
Oliver
2025-12-11 16:19:47 +11:00
committed by GitHub
parent 0723c74567
commit 20c7a5b5b8
9 changed files with 49 additions and 13 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

View File

@@ -69,7 +69,7 @@ To access this page, select *Scan Barcode* from the main navigation menu:
{{ image("barcode/barcode_nav_menu.png", "Barcode menu item") }}
{{ image("barcode/barcode_scan_page.png", "Barcode scan page") }}
### Barcodes in Forms
## Barcodes in Forms
The InvenTree user interface supports direct scanning of barcodes within certain forms in the web UI. This means that any form field which points to a model which supports barcodes can accept barcode input. If barcode scanning is supported for a particular field, a barcode icon will be displayed next to the input field:
@@ -83,6 +83,14 @@ Once scanned, the form field will be automatically populated with the correct it
{{ image("barcode/barcode_field_filled.png", "Barcode field populated") }}
Any field which supports barcode input will have this functionality, such as allocating stock items to an order:
{{ image("barcode/barcode_allocate_stock.png", "Allocate stock via barcode") }}
### User Configuration
By default, barcode scanning in form fields is disabled. Each user can enable this feature via their [user preferences](../settings/user.md#display-settings).
## App Integration
Barcode scanning is a key feature of the [companion mobile app](../app/barcode.md). When running on a device with an integrated camera, the app can scan barcodes directly from the camera feed.

View File

@@ -44,7 +44,7 @@ USER_SETTINGS: dict[str, InvenTreeSettingsKeyType] = {
'BARCODE_IN_FORM_FIELDS': {
'name': _('Barcode Scanner in Form Fields'),
'description': _('Allow barcode scanner input in form fields'),
'default': True,
'default': False,
'validator': bool,
},
'SEARCH_PREVIEW_SHOW_PARTS': {

View File

@@ -29,7 +29,6 @@ export function ScanButton({
aria-label={`barcode-scan-button-${modelType ?? 'any'}`}
onClick={open}
variant='transparent'
title={t`Open Barcode Scanner`}
>
<IconQrcode />
</ActionIcon>

View File

@@ -1,10 +1,16 @@
import { request } from '@playwright/test';
import { adminuser, apiUrl } from './defaults';
export const createApi = () =>
export const createApi = ({
username,
password
}: {
username?: string;
password?: string;
}) =>
request.newContext({
baseURL: apiUrl,
extraHTTPHeaders: {
Authorization: `Basic ${btoa(`${adminuser.username}:${adminuser.password}`)}`
Authorization: `Basic ${btoa(`${username || adminuser.username}:${password || adminuser.password}`)}`
}
});

View File

@@ -152,7 +152,7 @@ export const globalSearch = async (page: Page, query: string) => {
};
export const deletePart = async (name: string) => {
const api = await createApi();
const api = await createApi({});
const parts = await api
.get('part/', {
params: { search: name }

View File

@@ -1,4 +1,5 @@
import type { Page } from '@playwright/test';
import { createApi } from '../api';
import { test } from '../baseFixtures';
import { doCachedLogin } from '../login';
@@ -128,9 +129,33 @@ test('Barcode Scanning - Build', async ({ browser }) => {
test('Barcode Scanning - Forms', async ({ browser }) => {
const page = await doCachedLogin(browser, {
username: 'admin',
password: 'inventree',
url: '/stock/location/index/stock-items'
});
// Ensure the user setting is enabled
const api = await createApi({});
let patched = false;
await api
.patch('/api/settings/user/BARCODE_IN_FORM_FIELDS/', {
data: {
value: true
}
})
.then((response) => {
patched = response.status() === 200;
});
// Assert that the setting was patched successfully
if (!patched) {
throw new Error('Could not patch user setting: BARCODE_IN_FORM_FIELDS');
}
await page.reload();
// Open the "Add Stock Item" form
await page
.getByRole('button', { name: 'action-button-add-stock-item' })

View File

@@ -332,7 +332,7 @@ test('Settings - Admin - Barcode History', async ({ browser }) => {
// Scan some barcodes (via API calls)
const barcodes = ['ABC1234', 'XYZ5678', 'QRS9012'];
const api = await createApi();
const api = await createApi({});
for (let i = 0; i < barcodes.length; i++) {
const barcode = barcodes[i];
@@ -349,8 +349,8 @@ test('Settings - Admin - Barcode History', async ({ browser }) => {
},
timeout: 5000
})
.then(() => {
result = true;
.then((response) => {
result = response.status() === 200;
});
if (result) {
@@ -478,8 +478,6 @@ test('Settings - Admin - Parameter', async ({ browser }) => {
await page.getByRole('option', { name: 'my custom parameter' }).click();
await page.getByLabel('choice-field-data').fill('2');
await page.getByRole('button', { name: 'Submit' }).click();
await page.waitForTimeout(2500);
});
test('Settings - Admin - Unauthorized', async ({ browser }) => {

View File

@@ -16,7 +16,7 @@ export const setSettingState = async ({
type?: 'global' | 'plugin';
plugin?: string;
}) => {
const api = await createApi();
const api = await createApi({});
const url =
type === 'global'
? `settings/global/${setting}/`
@@ -37,7 +37,7 @@ export const setPluginState = async ({
plugin: string;
state: boolean;
}) => {
const api = await createApi();
const api = await createApi({});
const response = await api.patch(`plugins/${plugin}/activate/`, {
data: {
active: state