mirror of
https://github.com/inventree/InvenTree.git
synced 2025-12-14 08:19:54 +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:
BIN
docs/docs/assets/images/barcode/barcode_allocate_stock.png
Normal file
BIN
docs/docs/assets/images/barcode/barcode_allocate_stock.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 26 KiB |
@@ -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.
|
||||
|
||||
@@ -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': {
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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}`)}`
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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 }
|
||||
|
||||
@@ -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' })
|
||||
|
||||
@@ -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 }) => {
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user